From 43a299bc3f9723582f18e1233049260cc4c5e258 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 16 Aug 2009 14:29:08 -0400 Subject: [PATCH 0002/1030] Initial xsbt commit --- ivy/ConvertResolver.scala | 100 ++++++++++ ivy/CustomXmlParser.scala | 35 ++++ ivy/Ivy.scala | 307 ++++++++++++++++++++++++++++++ ivy/IvyActions.scala | 138 ++++++++++++++ ivy/IvyConfigurations.scala | 33 ++++ ivy/IvyInterface.scala | 360 ++++++++++++++++++++++++++++++++++++ ivy/IvyLogger.scala | 54 ++++++ ivy/IvyScala.scala | 74 ++++++++ 8 files changed, 1101 insertions(+) create mode 100644 ivy/ConvertResolver.scala create mode 100644 ivy/CustomXmlParser.scala create mode 100644 ivy/Ivy.scala create mode 100644 ivy/IvyActions.scala create mode 100644 ivy/IvyConfigurations.scala create mode 100644 ivy/IvyInterface.scala create mode 100644 ivy/IvyLogger.scala create mode 100644 ivy/IvyScala.scala diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala new file mode 100644 index 000000000..51c3277eb --- /dev/null +++ b/ivy/ConvertResolver.scala @@ -0,0 +1,100 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import org.apache.ivy.{core,plugins} +import core.module.id.ModuleRevisionId +import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} +import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} + +private object ConvertResolver +{ + /** Converts the given sbt resolver into an Ivy resolver..*/ + def apply(r: Resolver) = + { + r match + { + case repo: MavenRepository => + { + val resolver = new IBiblioResolver + initializeMavenStyle(resolver, repo.name, repo.root) + resolver + } + case JavaNet1Repository => + { + // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: + // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html + val resolver = new IBiblioResolver { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } + initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") + resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") + resolver + } + case repo: SshRepository => + { + val resolver = new SshResolver + initializeSSHResolver(resolver, repo) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver + } + case repo: SftpRepository => + { + val resolver = new SFTPResolver + initializeSSHResolver(resolver, repo) + resolver + } + case repo: FileRepository => + { + val resolver = new FileSystemResolver + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns) + import repo.configuration.{isLocal, isTransactional} + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => + { + val resolver = new URLResolver + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns) + resolver + } + } + } + private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) + { + resolver.setName(name) + resolver.setM2compatible(true) + resolver.setRoot(root) + } + private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository) + { + resolver.setName(repo.name) + resolver.setPassfile(null) + initializePatterns(resolver, repo.patterns) + initializeConnection(resolver, repo.connection) + } + private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection) + { + import resolver._ + import connection._ + hostname.foreach(setHost) + port.foreach(setPort) + authentication foreach + { + case RepositoryHelpers.PasswordAuthentication(user, password) => + setUser(user) + setUserPassword(password) + case RepositoryHelpers.KeyFileAuthentication(file, password) => + setKeyFile(file) + setKeyFilePassword(password) + } + } + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: RepositoryHelpers.Patterns) + { + resolver.setM2compatible(patterns.isMavenCompatible) + patterns.ivyPatterns.foreach(resolver.addIvyPattern) + patterns.artifactPatterns.foreach(resolver.addArtifactPattern) + } +} diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala new file mode 100644 index 000000000..6688d8ef7 --- /dev/null +++ b/ivy/CustomXmlParser.scala @@ -0,0 +1,35 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import java.io.ByteArrayInputStream +import java.net.URL + +import org.apache.ivy.{core, plugins} +import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor} +import core.settings.IvySettings +import plugins.parser.xml.XmlModuleDescriptorParser +import plugins.repository.Resource +import plugins.repository.url.URLResource + +/** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ +private object CustomXmlParser extends XmlModuleDescriptorParser with NotNull +{ + import XmlModuleDescriptorParser.Parser + class CustomParser(settings: IvySettings) extends Parser(CustomXmlParser, settings) with NotNull + { + def setSource(url: URL) = + { + super.setResource(new URLResource(url)) + super.setInput(url) + } + def setInput(bytes: Array[Byte]) { setInput(new ByteArrayInputStream(bytes)) } + /** Overridden because the super implementation overwrites the module descriptor.*/ + override def setResource(res: Resource) {} + override def setMd(md: DefaultModuleDescriptor) = super.setMd(md) + override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) + override def getDefaultConf = super.getDefaultConf + override def setDefaultConf(conf: String) = super.setDefaultConf(conf) + } +} \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala new file mode 100644 index 000000000..d85a46733 --- /dev/null +++ b/ivy/Ivy.scala @@ -0,0 +1,307 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import Artifact.{defaultExtension, defaultType} + +import java.io.File + +import org.apache.ivy.{core, plugins, util, Ivy} +import core.cache.DefaultRepositoryCacheManager +import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor} +import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import core.settings.IvySettings +import plugins.matcher.PatternMatcher +import plugins.parser.m2.PomModuleDescriptorParser +import plugins.resolver.ChainResolver +import util.Message + +final class IvySbt(configuration: IvyConfiguration) +{ + import configuration._ + /** ========== Configuration/Setup ============ + * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. + * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, + * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). + */ + private lazy val logger = new IvyLoggerInterface(log) + private def withDefaultLogger[T](f: => T): T = + IvySbt.synchronized // Ivy is not thread-safe. In particular, it uses a static DocumentBuilder, which is not thread-safe + { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(logger) + try { f } + finally { Message.setDefaultLogger(originalLogger) } + } + private lazy val settings = + { + val is = new IvySettings + is.setBaseDir(paths.baseDirectory) + IvySbt.configureCache(is, paths.cacheDirectory) + if(resolvers.isEmpty) + autodetectConfiguration(is) + else + IvySbt.setResolvers(is, resolvers, log) + is + } + private lazy val ivy = + { + val i = Ivy.newInstance(settings) + i.getLoggerEngine.pushLogger(logger) + i + } + /** Called to configure Ivy when inline resolvers are not specified. + * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ + private def autodetectConfiguration(settings: IvySettings) + { + log.debug("Autodetecting configuration.") + val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) + if(defaultIvyConfigFile.canRead) + settings.load(defaultIvyConfigFile) + else + IvySbt.setResolvers(settings, Resolver.withDefaultResolvers(Nil), log) + } + /** ========== End Configuration/Setup ============*/ + + /** Uses the configured Ivy instance within a safe context.*/ + def withIvy[T](f: Ivy => T): T = + withDefaultLogger + { + ivy.pushContext() + try { f(ivy) } + finally { ivy.popContext() } + } + + final class Module(val moduleConfiguration: ModuleConfiguration) extends NotNull + { + def logger = configuration.log + def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = + withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } + + import moduleConfiguration._ + private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = + { + val (baseModule, baseConfiguration) = + if(isUnconfigured) + autodetectDependencies(IvySbt.toID(module)) + else + configureModule + ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) + baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("m", "m") + (baseModule, baseConfiguration) + } + private def configureModule = + { + val moduleID = newConfiguredModuleID + val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) + log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) + + val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) + + IvySbt.addArtifacts(moduleID, artifacts) + IvySbt.addDependencies(moduleID, dependencies, parser) + IvySbt.addMainArtifact(moduleID) + (moduleID, parser.getDefaultConf) + } + private def newConfiguredModuleID = + { + val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) + mod.setLastModified(System.currentTimeMillis) + configurations.foreach(config => mod.addConfiguration(IvySbt.toIvyConfiguration(config))) + mod + } + + /** Parses the given Maven pom 'pomFile'.*/ + private def readPom(pomFile: File) = + { + val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), validate) + (IvySbt.toDefaultModuleDescriptor(md), "compile") + } + /** Parses the given Ivy file 'ivyFile'.*/ + private def readIvyFile(ivyFile: File) = + { + val url = toURL(ivyFile) + val parser = new CustomXmlParser.CustomParser(settings) + parser.setValidate(validate) + parser.setSource(url) + parser.parse() + val md = parser.getModuleDescriptor() + (IvySbt.toDefaultModuleDescriptor(md), parser.getDefaultConf) + } + private def toURL(file: File) = file.toURI.toURL + /** Called to determine dependencies when the dependency manager is SbtManager and no inline dependencies (Scala or XML) + * are defined. It will try to read from pom.xml first and then ivy.xml if pom.xml is not found. If neither is found, + * Ivy is configured with defaults.*/ + private def autodetectDependencies(module: ModuleRevisionId) = + { + log.debug("Autodetecting dependencies.") + val defaultPOMFile = IvySbt.defaultPOM(paths.baseDirectory) + if(defaultPOMFile.canRead) + readPom(defaultPOMFile) + else + { + val defaultIvy = IvySbt.defaultIvyFile(paths.baseDirectory) + if(defaultIvy.canRead) + readIvyFile(defaultIvy) + else + { + val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION + log.warn("No dependency configuration found, using defaults.") + val moduleID = DefaultModuleDescriptor.newDefaultInstance(module) + IvySbt.addMainArtifact(moduleID) + IvySbt.addDefaultArtifact(defaultConf, moduleID) + (moduleID, defaultConf) + } + } + } + } +} + +private object IvySbt +{ + val DefaultIvyConfigFilename = "ivysettings.xml" + val DefaultIvyFilename = "ivy.xml" + val DefaultMavenFilename = "pom.xml" + + private def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) + private def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) + private def defaultPOM(project: File) = new File(project, DefaultMavenFilename) + + /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */ + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: IvyLogger) + { + val newDefault = new ChainResolver + newDefault.setName("sbt-chain") + newDefault.setReturnFirst(true) + newDefault.setCheckmodified(true) + resolvers.foreach(r => newDefault.add(ConvertResolver(r))) + settings.addResolver(newDefault) + settings.setDefaultResolver(newDefault.getName) + log.debug("Using repositories:\n" + resolvers.mkString("\n\t")) + } + private def configureCache(settings: IvySettings, dir: Option[File]) + { + val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) + val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) + manager.setUseOrigin(true) + manager.setChangingMatcher(PatternMatcher.REGEXP); + manager.setChangingPattern(".*-SNAPSHOT"); + settings.setDefaultRepositoryCacheManager(manager) + } + private def toIvyConfiguration(configuration: Configuration) = + { + import org.apache.ivy.core.module.descriptor.{Configuration => IvyConfig} + import IvyConfig.Visibility._ + import configuration._ + new IvyConfig(name, if(isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) + } + private def addDefaultArtifact(defaultConf: String, moduleID: DefaultModuleDescriptor) = + moduleID.addArtifact(defaultConf, new MDArtifact(moduleID, moduleID.getModuleRevisionId.getName, defaultType, defaultExtension)) + /** Adds the ivy.xml main artifact. */ + private def addMainArtifact(moduleID: DefaultModuleDescriptor) + { + val artifact = DefaultArtifact.newIvyArtifact(moduleID.getResolvedModuleRevisionId, moduleID.getPublicationDate) + moduleID.setModuleArtifact(artifact) + moduleID.check() + } + /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ + private def toID(m: ModuleID) = + { + import m._ + ModuleRevisionId.newInstance(organization, name, revision) + } + private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = + { + val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a)) + configurations.foreach(artifact.addConfiguration) + artifact + } + private def extra(artifact: Artifact) = artifact.classifier.map(c => javaMap("m:classifier" -> c)).getOrElse(null) + + private object javaMap + { + import java.util.{HashMap, Map} + def apply[K,V](pairs: (K,V)*): Map[K,V] = + { + val map = new HashMap[K,V] + pairs.foreach { case (key, value) => map.put(key, value) } + map + } + } + /** Creates a full ivy file for 'module' using the 'content' XML as the part after the <info>...</info> section. */ + private def wrapped(module: ModuleID, content: scala.xml.NodeSeq) = + { + import module._ + + + {content} + + } + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ + private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = + parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ + private def parseIvyXML(settings: IvySettings, xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = + { + val parser = new CustomXmlParser.CustomParser(settings) + parser.setMd(moduleID) + parser.setDefaultConf(defaultConfiguration) + parser.setValidate(validate) + parser.setInput(xml.getBytes) + parser.parse() + parser + } + + /** This method is used to add inline dependencies to the provided module. */ + def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Iterable[ModuleID], parser: CustomXmlParser.CustomParser) + { + for(dependency <- dependencies) + { + val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), false, dependency.isChanging, dependency.isTransitive) + dependency.configurations match + { + case None => // The configuration for this dependency was not explicitly specified, so use the default + parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) + case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + parser.parseDepsConfs(confs, dependencyDescriptor) + } + for(artifact <- dependency.explicitArtifacts) + { + import artifact.{name, classifier, `type`, extension, url} + val extraMap = extra(artifact) + val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) + for(conf <- dependencyDescriptor.getModuleConfigurations) + dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) + } + moduleID.addDependency(dependencyDescriptor) + } + } + /** This method is used to add inline artifacts to the provided module. */ + def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]) + { + val allConfigurations = moduleID.getPublicConfigurationsNames + for(artifact <- artifacts) + { + val configurationStrings = + { + val artifactConfigurations = artifact.configurations + if(artifactConfigurations.isEmpty) + allConfigurations + else + artifactConfigurations.map(_.name) + } + val ivyArtifact = toIvyArtifact(moduleID, artifact, configurationStrings) + configurationStrings.foreach(configuration => moduleID.addArtifact(configuration, ivyArtifact)) + } + } + /** This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. + * Ivy 2.0.0 always produces a DefaultModuleDescriptor. */ + private def toDefaultModuleDescriptor(md: ModuleDescriptor) = + md match + { + case dmd: DefaultModuleDescriptor => dmd + case _ => error("Unknown ModuleDescriptor type.") + } +} diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala new file mode 100644 index 000000000..ae3fcf6d2 --- /dev/null +++ b/ivy/IvyActions.scala @@ -0,0 +1,138 @@ +package xsbt + +import java.io.File + +import org.apache.ivy.{core, plugins, util, Ivy} +import core.cache.DefaultRepositoryCacheManager +import core.LogOptions +import core.deliver.DeliverOptions +import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} +import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import core.publish.PublishOptions +import core.resolve.ResolveOptions +import core.retrieve.RetrieveOptions +import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} + +final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val quiet: Boolean) extends NotNull + +object IvyActions +{ + /** Clears the Ivy cache, as configured by 'config'. */ + def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } + + /** Creates a Maven pom from the given Ivy configuration*/ + def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], output: File) + { + module.withModule { (ivy, md, default) => + addLateDependencies(ivy, md, default, extraDependencies) + val pomModule = keepConfigurations(md, configurations) + PomModuleDescriptorWriter.write(pomModule, DefaultConfigurationMapping, output) + module.logger.info("Wrote " + output.getAbsolutePath) + } + } + // todo: correct default configuration for extra dependencies + private def addLateDependencies(ivy: Ivy, module: DefaultModuleDescriptor, defaultConfiguration: String, extraDependencies: Iterable[ModuleID]) + { + val parser = new CustomXmlParser.CustomParser(ivy.getSettings) + parser.setMd(module) + val defaultConf = if(defaultConfiguration.contains("->")) defaultConfiguration else (defaultConfiguration + "->default(compile)") + parser.setDefaultConf(defaultConf) + IvySbt.addDependencies(module, extraDependencies, parser) + } + private def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = + configurations match + { + case Some(confs) => confs.map(_.name).toList.toArray + case None => module.getPublicConfigurationsNames + } + /** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. + * This currently only preserves the information required by makePom*/ + private def keepConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): ModuleDescriptor = + { + val keepConfigurations = getConfigurations(module, configurations) + val keepSet = Set(keepConfigurations.toSeq : _*) + def translate(dependency: DependencyDescriptor) = + { + val keep = dependency.getModuleConfigurations.filter(keepSet.contains) + if(keep.isEmpty) + None + else // TODO: translate the dependency to contain only configurations to keep + Some(dependency) + } + val newModule = new DefaultModuleDescriptor(module.getModuleRevisionId, "", null) + newModule.setHomePage(module.getHomePage) + for(dependency <- module.getDependencies; translated <- translate(dependency)) + newModule.addDependency(translated) + newModule + } + + def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], quiet: Boolean) + { + module.withModule { case (ivy, md, default) => + addLateDependencies(ivy, md, default, extraDependencies) + resolve(quiet)(ivy, md, default) // todo: set download = false for resolve + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(getConfigurations(md, configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + } + } + // todo: map configurations, extra dependencies + def publish(module: IvySbt#Module, resolverName: String, srcArtifactPatterns: Iterable[String], deliveredIvyPattern: Option[String], configurations: Option[Iterable[Configuration]]) + { + module.withModule { case (ivy, md, default) => + val revID = md.getModuleRevisionId + val patterns = new java.util.ArrayList[String] + srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) + val options = (new PublishOptions).setOverwrite(true) + deliveredIvyPattern.foreach(options.setSrcIvyPattern) + options.setConfs(getConfigurations(md, configurations)) + ivy.publish(revID, patterns, resolverName, options) + } + } + /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. + * 'updateConfig' configures the actual resolution and retrieval process. */ + def update(module: IvySbt#Module, configuration: UpdateConfiguration) + { + module.withModule { case (ivy, md, default) => + import configuration._ + resolve(quiet)(ivy, md, default) + val retrieveOptions = new RetrieveOptions + retrieveOptions.setSync(synchronize) + val patternBase = retrieveDirectory.getAbsolutePath + val pattern = + if(patternBase.endsWith(File.separator)) + patternBase + outputPattern + else + patternBase + File.separatorChar + outputPattern + ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) + } + } + private def resolve(quiet: Boolean)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) = + { + val resolveOptions = new ResolveOptions + if(quiet) + resolveOptions.setLog(LogOptions.LOG_DOWNLOAD_ONLY) + val resolveReport = ivy.resolve(module, resolveOptions) + if(resolveReport.hasError) + error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n")) + } +} + +private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap) +{ + override def getScope(confs: Array[String]) = + { + Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match + { + case Some(conf) => conf.name + case None => + if(confs.isEmpty || confs(0) == Configurations.Default.name) + null + else + confs(0) + } + } + override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) +} \ No newline at end of file diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala new file mode 100644 index 000000000..366917c92 --- /dev/null +++ b/ivy/IvyConfigurations.scala @@ -0,0 +1,33 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import java.io.File +import scala.xml.NodeSeq + +final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull +final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val log: IvyLogger) extends NotNull + +final class ModuleConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, + val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], + val artifacts: Iterable[Artifact], val validate: Boolean) extends NotNull +{ + def isUnconfigured = dependencies.isEmpty && ivyXML.isEmpty && configurations.isEmpty && + defaultConfiguration.isEmpty && artifacts.isEmpty +} +object ModuleConfiguration +{ + def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = + if(explicitConfigurations.isEmpty) + { + defaultConfiguration match + { + case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil + case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations + case _ => Nil + } + } + else + explicitConfigurations +} \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala new file mode 100644 index 000000000..ae89d431b --- /dev/null +++ b/ivy/IvyInterface.scala @@ -0,0 +1,360 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import java.io.File +import java.net.{URI, URL} +import scala.xml.NodeSeq +import org.apache.ivy.plugins.resolver.IBiblioResolver +import org.apache.ivy.util.url.CredentialsStore + +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]) extends NotNull +{ + override def toString = organization + ":" + name + ":" + revision + // () required for chaining + def notTransitive() = intransitive() + def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts) + def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts) + def from(url: String) = artifacts(Artifact(name, new URL(url))) + def classifier(c: String) = artifacts(Artifact(name, c)) + def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts) +} +object ModuleID +{ + def apply(organization: String, name: String, revision: String): ModuleID = ModuleID(organization, name, revision, None) + def apply(organization: String, name: String, revision: String, configurations: Option[String]): ModuleID = + ModuleID(organization, name, revision, configurations, false, true) + def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean): ModuleID = + ModuleID(organization, name, revision, configurations, isChanging, isTransitive, Nil) +} +sealed trait Resolver extends NotNull +{ + def name: String +} +sealed case class MavenRepository(name: String, root: String) extends Resolver +{ + override def toString = name + ": " + root +} + +object RepositoryHelpers +{ + final case class Patterns(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) extends NotNull + { + private[xsbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[xsbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) + private[xsbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) + } + final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) extends NotNull + { + def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) + } + /** Configuration specific to an Ivy filesystem resolver. */ + final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) extends NotNull + { + def transactional() = FileConfiguration(isLocal, Some(true)) + def nontransactional() = FileConfiguration(isLocal, Some(false)) + def nonlocal() = FileConfiguration(false, isTransactional) + } + sealed trait SshAuthentication extends NotNull + final case class PasswordAuthentication(user: String, password: String) extends SshAuthentication + final case class KeyFileAuthentication(keyfile: File, password: String) extends SshAuthentication +} +import RepositoryHelpers.{Patterns, SshConnection, FileConfiguration} +import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} + +/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ +sealed abstract class PatternsBasedRepository extends Resolver +{ + type RepositoryType <: PatternsBasedRepository + /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ + protected def copy(patterns: Patterns): RepositoryType + + /** The object representing the configured patterns for this repository. */ + def patterns: Patterns + + /** Enables maven 2 compatibility for this repository. */ + def mavenStyle() = copy(patterns.mavenStyle()) + /** Adds the given patterns for resolving/publishing Ivy files.*/ + def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) + /** Adds the given patterns for resolving/publishing artifacts.*/ + def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) +} +/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ +final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository +{ + type RepositoryType = FileRepository + protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) + private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) + def transactional() = copy(configuration.transactional()) + def nonlocal() = copy(configuration.nonlocal()) +} +final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository +{ + type RepositoryType = URLRepository + protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) +} +/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ +sealed abstract class SshBasedRepository extends PatternsBasedRepository +{ + type RepositoryType <: SshBasedRepository + protected def copy(connection: SshConnection): RepositoryType + private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) + + /** The object representing the configured ssh connection for this repository. */ + def connection: SshConnection + + /** Configures this to use the specified user name and password when connecting to the remote repository. */ + def as(user: String, password: String): RepositoryType = copy(new PasswordAuthentication(user, password)) + /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ + def as(keyfile: File, password: String): RepositoryType = copy(new KeyFileAuthentication(keyfile, password)) +} +/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ +final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository +{ + type RepositoryType = SshRepository + protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + /** Defines the permissions to set when publishing to this repository. */ + def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) + def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) +} +/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ +final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository +{ + type RepositoryType = SftpRepository + protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) + protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) +} + +import Resolver._ +object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) +object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) +object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) +object JavaNet1Repository extends Resolver +{ + def name = "java.net Maven1 Repository" +} + +object Resolver +{ + val ScalaToolsReleasesName = "Scala-Tools Maven2 Repository" + val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository" + val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" + val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" + + def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = + withDefaultResolvers(userResolvers, true) + def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] = + withDefaultResolvers(userResolvers, true, scalaTools) + def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = + Seq(Resolver.defaultLocal) ++ + userResolvers ++ + single(DefaultMavenRepository, mavenCentral)++ + single(ScalaToolsReleases, scalaTools) + private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if(nonEmpty) Seq(value) else Nil + + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull + { + /** Subclasses should implement this method to */ + protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType + /** Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject + * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, None, None, None) + /** Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, None) + /** Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, Some(basePath)) + /** Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), None) + /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), Some(basePath)) + /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = + construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) + } + /** A factory to construct an interface to an Ivy SSH resolver.*/ + object ssh extends Define[SshRepository] + { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) + } + /** A factory to construct an interface to an Ivy SFTP resolver.*/ + object sftp extends Define[SftpRepository] + { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) + } + /** A factory to construct an interface to an Ivy filesytem resolver. */ + object file + { + /** Constructs a file resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ + def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, ivyStylePatterns) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = + baseRepository(baseDirectory.toURI)(FileRepository(name, defaultFileConfiguration, _)) + } + object url + { + /** Constructs a URL resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ + def apply(name: String): URLRepository = URLRepository(name, ivyStylePatterns) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = + baseRepository(baseURL.toURI)(URLRepository(name, _)) + } + private def baseRepository[T](baseURI: java.net.URI)(construct: Patterns => T)(implicit basePatterns: Patterns): T = + construct(resolvePatterns(baseURI.normalize, basePatterns)) + + /** If `base` is None, `patterns` is returned unchanged. + * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ + private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = + base match + { + case Some(path) => resolvePatterns(pathURI(path), patterns) + case None => patterns + } + /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ + private def resolvePatterns(base: URI, basePatterns: Patterns): Patterns = + { + def resolve(pattern: String) = base.resolve(pathURI(pattern)).getPath + def resolveAll(patterns: Seq[String]) = patterns.map(resolve) + Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) + } + /** Constructs a `URI` with the path component set to `path` and the other components set to null.*/ + private def pathURI(path: String) = new URI(null, null, path, null) + + def defaultFileConfiguration = FileConfiguration(true, None) + def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) + def ivyStylePatterns = Patterns(Nil, Nil, false) + + def defaultPatterns = mavenStylePatterns + def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" + def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" + + def userRoot = System.getProperty("user.home") + def userMavenRoot = userRoot + "/.m2/repository/" + def userIvyRoot = userRoot + "/.ivy2/" + + def defaultLocal = defaultUserFileRepository("local") + def defaultShared = defaultUserFileRepository("shared") + def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns) + def defaultIvyPatterns = + { + val pList = List(localBasePattern) + Patterns(pList, pList, false) + } +} + +object Configurations +{ + def config(name: String) = new Configuration(name) + def defaultMavenConfigurations = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil + + lazy val Default = config("default") + lazy val Compile = config("compile") + lazy val IntegrationTest = config("it") hide + lazy val Provided = config("provided") + lazy val Javadoc = config("javadoc") + lazy val Runtime = config("runtime") + lazy val Test = config("test") hide + lazy val Sources = config("sources") + lazy val System = config("system") + lazy val Optional = config("optional") + + lazy val CompilerPlugin = config("plugin") hide + + private[xsbt] val DefaultMavenConfiguration = defaultConfiguration(true) + private[xsbt] val DefaultIvyConfiguration = defaultConfiguration(false) + private[xsbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration + private[xsbt] def defaultConfiguration(mavenStyle: Boolean) = + { + val base = if(mavenStyle) Configurations.Compile else Configurations.Default + config(base.name + "->default(compile)") + } + + private[xsbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) +} +/** Represents an Ivy configuration. */ +final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) extends NotNull +{ + require(name != null && !name.isEmpty) + require(description != null) + def this(name: String) = this(name, "", true, Nil, true) + def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) + def notTransitive = intransitive + def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) + def hide = Configuration(name, description, false, extendsConfigs, transitive) + override def toString = name +} + +final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]) extends NotNull +object Artifact +{ + def apply(name: String): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None) + def apply(name: String, classifier: String): Artifact = Artifact(name, defaultType, defaultExtension, Some(classifier), Nil, None) + def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) + def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) + val defaultExtension = "jar" + val defaultType = "jar" + private[this] def extract(url: URL, default: String) = + { + val s = url.toString + val i = s.lastIndexOf('.') + if(i >= 0) + s.substring(i+1) + else + default + } +} +/* +object Credentials +{ + /** Add the provided credentials to Ivy's credentials cache.*/ + def add(realm: String, host: String, userName: String, passwd: String): Unit = + CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) + /** Load credentials from the given file into Ivy's credentials cache.*/ + def apply(file: String, log: Logger): Unit = apply(Path.fromFile(file), log) + /** Load credentials from the given file into Ivy's credentials cache.*/ + def apply(file: File, log: Logger): Unit = apply(Path.fromFile(file), log) + /** Load credentials from the given file into Ivy's credentials cache.*/ + def apply(path: Path, log: Logger) + { + val msg = + if(path.exists) + { + val properties = new scala.collection.mutable.HashMap[String, String] + def get(keys: List[String]) = keys.flatMap(properties.get).firstOption.toRight(keys.head + " not specified in credentials file: " + path) + + impl.MapUtilities.read(properties, path, log) orElse + { + List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match + { + case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass); None + case (errors, _) => Some(errors.mkString("\n")) + } + } + } + else + Some("Credentials file " + path + " does not exist") + msg.foreach(x => log.warn(x)) + } + private[this] val RealmKeys = List("realm") + private[this] val HostKeys = List("host", "hostname") + private[this] val UserKeys = List("user", "user.name", "username") + private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") +}*/ \ No newline at end of file diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala new file mode 100644 index 000000000..ff3ad2f19 --- /dev/null +++ b/ivy/IvyLogger.scala @@ -0,0 +1,54 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import org.apache.ivy.util.{Message, MessageLogger} + +trait IvyLogger +{ + def info(msg: => String) + def debug(msg: => String) + def warn(msg: => String) + def error(msg: => String) + def verbose(msg: => String) +} + +/** Interface to Ivy logging. */ +private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger +{ + def rawlog(msg: String, level: Int) = log(msg, level) + def log(msg: String, level: Int) + { + import Message.{MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR} + level match + { + case MSG_DEBUG => debug(msg) + case MSG_VERBOSE => verbose(msg) + case MSG_INFO => info(msg) + case MSG_WARN => warn(msg) + case MSG_ERR => error(msg) + } + } + def debug(msg: String) = logger.debug(msg) + def verbose(msg: String) = logger.verbose(msg) + def deprecated(msg: String) = warn(msg) + def info(msg: String) = logger.info(msg) + def rawinfo(msg: String) = info(msg) + def warn(msg: String) = logger.warn(msg) + def error(msg: String) = logger.error(msg) + + private def emptyList = java.util.Collections.emptyList[T forSome { type T}] + def getProblems = emptyList + def getWarns = emptyList + def getErrors = emptyList + + def clearProblems = () + def sumupProblems = () + def progress = () + def endProgress = () + + def endProgress(msg: String) = info(msg) + def isShowProgress = false + def setShowProgress(progress: Boolean) {} +} diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala new file mode 100644 index 000000000..0f3332d34 --- /dev/null +++ b/ivy/IvyScala.scala @@ -0,0 +1,74 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009 Mark Harrah + */ +package xsbt + +import java.util.Collections +import scala.collection.mutable.HashSet + +import org.apache.ivy.{core, plugins} +import core.module.descriptor.{DefaultExcludeRule, ExcludeRule} +import core.module.descriptor.{DefaultModuleDescriptor, ModuleDescriptor} +import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import plugins.matcher.ExactPatternMatcher + +final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) extends NotNull +private object IvyScala +{ + val ScalaOrganization = "org.scala-lang" + val ScalaLibraryID = "scala-library" + val ScalaCompilerID = "scala-compiler" + + /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ + def checkModule(module: DefaultModuleDescriptor, conf: String)(check: IvyScala) + { + if(check.checkExplicit) + checkDependencies(module, check.scalaVersion, check.configurations) + if(check.filterImplicit) + excludeScalaJars(module, check.configurations) + } + /** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the + * dependencies matches scalaVersion. */ + private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration]) + { + val configSet = configurationSet(configurations) + for(dep <- module.getDependencies.toList) + { + val id = dep.getDependencyRevisionId + if(id.getOrganisation == ScalaOrganization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet.contains)) + error("Different Scala version specified in dependency ("+ id.getRevision + ") than in project (" + scalaVersion + ").") + } + } + private def configurationSet(configurations: Iterable[Configuration]) = HashSet(configurations.map(_.toString).toSeq : _*) + /** Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is + * done because normally these jars are already on the classpath and cannot/should not be overridden. The version + * of Scala to use is done by setting scala.version in the project definition. */ + private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) + { + val configurationNames = + { + val names = module.getConfigurationsNames + if(configurations.isEmpty) + names + else + { + val configSet = configurationSet(configurations) + configSet.intersect(HashSet(names : _*)) + configSet.toArray + } + } + def excludeScalaJar(name: String): Unit = + module.addExcludeRule(excludeRule(ScalaOrganization, name, configurationNames)) + excludeScalaJar(ScalaLibraryID) + excludeScalaJar(ScalaCompilerID) + } + /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for + * the given configurations. */ + private def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = + { + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "*", "*") + val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, Collections.emptyMap[AnyRef,AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } +} \ No newline at end of file From 3c68c20030c5a5c4046f4aa1ef8d13f354556c76 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 18 Aug 2009 00:51:08 -0400 Subject: [PATCH 0003/1030] Setup interface project for testing --- ivy/ComponentManager.scala | 45 +++++++++++++++++++++++++++++++++++++ ivy/CustomXmlParser.scala | 2 +- ivy/IvyActions.scala | 24 ++++++++++++++++++++ ivy/IvyConfigurations.scala | 2 ++ ivy/IvyInterface.scala | 15 +++++++++---- ivy/IvyLogger.scala | 2 +- 6 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 ivy/ComponentManager.scala diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala new file mode 100644 index 000000000..f1d441916 --- /dev/null +++ b/ivy/ComponentManager.scala @@ -0,0 +1,45 @@ +package xsbt + +import java.io.File +import xsbti.Versions + +/** A component manager provides access to the pieces of xsbt that are distributed as components. +* There are two types of components. The first type is compiled subproject jars with their dependencies. +* The second type is a subproject distributed as a source jar so that it can be compiled against a specific +* version of Scala. +* +* The component manager provides services to install and retrieve components to the local repository. +* This is used for source jars so that the compilation need not be repeated for other projects on the same +* machine. +*/ +class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull +{ + def location(id: String): File = new File(baseDirectory, id) + def directory(id: String): File = + { + val dir = location(id) + if(!dir.exists) + update(id) + dir + } + private def contents(dir: File): Seq[File] = + { + val fs = dir.listFiles + if(fs == null) Nil else fs + } + def files(id: String): Iterable[File] = + { + val fs = contents(directory(id)) + if(!fs.isEmpty) fs else error("Could not find required component '" + id + "'") + } + def file(id: String): File = + files(id).toList match { + case x :: Nil => x + case xs => error("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) + } + + def update(id: String): Unit = + IvyActions.basicRetrieveLocal(sbtModuleID("manager"), Seq(sbtModuleID(id)), location(id), log) + def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, Versions.Sbt) + def cache(id: String): Unit = IvyActions.basicPublishLocal(sbtModuleID(id), Nil, files(id), log) +} \ No newline at end of file diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index 6688d8ef7..91ca60a79 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -14,7 +14,7 @@ import plugins.repository.Resource import plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ -private object CustomXmlParser extends XmlModuleDescriptorParser with NotNull +private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings) extends Parser(CustomXmlParser, settings) with NotNull diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index ae3fcf6d2..cb7f74b62 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -18,6 +18,30 @@ final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: object IvyActions { + def basicPublishLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], artifactFiles: Iterable[File], log: IvyLogger) + { + val artifacts = artifactFiles.map(Artifact.defaultArtifact) + val (ivy, local) = basicLocalIvy(log) + val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, artifacts)) + val srcArtifactPatterns = artifactFiles.map(_.getAbsolutePath) + publish(module, local.name, srcArtifactPatterns, None, None) + } + def basicRetrieveLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], to: File, log: IvyLogger) + { + val (ivy, local) = basicLocalIvy(log) + val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, Nil)) + val up = new UpdateConfiguration(to, defaultOutputPattern, false, true) + update(module, up) + } + def defaultOutputPattern = "[artifact]-[revision](-[classifier]).[ext]" + private def basicLocalIvy(log: IvyLogger) = + { + val local = Resolver.defaultLocal + val paths = new IvyPaths(new File("."), None) + val conf = new IvyConfiguration(paths, Seq(local), log) + (new IvySbt(conf), local) + } + /** Clears the Ivy cache, as configured by 'config'. */ def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 366917c92..39b7948be 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -18,6 +18,8 @@ final class ModuleConfiguration(val module: ModuleID, val dependencies: Iterable } object ModuleConfiguration { + def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) = + new ModuleConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index ae89d431b..d31ac00c3 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -311,15 +311,22 @@ object Artifact def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) val defaultExtension = "jar" val defaultType = "jar" - private[this] def extract(url: URL, default: String) = + private[this] def extract(url: URL, default: String): String = extract(url.toString, default) + private[this] def extract(name: String, default: String): String = { - val s = url.toString - val i = s.lastIndexOf('.') + val i = name.lastIndexOf('.') if(i >= 0) - s.substring(i+1) + name.substring(i+1) else default } + def defaultArtifact(file: File) = + { + val name = file.getName + val i = name.lastIndexOf('.') + val base = if(i >= 0) name.substring(0, i) else name + Artifact(name, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) + } } /* object Credentials diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index ff3ad2f19..c58ffd054 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -5,7 +5,7 @@ package xsbt import org.apache.ivy.util.{Message, MessageLogger} -trait IvyLogger +trait IvyLogger extends NotNull { def info(msg: => String) def debug(msg: => String) From 2acaa0ad25fa8f1af73b2fb8245d96e56d0d0c05 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 20 Aug 2009 00:02:06 -0400 Subject: [PATCH 0004/1030] Tests and fixes for component manager and cache interface. --- ivy/ComponentManager.scala | 30 ++++- ivy/Ivy.scala | 16 +-- ivy/IvyActions.scala | 38 +++---- ivy/IvyCache.scala | 103 ++++++++++++++++++ ivy/IvyInterface.scala | 26 ++--- ivy/src/test/scala/ComponentManagerTest.scala | 95 ++++++++++++++++ ivy/src/test/scala/TestIvyLogger.scala | 9 ++ 7 files changed, 267 insertions(+), 50 deletions(-) create mode 100644 ivy/IvyCache.scala create mode 100644 ivy/src/test/scala/ComponentManagerTest.scala create mode 100644 ivy/src/test/scala/TestIvyLogger.scala diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index f1d441916..fc1209758 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -9,12 +9,16 @@ import xsbti.Versions * version of Scala. * * The component manager provides services to install and retrieve components to the local repository. -* This is used for source jars so that the compilation need not be repeated for other projects on the same +* This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull { + /** Get the location where files for component 'id' are stored. This method does not ensure that the component is retrieved from the + * local repository. By default, the location returned is is baseDirectory / id.*/ def location(id: String): File = new File(baseDirectory, id) + /** Get the location where files for component 'id' are stored. If the component has not yet been retrieved from the local repository, + * it is retrieved first. */ def directory(id: String): File = { val dir = location(id) @@ -22,24 +26,38 @@ class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull update(id) dir } + // get the contents of the given directory, wrapping a null result in an empty list. private def contents(dir: File): Seq[File] = { val fs = dir.listFiles if(fs == null) Nil else fs } + /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String): Iterable[File] = { val fs = contents(directory(id)) - if(!fs.isEmpty) fs else error("Could not find required component '" + id + "'") + if(!fs.isEmpty) fs else invalid("Could not find required component '" + id + "'") } + /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ def file(id: String): File = files(id).toList match { case x :: Nil => x - case xs => error("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) + case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) } - + private def invalid(msg: String) = throw new InvalidComponent(msg) + private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) + + /** Retrieve the file for component 'id' from the local repository. */ def update(id: String): Unit = - IvyActions.basicRetrieveLocal(sbtModuleID("manager"), Seq(sbtModuleID(id)), location(id), log) + try { IvyCache.retrieveCachedJar(sbtModuleID(id), location(id), log) } + catch { case e: NotInCache => invalid(e) } + def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, Versions.Sbt) - def cache(id: String): Unit = IvyActions.basicPublishLocal(sbtModuleID(id), Nil, files(id), log) + /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ + def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id), log) + def clearCache(id: String): Unit = IvyCache.clearCachedJar(sbtModuleID(id), log) +} +class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) +{ + def this(msg: String) = this(msg, null) } \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index d85a46733..ad7e4866c 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -73,13 +73,13 @@ final class IvySbt(configuration: IvyConfiguration) try { f(ivy) } finally { ivy.popContext() } } - + final class Module(val moduleConfiguration: ModuleConfiguration) extends NotNull { def logger = configuration.log def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } - + import moduleConfiguration._ private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = { @@ -97,7 +97,7 @@ final class IvySbt(configuration: IvyConfiguration) val moduleID = newConfiguredModuleID val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) - + val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) IvySbt.addArtifacts(moduleID, artifacts) @@ -112,7 +112,7 @@ final class IvySbt(configuration: IvyConfiguration) configurations.foreach(config => mod.addConfiguration(IvySbt.toIvyConfiguration(config))) mod } - + /** Parses the given Maven pom 'pomFile'.*/ private def readPom(pomFile: File) = { @@ -164,11 +164,11 @@ private object IvySbt val DefaultIvyConfigFilename = "ivysettings.xml" val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" - + private def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) private def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) private def defaultPOM(project: File) = new File(project, DefaultMavenFilename) - + /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */ private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: IvyLogger) { @@ -207,7 +207,7 @@ private object IvySbt moduleID.check() } /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ - private def toID(m: ModuleID) = + private[xsbt] def toID(m: ModuleID) = { import m._ ModuleRevisionId.newInstance(organization, name, revision) @@ -253,7 +253,7 @@ private object IvySbt parser.parse() parser } - + /** This method is used to add inline dependencies to the provided module. */ def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Iterable[ModuleID], parser: CustomXmlParser.CustomParser) { diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index cb7f74b62..3b95062a9 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -6,6 +6,7 @@ import org.apache.ivy.{core, plugins, util, Ivy} import core.cache.DefaultRepositoryCacheManager import core.LogOptions import core.deliver.DeliverOptions +import core.install.InstallOptions import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} @@ -18,33 +19,24 @@ final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: object IvyActions { - def basicPublishLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], artifactFiles: Iterable[File], log: IvyLogger) + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ + def install(module: IvySbt#Module, from: String, to: String) { - val artifacts = artifactFiles.map(Artifact.defaultArtifact) - val (ivy, local) = basicLocalIvy(log) - val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, artifacts)) - val srcArtifactPatterns = artifactFiles.map(_.getAbsolutePath) - publish(module, local.name, srcArtifactPatterns, None, None) - } - def basicRetrieveLocal(moduleID: ModuleID, dependencies: Iterable[ModuleID], to: File, log: IvyLogger) - { - val (ivy, local) = basicLocalIvy(log) - val module = new ivy.Module(ModuleConfiguration(moduleID, dependencies, Nil)) - val up = new UpdateConfiguration(to, defaultOutputPattern, false, true) - update(module, up) - } - def defaultOutputPattern = "[artifact]-[revision](-[classifier]).[ext]" - private def basicLocalIvy(log: IvyLogger) = - { - val local = Resolver.defaultLocal - val paths = new IvyPaths(new File("."), None) - val conf = new IvyConfiguration(paths, Seq(local), log) - (new IvySbt(conf), local) + module.withModule { (ivy, md, default) => + for(dependency <- md.getDependencies) + { + module.logger.info("Installing " + dependency) + val options = new InstallOptions + options.setValidate(module.moduleConfiguration.validate) + options.setTransitive(dependency.isTransitive) + ivy.install(dependency.getDependencyRevisionId, from, to, options) + } + } } /** Clears the Ivy cache, as configured by 'config'. */ def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } - + /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], output: File) { @@ -90,7 +82,7 @@ object IvyActions newModule.addDependency(translated) newModule } - + def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], quiet: Boolean) { module.withModule { case (ivy, md, default) => diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala new file mode 100644 index 000000000..cd6fdb2b2 --- /dev/null +++ b/ivy/IvyCache.scala @@ -0,0 +1,103 @@ +package xsbt + +import java.io.File +import java.net.URL + +import org.apache.ivy.{core, plugins, util} +import core.cache.{ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager} +import core.module.descriptor.{Artifact => IvyArtifact, DefaultArtifact} +import plugins.repository.file.{FileRepository=>IvyFileRepository, FileResource} +import plugins.repository.{ArtifactResourceResolver, Resource, ResourceDownloader} +import plugins.resolver.util.ResolvedResource +import util.FileUtil + +class NotInCache(val id: ModuleID, cause: Throwable) + extends RuntimeException(NotInCache(id, cause), cause) +{ + def this(id: ModuleID) = this(id, null) +} +private object NotInCache +{ + def apply(id: ModuleID, cause: Throwable) = + { + val postfix = if(cause == null) "" else (": " +cause.toString) + "File for " + id + " not in cache" + postfix + } +} +/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ +object IvyCache +{ + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ + def cacheJar(moduleID: ModuleID, file: File, log: IvyLogger) + { + val artifact = defaultArtifact(moduleID) + val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) + withDefaultCache(log) { cache => + val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } + cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) + } + } + /** Clears the cache of the jar for the given ID.*/ + def clearCachedJar(id: ModuleID, log: IvyLogger) + { + try { getCachedFile(id, log).delete } + catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } + } + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ + def retrieveCachedJar(id: ModuleID, toDirectory: File, log: IvyLogger) = + { + val cachedFile = getCachedFile(id, log) + val copyTo = new File(toDirectory, cachedFile.getName) + FileUtil.copy(cachedFile, copyTo, null) + copyTo + } + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown.*/ + def getCachedFile(id: ModuleID, log: IvyLogger): File = + { + val cachedFile = + try + { + withDefaultCache(log) { cache => + val artifact = defaultArtifact(id) + cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) + } + } + catch { case e: Exception => throw new NotInCache(id, e) } + + if(cachedFile.exists) cachedFile else throw new NotInCache(id) + } + /** Calls the given function with the default Ivy cache.*/ + def withDefaultCache[T](log: IvyLogger)(f: DefaultRepositoryCacheManager => T): T = + { + val (ivy, local) = basicLocalIvy(log) + ivy.withIvy { ivy => + val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] + cache.setUseOrigin(false) + f(cache) + } + } + private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ + private def basicLocalIvy(log: IvyLogger) = + { + val local = Resolver.defaultLocal + val paths = new IvyPaths(new File("."), None) + val conf = new IvyConfiguration(paths, Seq(local), log) + (new IvySbt(conf), local) + } + /** Creates a default jar artifact based on the given ID.*/ + private def defaultArtifact(moduleID: ModuleID): IvyArtifact = + new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") +} +/** Required by Ivy for copying to the cache.*/ +private class FileDownloader extends ResourceDownloader with NotNull +{ + def download(artifact: IvyArtifact, resource: Resource, dest: File) + { + if(dest.exists()) dest.delete() + val part = new File(dest.getAbsolutePath + ".part") + FileUtil.copy(resource.openStream, part, null) + if(!part.renameTo(dest)) + error("Could not move temporary file " + part + " to final location " + dest) + } +} \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index d31ac00c3..5b8312cc9 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -72,7 +72,7 @@ sealed abstract class PatternsBasedRepository extends Resolver /** The object representing the configured patterns for this repository. */ def patterns: Patterns - + /** Enables maven 2 compatibility for this repository. */ def mavenStyle() = copy(patterns.mavenStyle()) /** Adds the given patterns for resolving/publishing Ivy files.*/ @@ -100,10 +100,10 @@ sealed abstract class SshBasedRepository extends PatternsBasedRepository type RepositoryType <: SshBasedRepository protected def copy(connection: SshConnection): RepositoryType private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) - + /** The object representing the configured ssh connection for this repository. */ def connection: SshConnection - + /** Configures this to use the specified user name and password when connecting to the remote repository. */ def as(user: String, password: String): RepositoryType = copy(new PasswordAuthentication(user, password)) /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ @@ -218,7 +218,7 @@ object Resolver } private def baseRepository[T](baseURI: java.net.URI)(construct: Patterns => T)(implicit basePatterns: Patterns): T = construct(resolvePatterns(baseURI.normalize, basePatterns)) - + /** If `base` is None, `patterns` is returned unchanged. * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = @@ -236,7 +236,7 @@ object Resolver } /** Constructs a `URI` with the path component set to `path` and the other components set to null.*/ private def pathURI(path: String) = new URI(null, null, path, null) - + def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) def ivyStylePatterns = Patterns(Nil, Nil, false) @@ -244,11 +244,11 @@ object Resolver def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" - + def userRoot = System.getProperty("user.home") def userMavenRoot = userRoot + "/.m2/repository/" def userIvyRoot = userRoot + "/.ivy2/" - + def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns) @@ -263,7 +263,7 @@ object Configurations { def config(name: String) = new Configuration(name) def defaultMavenConfigurations = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil - + lazy val Default = config("default") lazy val Compile = config("compile") lazy val IntegrationTest = config("it") hide @@ -276,7 +276,7 @@ object Configurations lazy val Optional = config("optional") lazy val CompilerPlugin = config("plugin") hide - + private[xsbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[xsbt] val DefaultIvyConfiguration = defaultConfiguration(false) private[xsbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration @@ -285,7 +285,7 @@ object Configurations val base = if(mavenStyle) Configurations.Compile else Configurations.Default config(base.name + "->default(compile)") } - + private[xsbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } /** Represents an Ivy configuration. */ @@ -311,8 +311,8 @@ object Artifact def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) val defaultExtension = "jar" val defaultType = "jar" - private[this] def extract(url: URL, default: String): String = extract(url.toString, default) - private[this] def extract(name: String, default: String): String = + def extract(url: URL, default: String): String = extract(url.toString, default) + def extract(name: String, default: String): String = { val i = name.lastIndexOf('.') if(i >= 0) @@ -346,7 +346,7 @@ object Credentials { val properties = new scala.collection.mutable.HashMap[String, String] def get(keys: List[String]) = keys.flatMap(properties.get).firstOption.toRight(keys.head + " not specified in credentials file: " + path) - + impl.MapUtilities.read(properties, path, log) orElse { List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala new file mode 100644 index 000000000..5d88297f4 --- /dev/null +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -0,0 +1,95 @@ +package xsbt + +import java.io.File +import org.specs._ +import FileUtilities.{createDirectory, delete, touch, withTemporaryDirectory} +import org.apache.ivy.util.ChecksumHelper + +object ComponentManagerTest extends Specification +{ + val TestID = "manager-test" + "Component manager" should { + "throw an exception if 'file' is called for a non-existing component" in { + withManager { _.file(TestID) must throwA[InvalidComponent] } + } + "throw an exception if 'file' is called for an empty component" in { + withManager { manager => + createDirectory(manager.location(TestID)) + ( manager.file(TestID) ) must throwA[InvalidComponent] + } + } + "return the file for a single-file component" in { + withManager { manager => + createFiles(manager, TestID, "a") match { case Seq(x) => + manager.file(TestID).getAbsoluteFile must beEqualTo(x.getAbsoluteFile) + } + } + } + + "throw an exception if 'file' is called for multi-file component" in { + withManager { manager => + createFiles(manager, TestID, "a", "b") + ( manager.file(TestID) ) must throwA[InvalidComponent] + } + } + "return the files for a multi-file component" in { + withManager { manager => + val files = createFiles(manager, TestID, "a", "b") + manager.files(TestID) must haveTheSameElementsAs(files) + } + } + "return the files for a single-file component" in { + withManager { manager => + val files = createFiles(manager, TestID, "a") + manager.files(TestID) must haveTheSameElementsAs(files) + } + } + "throw an exception if 'files' is called for a non-existing component" in { + withManager { _.files(TestID) must throwA[InvalidComponent] } + } + + "properly cache a file and then retrieve it to an unresolved component" in { + withManager { manager => + val file = createFile(manager, TestID, "a") + val hash = checksum(file) + try + { + manager.cache(TestID) + delete(manager.location(TestID)) + FileUtilities.listFiles(manager.location(TestID)).toList must haveSize(0) + checksum(manager.file(TestID)) must beEqualTo(hash) + } + finally { manager.clearCache(TestID) } + } + } + + "not retrieve to a component already resolved" in { + withManager { manager => + val file = createFile(manager, TestID, "a") + try + { + manager.cache(TestID) + val idDirectory = manager.location(TestID) + delete(idDirectory) + createDirectory(idDirectory) + manager.file(TestID) must throwA[InvalidComponent] + } + finally { manager.clearCache(TestID) } + } + } + } + private def checksum(file: File) = ChecksumHelper.computeAsString(file, "sha1") + private def createFile(manager: ComponentManager, id: String, name: String): File = createFiles(manager, id, name).toList.head + private def createFiles(manager: ComponentManager, id: String, names: String*): Seq[File] = + { + val dir = manager.location(id) + createDirectory(dir) + names.map { name => + val testFile = new File(dir, name) + touch(testFile) + testFile + } + } + private def withManager[T](f: ComponentManager => T): T = + TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(temp, logger)) } ) +} \ No newline at end of file diff --git a/ivy/src/test/scala/TestIvyLogger.scala b/ivy/src/test/scala/TestIvyLogger.scala new file mode 100644 index 000000000..5ed7716d2 --- /dev/null +++ b/ivy/src/test/scala/TestIvyLogger.scala @@ -0,0 +1,9 @@ +package xsbt + +import xsbti.TestLogger + +class TestIvyLogger extends TestLogger with IvyLogger +object TestIvyLogger +{ + def apply[T](f: TestIvyLogger => T): T = TestLogger(new TestIvyLogger)(f) +} \ No newline at end of file From 1fedab85be1f4df3a1169f65f652be4d67d4eb64 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 5 Sep 2009 12:19:34 -0400 Subject: [PATCH 0005/1030] Filling in logging and making cross-compile work. --- ivy/src/test/scala/TestIvyLogger.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/src/test/scala/TestIvyLogger.scala b/ivy/src/test/scala/TestIvyLogger.scala index 5ed7716d2..9d987b806 100644 --- a/ivy/src/test/scala/TestIvyLogger.scala +++ b/ivy/src/test/scala/TestIvyLogger.scala @@ -1,9 +1,12 @@ package xsbt -import xsbti.TestLogger - -class TestIvyLogger extends TestLogger with IvyLogger +class TestIvyLogger extends BufferedLogger(new ConsoleLogger) with IvyLogger { def verbose(msg: => String) = info(msg) } object TestIvyLogger { - def apply[T](f: TestIvyLogger => T): T = TestLogger(new TestIvyLogger)(f) + def apply[T](f: IvyLogger => T): T = + { + val log = new TestIvyLogger + log.setLevel(Level.Debug) + log.bufferQuietly(f(log)) + } } \ No newline at end of file From b6b7fe2f9b2c0202025c4f86daa163bcf40f13a9 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 8 Sep 2009 23:13:30 -0400 Subject: [PATCH 0006/1030] Updates to Ivy component and getting launcher component working. --- ivy/Ivy.scala | 83 ++++++++++++++++++------------------- ivy/IvyConfigurations.scala | 39 +++++++++++++---- ivy/IvyInterface.scala | 19 ++++++--- 3 files changed, 87 insertions(+), 54 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index ad7e4866c..3e45f790b 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -80,21 +80,24 @@ final class IvySbt(configuration: IvyConfiguration) def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } - import moduleConfiguration._ private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = { val (baseModule, baseConfiguration) = - if(isUnconfigured) - autodetectDependencies(IvySbt.toID(module)) - else - configureModule - ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) - baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("m", "m") + moduleConfiguration match + { + case ic: InlineConfiguration => configureInline(ic) + case ec: EmptyConfiguration => configureEmpty(ec.module) + case pc: PomConfiguration => readPom(pc.file, pc.validate) + case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate) + } + moduleConfiguration.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) + baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra") (baseModule, baseConfiguration) } - private def configureModule = + private def configureInline(ic: InlineConfiguration) = { - val moduleID = newConfiguredModuleID + import ic._ + val moduleID = newConfiguredModuleID(module, configurations) val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) @@ -105,7 +108,7 @@ final class IvySbt(configuration: IvyConfiguration) IvySbt.addMainArtifact(moduleID) (moduleID, parser.getDefaultConf) } - private def newConfiguredModuleID = + private def newConfiguredModuleID(module: ModuleID, configurations: Iterable[Configuration]) = { val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) mod.setLastModified(System.currentTimeMillis) @@ -114,13 +117,13 @@ final class IvySbt(configuration: IvyConfiguration) } /** Parses the given Maven pom 'pomFile'.*/ - private def readPom(pomFile: File) = + private def readPom(pomFile: File, validate: Boolean) = { val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), validate) (IvySbt.toDefaultModuleDescriptor(md), "compile") } /** Parses the given Ivy file 'ivyFile'.*/ - private def readIvyFile(ivyFile: File) = + private def readIvyFile(ivyFile: File, validate: Boolean) = { val url = toURL(ivyFile) val parser = new CustomXmlParser.CustomParser(settings) @@ -131,30 +134,14 @@ final class IvySbt(configuration: IvyConfiguration) (IvySbt.toDefaultModuleDescriptor(md), parser.getDefaultConf) } private def toURL(file: File) = file.toURI.toURL - /** Called to determine dependencies when the dependency manager is SbtManager and no inline dependencies (Scala or XML) - * are defined. It will try to read from pom.xml first and then ivy.xml if pom.xml is not found. If neither is found, - * Ivy is configured with defaults.*/ - private def autodetectDependencies(module: ModuleRevisionId) = + private def configureEmpty(module: ModuleID) = { - log.debug("Autodetecting dependencies.") - val defaultPOMFile = IvySbt.defaultPOM(paths.baseDirectory) - if(defaultPOMFile.canRead) - readPom(defaultPOMFile) - else - { - val defaultIvy = IvySbt.defaultIvyFile(paths.baseDirectory) - if(defaultIvy.canRead) - readIvyFile(defaultIvy) - else - { - val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION - log.warn("No dependency configuration found, using defaults.") - val moduleID = DefaultModuleDescriptor.newDefaultInstance(module) - IvySbt.addMainArtifact(moduleID) - IvySbt.addDefaultArtifact(defaultConf, moduleID) - (moduleID, defaultConf) - } - } + val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION + val moduleID = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) + moduleID.setLastModified(System.currentTimeMillis) + moduleID.addConfiguration(IvySbt.toIvyConfiguration(Configurations.Default)) + IvySbt.addMainArtifact(moduleID) + (moduleID, defaultConf) } } } @@ -165,9 +152,9 @@ private object IvySbt val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" - private def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) - private def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) - private def defaultPOM(project: File) = new File(project, DefaultMavenFilename) + def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) + def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) + def defaultPOM(project: File) = new File(project, DefaultMavenFilename) /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */ private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: IvyLogger) @@ -190,7 +177,7 @@ private object IvySbt manager.setChangingPattern(".*-SNAPSHOT"); settings.setDefaultRepositoryCacheManager(manager) } - private def toIvyConfiguration(configuration: Configuration) = + def toIvyConfiguration(configuration: Configuration) = { import org.apache.ivy.core.module.descriptor.{Configuration => IvyConfig} import IvyConfig.Visibility._ @@ -207,10 +194,10 @@ private object IvySbt moduleID.check() } /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ - private[xsbt] def toID(m: ModuleID) = + def toID(m: ModuleID) = { import m._ - ModuleRevisionId.newInstance(organization, name, revision) + ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes)) } private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { @@ -218,7 +205,19 @@ private object IvySbt configurations.foreach(artifact.addConfiguration) artifact } - private def extra(artifact: Artifact) = artifact.classifier.map(c => javaMap("m:classifier" -> c)).getOrElse(null) + private def extra(artifact: Artifact) = + { + val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } + javaMap(artifact.extraAttributes) + } + private def javaMap(map: Map[String,String]) = + if(map.isEmpty) null + else + { + val wrap = scala.collection.jcl.Map(new java.util.HashMap[String,String]) + wrap ++= map + wrap.underlying + } private object javaMap { diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 39b7948be..6bf0115e5 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -9,17 +9,21 @@ import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val log: IvyLogger) extends NotNull -final class ModuleConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, - val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], - val artifacts: Iterable[Artifact], val validate: Boolean) extends NotNull +sealed trait ModuleConfiguration extends NotNull { - def isUnconfigured = dependencies.isEmpty && ivyXML.isEmpty && configurations.isEmpty && - defaultConfiguration.isEmpty && artifacts.isEmpty + def validate: Boolean + def ivyScala: Option[IvyScala] } -object ModuleConfiguration +final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration +final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration +final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, + val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], + val artifacts: Iterable[Artifact], val validate: Boolean) extends ModuleConfiguration +final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration +object InlineConfiguration { def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) = - new ModuleConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false) + new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) { @@ -32,4 +36,25 @@ object ModuleConfiguration } else explicitConfigurations +} +object ModuleConfiguration +{ + def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: IvyLogger) = + { + log.debug("Autodetecting dependencies.") + val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) + if(defaultPOMFile.canRead) + new PomConfiguration(defaultPOMFile, ivyScala, validate) + else + { + val defaultIvy = IvySbt.defaultIvyFile(baseDirectory) + if(defaultIvy.canRead) + new IvyFileConfiguration(defaultIvy, ivyScala, validate) + else + { + log.warn("No dependency configuration found, using defaults.") + new EmptyConfiguration(module, ivyScala, validate) + } + } + } } \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 5b8312cc9..f62266cb1 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,16 +9,17 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.IBiblioResolver import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]) extends NotNull +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact], extraAttributes: Map[String,String]) extends NotNull { override def toString = organization + ":" + name + ":" + revision // () required for chaining def notTransitive() = intransitive() - def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts) - def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts) + def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts, extraAttributes) + def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts, extraAttributes) def from(url: String) = artifacts(Artifact(name, new URL(url))) def classifier(c: String) = artifacts(Artifact(name, c)) - def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts) + def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes) + def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ attributes) } object ModuleID { @@ -27,6 +28,8 @@ object ModuleID ModuleID(organization, name, revision, configurations, false, true) def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean): ModuleID = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, Nil) + def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]): ModuleID = + ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, Map.empty) } sealed trait Resolver extends NotNull { @@ -302,13 +305,19 @@ final case class Configuration(name: String, description: String, isPublic: Bool override def toString = name } -final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]) extends NotNull +final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) extends NotNull +{ + def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ attributes) +} object Artifact { def apply(name: String): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None) + def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None, extra) def apply(name: String, classifier: String): Artifact = Artifact(name, defaultType, defaultExtension, Some(classifier), Nil, None) def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = + Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) val defaultExtension = "jar" val defaultType = "jar" def extract(url: URL, default: String): String = extract(url.toString, default) From abd06a17c5440d45fb30b61be172adc993e25c7f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 27 Sep 2009 14:39:26 -0400 Subject: [PATCH 0007/1030] Turned sbt launcher into a general Scala application launcher as described in launch.specification --- ivy/ComponentManager.scala | 29 ++------ ivy/ConvertResolver.scala | 2 +- ivy/CustomXmlParser.scala | 7 +- ivy/Ivy.scala | 27 +++++-- ivy/IvyActions.scala | 6 +- ivy/IvyCache.scala | 23 +++--- ivy/IvyConfigurations.scala | 15 ++-- ivy/IvyInterface.scala | 39 ++++++---- ivy/src/test/scala/ComponentManagerTest.scala | 73 ++++++++----------- 9 files changed, 108 insertions(+), 113 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index fc1209758..d13459a67 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -1,7 +1,6 @@ package xsbt import java.io.File -import xsbti.Versions /** A component manager provides access to the pieces of xsbt that are distributed as components. * There are two types of components. The first type is compiled subproject jars with their dependencies. @@ -12,30 +11,13 @@ import xsbti.Versions * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull +class ComponentManager(provider: xsbti.ComponentProvider, log: IvyLogger) extends NotNull { - /** Get the location where files for component 'id' are stored. This method does not ensure that the component is retrieved from the - * local repository. By default, the location returned is is baseDirectory / id.*/ - def location(id: String): File = new File(baseDirectory, id) - /** Get the location where files for component 'id' are stored. If the component has not yet been retrieved from the local repository, - * it is retrieved first. */ - def directory(id: String): File = - { - val dir = location(id) - if(!dir.exists) - update(id) - dir - } - // get the contents of the given directory, wrapping a null result in an empty list. - private def contents(dir: File): Seq[File] = - { - val fs = dir.listFiles - if(fs == null) Nil else fs - } /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String): Iterable[File] = { - val fs = contents(directory(id)) + val existing = provider.component(id) + val fs = if(existing.isEmpty) { update(id); provider.component(id) } else existing if(!fs.isEmpty) fs else invalid("Could not find required component '" + id + "'") } /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ @@ -47,12 +29,13 @@ class ComponentManager(baseDirectory: File, log: IvyLogger) extends NotNull private def invalid(msg: String) = throw new InvalidComponent(msg) private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) + def define(id: String, files: Iterable[File]) = provider.defineComponent(id, files.toSeq.toArray) /** Retrieve the file for component 'id' from the local repository. */ def update(id: String): Unit = - try { IvyCache.retrieveCachedJar(sbtModuleID(id), location(id), log) } + try { IvyCache.withCachedJar(sbtModuleID(id), log)(jar => define(id, Seq(jar)) ) } catch { case e: NotInCache => invalid(e) } - def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, Versions.Sbt) + def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, xsbti.Versions.Sbt) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id), log) def clearCache(id: String): Unit = IvyCache.clearCachedJar(sbtModuleID(id), log) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 51c3277eb..6625e604e 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -91,7 +91,7 @@ private object ConvertResolver setKeyFilePassword(password) } } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: RepositoryHelpers.Patterns) + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns) { resolver.setM2compatible(patterns.isMavenCompatible) patterns.ivyPatterns.foreach(resolver.addIvyPattern) diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index 91ca60a79..218b324ff 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -17,8 +17,10 @@ import plugins.repository.url.URLResource private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull { import XmlModuleDescriptorParser.Parser - class CustomParser(settings: IvySettings) extends Parser(CustomXmlParser, settings) with NotNull + class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) with NotNull { + defaultConfig.foreach(x => setDefaultConfMapping("*->default(compile)")) + def setSource(url: URL) = { super.setResource(new URLResource(url)) @@ -29,7 +31,6 @@ private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotN override def setResource(res: Resource) {} override def setMd(md: DefaultModuleDescriptor) = super.setMd(md) override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) - override def getDefaultConf = super.getDefaultConf - override def setDefaultConf(conf: String) = super.setDefaultConf(conf) + override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) } } \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 3e45f790b..fee07b00b 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -8,6 +8,7 @@ import Artifact.{defaultExtension, defaultType} import java.io.File import org.apache.ivy.{core, plugins, util, Ivy} +import core.IvyPatternHelper import core.cache.DefaultRepositoryCacheManager import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor} @@ -74,7 +75,7 @@ final class IvySbt(configuration: IvyConfiguration) finally { ivy.popContext() } } - final class Module(val moduleConfiguration: ModuleConfiguration) extends NotNull + final class Module(val moduleSettings: ModuleSettings) extends NotNull { def logger = configuration.log def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = @@ -83,14 +84,14 @@ final class IvySbt(configuration: IvyConfiguration) private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = { val (baseModule, baseConfiguration) = - moduleConfiguration match + moduleSettings match { case ic: InlineConfiguration => configureInline(ic) case ec: EmptyConfiguration => configureEmpty(ec.module) case pc: PomConfiguration => readPom(pc.file, pc.validate) case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate) } - moduleConfiguration.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) + moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra") (baseModule, baseConfiguration) } @@ -105,6 +106,7 @@ final class IvySbt(configuration: IvyConfiguration) IvySbt.addArtifacts(moduleID, artifacts) IvySbt.addDependencies(moduleID, dependencies, parser) + IvySbt.setModuleConfigurations(settings, moduleConfigurations) IvySbt.addMainArtifact(moduleID) (moduleID, parser.getDefaultConf) } @@ -126,7 +128,7 @@ final class IvySbt(configuration: IvyConfiguration) private def readIvyFile(ivyFile: File, validate: Boolean) = { val url = toURL(ivyFile) - val parser = new CustomXmlParser.CustomParser(settings) + val parser = new CustomXmlParser.CustomParser(settings, None) parser.setValidate(validate) parser.setSource(url) parser.parse() @@ -168,6 +170,20 @@ private object IvySbt settings.setDefaultResolver(newDefault.getName) log.debug("Using repositories:\n" + resolvers.mkString("\n\t")) } + private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration]) + { + val existing = settings.getResolverNames + for(moduleConf <- moduleConfigurations) + { + import moduleConf._ + import IvyPatternHelper._ + import PatternMatcher._ + if(!existing.contains(resolver.name)) + settings.addResolver(ConvertResolver(resolver)) + val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) + settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) + } + } private def configureCache(settings: IvySettings, dir: Option[File]) { val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) @@ -244,9 +260,8 @@ private object IvySbt /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ private def parseIvyXML(settings: IvySettings, xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = { - val parser = new CustomXmlParser.CustomParser(settings) + val parser = new CustomXmlParser.CustomParser(settings, Some(defaultConfiguration)) parser.setMd(moduleID) - parser.setDefaultConf(defaultConfiguration) parser.setValidate(validate) parser.setInput(xml.getBytes) parser.parse() diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 3b95062a9..f738a3912 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -27,7 +27,7 @@ object IvyActions { module.logger.info("Installing " + dependency) val options = new InstallOptions - options.setValidate(module.moduleConfiguration.validate) + options.setValidate(module.moduleSettings.validate) options.setTransitive(dependency.isTransitive) ivy.install(dependency.getDependencyRevisionId, from, to, options) } @@ -50,10 +50,8 @@ object IvyActions // todo: correct default configuration for extra dependencies private def addLateDependencies(ivy: Ivy, module: DefaultModuleDescriptor, defaultConfiguration: String, extraDependencies: Iterable[ModuleID]) { - val parser = new CustomXmlParser.CustomParser(ivy.getSettings) + val parser = new CustomXmlParser.CustomParser(ivy.getSettings, Some(defaultConfiguration)) parser.setMd(module) - val defaultConf = if(defaultConfiguration.contains("->")) defaultConfiguration else (defaultConfiguration + "->default(compile)") - parser.setDefaultConf(defaultConf) IvySbt.addDependencies(module, extraDependencies, parser) } private def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index cd6fdb2b2..9e9c4d9e4 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -40,19 +40,20 @@ object IvyCache /** Clears the cache of the jar for the given ID.*/ def clearCachedJar(id: ModuleID, log: IvyLogger) { - try { getCachedFile(id, log).delete } + try { withCachedJar(id, log)(_.delete) } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ def retrieveCachedJar(id: ModuleID, toDirectory: File, log: IvyLogger) = - { - val cachedFile = getCachedFile(id, log) - val copyTo = new File(toDirectory, cachedFile.getName) - FileUtil.copy(cachedFile, copyTo, null) - copyTo - } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown.*/ - def getCachedFile(id: ModuleID, log: IvyLogger): File = + withCachedJar(id, log) { cachedFile => + val copyTo = new File(toDirectory, cachedFile.getName) + FileUtil.copy(cachedFile, copyTo, null) + copyTo + } + + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown + * TODO: locking.*/ + def withCachedJar[T](id: ModuleID, log: IvyLogger)(f: File => T): T = { val cachedFile = try @@ -64,7 +65,7 @@ object IvyCache } catch { case e: Exception => throw new NotInCache(id, e) } - if(cachedFile.exists) cachedFile else throw new NotInCache(id) + if(cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } /** Calls the given function with the default Ivy cache.*/ def withDefaultCache[T](log: IvyLogger)(f: DefaultRepositoryCacheManager => T): T = @@ -82,7 +83,7 @@ object IvyCache { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), None) - val conf = new IvyConfiguration(paths, Seq(local), log) + val conf = new IvyConfiguration(paths, Seq(local), Nil, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 6bf0115e5..29cbd15ab 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -7,19 +7,20 @@ import java.io.File import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull -final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val log: IvyLogger) extends NotNull +final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], + val moduleConfigurations: Seq[ModuleConfiguration], val log: IvyLogger) extends NotNull -sealed trait ModuleConfiguration extends NotNull +sealed trait ModuleSettings extends NotNull { def validate: Boolean def ivyScala: Option[IvyScala] } -final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration -final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration +final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], - val artifacts: Iterable[Artifact], val validate: Boolean) extends ModuleConfiguration -final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleConfiguration + val artifacts: Iterable[Artifact], val validate: Boolean) extends ModuleSettings +final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings object InlineConfiguration { def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) = @@ -37,7 +38,7 @@ object InlineConfiguration else explicitConfigurations } -object ModuleConfiguration +object ModuleSettings { def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: IvyLogger) = { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index f62266cb1..f659321f2 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -19,7 +19,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def from(url: String) = artifacts(Artifact(name, new URL(url))) def classifier(c: String) = artifacts(Artifact(name, c)) def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes) - def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ attributes) + def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ ModuleID.checkE(attributes)) } object ModuleID { @@ -30,6 +30,10 @@ object ModuleID ModuleID(organization, name, revision, configurations, isChanging, isTransitive, Nil) def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]): ModuleID = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, Map.empty) + + def checkE(attributes: Seq[(String, String)]) = + for ( (key, value) <- attributes) yield + if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } sealed trait Resolver extends NotNull { @@ -40,14 +44,20 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver override def toString = name + ": " + root } +final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) extends NotNull +{ + private[xsbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[xsbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) + private[xsbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) +} +object Patterns +{ + def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) + def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(Nil, artifactPatterns, isMavenCompatible) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) +} object RepositoryHelpers { - final case class Patterns(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) extends NotNull - { - private[xsbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) - private[xsbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) - private[xsbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) - } final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) extends NotNull { def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) @@ -63,7 +73,7 @@ object RepositoryHelpers final case class PasswordAuthentication(user: String, password: String) extends SshAuthentication final case class KeyFileAuthentication(keyfile: File, password: String) extends SshAuthentication } -import RepositoryHelpers.{Patterns, SshConnection, FileConfiguration} +import RepositoryHelpers.{SshConnection, FileConfiguration} import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} /** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ @@ -283,12 +293,7 @@ object Configurations private[xsbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[xsbt] val DefaultIvyConfiguration = defaultConfiguration(false) private[xsbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration - private[xsbt] def defaultConfiguration(mavenStyle: Boolean) = - { - val base = if(mavenStyle) Configurations.Compile else Configurations.Default - config(base.name + "->default(compile)") - } - + private[xsbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default private[xsbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } /** Represents an Ivy configuration. */ @@ -337,6 +342,12 @@ object Artifact Artifact(name, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } } +final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) extends NotNull +object ModuleConfiguration +{ + def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) + def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) +} /* object Credentials { diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 5d88297f4..6928ab98a 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -14,34 +14,33 @@ object ComponentManagerTest extends Specification } "throw an exception if 'file' is called for an empty component" in { withManager { manager => - createDirectory(manager.location(TestID)) + manager.define(TestID, Nil) ( manager.file(TestID) ) must throwA[InvalidComponent] } } "return the file for a single-file component" in { withManager { manager => - createFiles(manager, TestID, "a") match { case Seq(x) => - manager.file(TestID).getAbsoluteFile must beEqualTo(x.getAbsoluteFile) - } + val hash = defineFile(manager, TestID, "a") + checksum(manager.file(TestID)) must beEqualTo(hash) } } "throw an exception if 'file' is called for multi-file component" in { withManager { manager => - createFiles(manager, TestID, "a", "b") + defineFiles(manager, TestID, "a", "b") ( manager.file(TestID) ) must throwA[InvalidComponent] } } "return the files for a multi-file component" in { withManager { manager => - val files = createFiles(manager, TestID, "a", "b") - manager.files(TestID) must haveTheSameElementsAs(files) + val hashes = defineFiles(manager, TestID, "a", "b") + checksum(manager.files(TestID)) must haveTheSameElementsAs(hashes) } } "return the files for a single-file component" in { withManager { manager => - val files = createFiles(manager, TestID, "a") - manager.files(TestID) must haveTheSameElementsAs(files) + val hashes = defineFiles(manager, TestID, "a") + checksum(manager.files(TestID)) must haveTheSameElementsAs(hashes) } } "throw an exception if 'files' is called for a non-existing component" in { @@ -49,47 +48,33 @@ object ComponentManagerTest extends Specification } "properly cache a file and then retrieve it to an unresolved component" in { - withManager { manager => - val file = createFile(manager, TestID, "a") - val hash = checksum(file) + withManager { definingManager => + val hash = defineFile(definingManager, TestID, "a") try { - manager.cache(TestID) - delete(manager.location(TestID)) - FileUtilities.listFiles(manager.location(TestID)).toList must haveSize(0) - checksum(manager.file(TestID)) must beEqualTo(hash) + definingManager.cache(TestID) + withManager { usingManager => + checksum(usingManager.file(TestID)) must beEqualTo(hash) + } } - finally { manager.clearCache(TestID) } - } - } - - "not retrieve to a component already resolved" in { - withManager { manager => - val file = createFile(manager, TestID, "a") - try - { - manager.cache(TestID) - val idDirectory = manager.location(TestID) - delete(idDirectory) - createDirectory(idDirectory) - manager.file(TestID) must throwA[InvalidComponent] - } - finally { manager.clearCache(TestID) } + finally { definingManager.clearCache(TestID) } } } } - private def checksum(file: File) = ChecksumHelper.computeAsString(file, "sha1") - private def createFile(manager: ComponentManager, id: String, name: String): File = createFiles(manager, id, name).toList.head - private def createFiles(manager: ComponentManager, id: String, names: String*): Seq[File] = - { - val dir = manager.location(id) - createDirectory(dir) - names.map { name => - val testFile = new File(dir, name) - touch(testFile) - testFile + private def checksum(files: Iterable[File]): Seq[String] = files.map(checksum).toSeq + private def checksum(file: File): String = if(file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" + private def defineFile(manager: ComponentManager, id: String, name: String): String = createFile(manager, id, name)(checksum) + private def defineFiles(manager: ComponentManager, id: String, names: String*): Seq[String] = createFiles(manager, id, names : _*)(checksum) + private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = createFiles(manager, id, name)(files => f(files.toList.head)) + private def createFiles[T](manager: ComponentManager, id: String, names: String*)(f: Seq[File] => T): T = + withTemporaryDirectory { dir => + val files = names.map(name => new File(dir, name) ) + files.foreach(writeRandomContent) + manager.define(id, files) + f(files) } - } + private def writeRandomContent(file: File) = FileUtilities.write(file, randomString) + private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(temp, logger)) } ) + TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(new xsbt.boot.ComponentProvider(temp), logger)) } ) } \ No newline at end of file From e08e1d2dacf12aa1d1da6b2e017f4015880199ab Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 1 Oct 2009 22:56:23 -0400 Subject: [PATCH 0008/1030] Include latest updates from sbt Ivy support --- ivy/CustomXmlParser.scala | 4 ++-- ivy/IvyInterface.scala | 32 +++++++++++++++++++------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index 218b324ff..1c4d88b0c 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -19,8 +19,8 @@ private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotN import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) with NotNull { - defaultConfig.foreach(x => setDefaultConfMapping("*->default(compile)")) - + if(defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") + def setSource(url: URL) = { super.setResource(new URLResource(url)) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index f659321f2..cd6f7009b 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -20,6 +20,12 @@ final case class ModuleID(organization: String, name: String, revision: String, def classifier(c: String) = artifacts(Artifact(name, c)) def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes) def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ ModuleID.checkE(attributes)) + def sources() = artifacts(Artifact(name, "sources", "jar", "sources")) + def javadoc() = artifacts(Artifact(name, "javadoc", "jar", "javadoc")) + def withSources() = jarIfEmpty.sources() + def withJavadoc() = jarIfEmpty.javadoc() + private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this + def jar() = artifacts(Artifact(name, "jar", "jar")) } object ModuleID { @@ -215,48 +221,47 @@ object Resolver { /** Constructs a file resolver with the given name. The patterns to use must be explicitly specified * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, ivyStylePatterns) + def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(baseDirectory.toURI)(FileRepository(name, defaultFileConfiguration, _)) + baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) } object url { /** Constructs a URL resolver with the given name. The patterns to use must be explicitly specified * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): URLRepository = URLRepository(name, ivyStylePatterns) + def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = - baseRepository(baseURL.toURI)(URLRepository(name, _)) + baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) } - private def baseRepository[T](baseURI: java.net.URI)(construct: Patterns => T)(implicit basePatterns: Patterns): T = - construct(resolvePatterns(baseURI.normalize, basePatterns)) + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = + construct(resolvePatterns(base, basePatterns)) /** If `base` is None, `patterns` is returned unchanged. * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = base match { - case Some(path) => resolvePatterns(pathURI(path), patterns) + case Some(path) => resolvePatterns(path, patterns) case None => patterns } /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ - private def resolvePatterns(base: URI, basePatterns: Patterns): Patterns = + private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = { - def resolve(pattern: String) = base.resolve(pathURI(pattern)).getPath + val normBase = base.replace('\\', '/') + def resolve(pattern: String) = if(normBase.endsWith("/") || pattern.startsWith("/")) normBase +pattern else normBase + "/" + pattern def resolveAll(patterns: Seq[String]) = patterns.map(resolve) Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) } - /** Constructs a `URI` with the path component set to `path` and the other components set to null.*/ - private def pathURI(path: String) = new URI(null, null, path, null) - + def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) def ivyStylePatterns = Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" + def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]" def userRoot = System.getProperty("user.home") def userMavenRoot = userRoot + "/.m2/repository/" @@ -320,6 +325,7 @@ object Artifact def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None, extra) def apply(name: String, classifier: String): Artifact = Artifact(name, defaultType, defaultExtension, Some(classifier), Nil, None) def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) + def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) From ac02123ace79407aa539ceb6988e904a1d2606f7 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 9 Oct 2009 19:12:14 -0400 Subject: [PATCH 0009/1030] Additions to help the sbt/xsbt combination --- ivy/ComponentManager.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index d13459a67..e420ffe22 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -11,7 +11,7 @@ import java.io.File * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(provider: xsbti.ComponentProvider, log: IvyLogger) extends NotNull +class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull { /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String): Iterable[File] = From ec61fa3df0e8a2c80fda68a06c5df41fb3d9994c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 10 Oct 2009 22:01:03 -0400 Subject: [PATCH 0010/1030] Synchronize caches --- ivy/ComponentManager.scala | 69 +++++++++++++++---- ivy/IvyCache.scala | 1 + ivy/src/test/scala/ComponentManagerTest.scala | 17 ++--- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index e420ffe22..483a0bb31 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -1,6 +1,7 @@ package xsbt -import java.io.File +import java.io.{File,FileOutputStream} +import ComponentManager.lock /** A component manager provides access to the pieces of xsbt that are distributed as components. * There are two types of components. The first type is compiled subproject jars with their dependencies. @@ -14,33 +15,73 @@ import java.io.File class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull { /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ - def files(id: String): Iterable[File] = + def files(id: String)(ifMissing: IfMissing): Iterable[File] = { - val existing = provider.component(id) - val fs = if(existing.isEmpty) { update(id); provider.component(id) } else existing - if(!fs.isEmpty) fs else invalid("Could not find required component '" + id + "'") + def fromGlobal = + lockGlobalCache { + try { update(id); getOrElse(createAndCache) } + catch { case e: NotInCache => createAndCache } + } + def getOrElse(orElse: => Iterable[File]) = + { + val existing = provider.component(id) + if(existing.isEmpty) orElse else existing + } + def notFound = invalid("Could not find required component '" + id + "'") + def createAndCache = + ifMissing match { + case IfMissing.Fail => notFound + case d: IfMissing.Define => + d() + if(d.cache) cache(id) + getOrElse(notFound) + } + + lockLocalCache { getOrElse(fromGlobal) } } + private def lockLocalCache[T](action: => T): T = lock("local cache", provider.lockFile, log) ( action ) + private def lockGlobalCache[T](action: => T): T = lock("global cache", IvyCache.lockFile, log)( action ) /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ - def file(id: String): File = - files(id).toList match { + def file(id: String)(ifMissing: IfMissing): File = + files(id)(ifMissing).toList match { case x :: Nil => x case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) } private def invalid(msg: String) = throw new InvalidComponent(msg) private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) - def define(id: String, files: Iterable[File]) = provider.defineComponent(id, files.toSeq.toArray) + def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } /** Retrieve the file for component 'id' from the local repository. */ - def update(id: String): Unit = - try { IvyCache.withCachedJar(sbtModuleID(id), log)(jar => define(id, Seq(jar)) ) } - catch { case e: NotInCache => invalid(e) } + private def update(id: String): Unit = IvyCache.withCachedJar(sbtModuleID(id), log)(jar => define(id, Seq(jar)) ) - def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, xsbti.Versions.Sbt) + private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, xsbti.Versions.Sbt) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ - def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id), log) - def clearCache(id: String): Unit = IvyCache.clearCachedJar(sbtModuleID(id), log) + def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), log) + def clearCache(id: String): Unit = lockGlobalCache { IvyCache.clearCachedJar(sbtModuleID(id), log) } } class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { def this(msg: String) = this(msg, null) +} +sealed trait IfMissing extends NotNull +object IfMissing +{ + object Fail extends IfMissing + final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } +} +object ComponentManager +{ + def lock[T](label: String, file: File, log: IvyLogger)(action: => T): T = + { + synchronized { + val channel = new FileOutputStream(file).getChannel + try { + val freeLock = channel.tryLock + val lock = if(freeLock eq null) { log.info("Waiting for " + label + " to be available..."); channel.lock } else freeLock + try { action } + finally { lock.release() } + } + finally { channel.close() } + } + } } \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 9e9c4d9e4..74c27e3e8 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -27,6 +27,7 @@ private object NotInCache /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ object IvyCache { + def lockFile = new File(System.getProperty("temp.dir"), "sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, log: IvyLogger) { diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 6928ab98a..90613ce1e 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -4,47 +4,48 @@ import java.io.File import org.specs._ import FileUtilities.{createDirectory, delete, touch, withTemporaryDirectory} import org.apache.ivy.util.ChecksumHelper +import IfMissing.Fail object ComponentManagerTest extends Specification { val TestID = "manager-test" "Component manager" should { "throw an exception if 'file' is called for a non-existing component" in { - withManager { _.file(TestID) must throwA[InvalidComponent] } + withManager { _.file(TestID)(Fail) must throwA[InvalidComponent] } } "throw an exception if 'file' is called for an empty component" in { withManager { manager => manager.define(TestID, Nil) - ( manager.file(TestID) ) must throwA[InvalidComponent] + ( manager.file(TestID)(Fail) ) must throwA[InvalidComponent] } } "return the file for a single-file component" in { withManager { manager => val hash = defineFile(manager, TestID, "a") - checksum(manager.file(TestID)) must beEqualTo(hash) + checksum(manager.file(TestID)(Fail)) must beEqualTo(hash) } } "throw an exception if 'file' is called for multi-file component" in { withManager { manager => defineFiles(manager, TestID, "a", "b") - ( manager.file(TestID) ) must throwA[InvalidComponent] + ( manager.file(TestID)(Fail) ) must throwA[InvalidComponent] } } "return the files for a multi-file component" in { withManager { manager => val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)) must haveTheSameElementsAs(hashes) + checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) } } "return the files for a single-file component" in { withManager { manager => val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)) must haveTheSameElementsAs(hashes) + checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) } } "throw an exception if 'files' is called for a non-existing component" in { - withManager { _.files(TestID) must throwA[InvalidComponent] } + withManager { _.files(TestID)(Fail) must throwA[InvalidComponent] } } "properly cache a file and then retrieve it to an unresolved component" in { @@ -54,7 +55,7 @@ object ComponentManagerTest extends Specification { definingManager.cache(TestID) withManager { usingManager => - checksum(usingManager.file(TestID)) must beEqualTo(hash) + checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) } } finally { definingManager.clearCache(TestID) } From a33bb71f502dc7fd22aba1bfa7c5d52acd6200d3 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 11 Oct 2009 15:43:42 -0400 Subject: [PATCH 0011/1030] Only write 'info' tag if user has not provided one. --- ivy/Ivy.scala | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index fee07b00b..6b7b89dce 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -245,15 +245,20 @@ private object IvySbt map } } - /** Creates a full ivy file for 'module' using the 'content' XML as the part after the <info>...</info> section. */ - private def wrapped(module: ModuleID, content: scala.xml.NodeSeq) = + /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ + private def wrapped(module: ModuleID, dependencies: scala.xml.NodeSeq) = { import module._ - - {content} + { if(hasInfo(dependencies)) + scala.xml.NodeSeq.Empty + else + + } + {dependencies} } + private def hasInfo(x: scala.xml.NodeSeq) = !({x} \ "info").isEmpty /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) From 94b8fb5a1980e493e52fd56c9b97147f89be8689 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 14 Oct 2009 18:05:53 -0400 Subject: [PATCH 0012/1030] Fix global lock implementation for ComponentManager --- ivy/ComponentManager.scala | 27 +++++-------------- ivy/IvyCache.scala | 2 +- ivy/src/test/scala/ComponentManagerTest.scala | 2 +- 3 files changed, 8 insertions(+), 23 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 483a0bb31..0056ace7a 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -1,7 +1,7 @@ package xsbt import java.io.{File,FileOutputStream} -import ComponentManager.lock +import java.util.concurrent.Callable /** A component manager provides access to the pieces of xsbt that are distributed as components. * There are two types of components. The first type is compiled subproject jars with their dependencies. @@ -12,7 +12,7 @@ import ComponentManager.lock * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull +class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull { /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String)(ifMissing: IfMissing): Iterable[File] = @@ -36,11 +36,12 @@ class ComponentManager(provider: xsbti.ComponentProvider, val log: IvyLogger) ex if(d.cache) cache(id) getOrElse(notFound) } - + lockLocalCache { getOrElse(fromGlobal) } } - private def lockLocalCache[T](action: => T): T = lock("local cache", provider.lockFile, log) ( action ) - private def lockGlobalCache[T](action: => T): T = lock("global cache", IvyCache.lockFile, log)( action ) + private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action ) + private def lockGlobalCache[T](action: => T): T = lock(IvyCache.lockFile)( action ) + private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ def file(id: String)(ifMissing: IfMissing): File = files(id)(ifMissing).toList match { @@ -68,20 +69,4 @@ object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } -} -object ComponentManager -{ - def lock[T](label: String, file: File, log: IvyLogger)(action: => T): T = - { - synchronized { - val channel = new FileOutputStream(file).getChannel - try { - val freeLock = channel.tryLock - val lock = if(freeLock eq null) { log.info("Waiting for " + label + " to be available..."); channel.lock } else freeLock - try { action } - finally { lock.release() } - } - finally { channel.close() } - } - } } \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 74c27e3e8..e3f0044bc 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -27,7 +27,7 @@ private object NotInCache /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ object IvyCache { - def lockFile = new File(System.getProperty("temp.dir"), "sbt.cache.lock") + def lockFile = new File(System.getProperty("java.io.tmpdir"), "sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, log: IvyLogger) { diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 90613ce1e..446cec24e 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = FileUtilities.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(new xsbt.boot.ComponentProvider(temp), logger)) } ) + TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) } \ No newline at end of file From 8325c28bb27b4bae94f9db1808909d9a8fef0cd0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 9 Nov 2009 22:02:53 -0500 Subject: [PATCH 0013/1030] Fix issue where compiler interface was poorly cached --- ivy/ComponentManager.scala | 13 ++++++++++++- ivy/IvyCache.scala | 3 +-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 0056ace7a..fc4606f6d 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -55,7 +55,7 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr /** Retrieve the file for component 'id' from the local repository. */ private def update(id: String): Unit = IvyCache.withCachedJar(sbtModuleID(id), log)(jar => define(id, Seq(jar)) ) - private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, xsbti.Versions.Sbt) + private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, ComponentManager.stampedVersion) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), log) def clearCache(id: String): Unit = lockGlobalCache { IvyCache.clearCachedJar(sbtModuleID(id), log) } @@ -69,4 +69,15 @@ object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } +} +object ComponentManager +{ + lazy val (version, timestamp) = + { + val properties = new java.util.Properties + val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") + try { properties.load(propertiesStream) } finally { propertiesStream.close() } + (properties.getProperty("version"), properties.getProperty("timestamp")) + } + lazy val stampedVersion = version + "_" + timestamp } \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index e3f0044bc..cfb829458 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -52,8 +52,7 @@ object IvyCache copyTo } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown - * TODO: locking.*/ + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ def withCachedJar[T](id: ModuleID, log: IvyLogger)(f: File => T): T = { val cachedFile = From dc66cec624055e259173986ea4da2146cbc603b9 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 10 Jan 2010 16:47:38 -0500 Subject: [PATCH 0014/1030] Fixes for Ivy interface component --- ivy/Ivy.scala | 3 ++- ivy/IvyInterface.scala | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 6b7b89dce..485a6fcf4 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -192,6 +192,7 @@ private object IvySbt manager.setChangingMatcher(PatternMatcher.REGEXP); manager.setChangingPattern(".*-SNAPSHOT"); settings.setDefaultRepositoryCacheManager(manager) + dir.foreach(dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath)) } def toIvyConfiguration(configuration: Configuration) = { @@ -224,7 +225,7 @@ private object IvySbt private def extra(artifact: Artifact) = { val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } - javaMap(artifact.extraAttributes) + javaMap(ea.extraAttributes) } private def javaMap(map: Map[String,String]) = if(map.isEmpty) null diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index cd6f7009b..15504e9b8 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -257,7 +257,7 @@ object Resolver def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) - def ivyStylePatterns = Patterns(Nil, Nil, false) + def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" @@ -354,7 +354,7 @@ object ModuleConfiguration def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) } -/* + object Credentials { /** Add the provided credentials to Ivy's credentials cache.*/ @@ -390,4 +390,4 @@ object Credentials private[this] val HostKeys = List("host", "hostname") private[this] val UserKeys = List("user", "user.name", "username") private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") -}*/ \ No newline at end of file +} \ No newline at end of file From 699f171d625c743f76601d798e453a7550e552ef Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 10 Jan 2010 21:06:00 -0500 Subject: [PATCH 0015/1030] compile fixes --- ivy/IvyInterface.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 15504e9b8..d44179deb 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -354,7 +354,7 @@ object ModuleConfiguration def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) } - +/* object Credentials { /** Add the provided credentials to Ivy's credentials cache.*/ @@ -390,4 +390,4 @@ object Credentials private[this] val HostKeys = List("host", "hostname") private[this] val UserKeys = List("user", "user.name", "username") private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") -} \ No newline at end of file +}*/ \ No newline at end of file From 9f9cbd55c73c82ce3120a129f99600a40db2e303 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Jan 2010 19:05:23 -0500 Subject: [PATCH 0016/1030] Replace Ivy interface with the component from xsbt --- ivy/ComponentManager.scala | 2 +- ivy/ConvertResolver.scala | 2 +- ivy/CustomXmlParser.scala | 4 +- ivy/Ivy.scala | 37 +++++-------- ivy/IvyActions.scala | 2 +- ivy/IvyCache.scala | 4 +- ivy/IvyConfigurations.scala | 54 ++++++++++++++++--- ivy/IvyInterface.scala | 18 +++---- ivy/IvyLogger.scala | 2 +- ivy/IvyScala.scala | 25 +++++---- ivy/src/test/scala/ComponentManagerTest.scala | 4 +- ivy/src/test/scala/TestIvyLogger.scala | 4 +- 12 files changed, 99 insertions(+), 59 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index fc4606f6d..5e2c8bd51 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -1,4 +1,4 @@ -package xsbt +package sbt import java.io.{File,FileOutputStream} import java.util.concurrent.Callable diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 6625e604e..1d9ec9414 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009 Mark Harrah */ -package xsbt +package sbt import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index 1c4d88b0c..f80eed9b9 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009 Mark Harrah */ -package xsbt +package sbt import java.io.ByteArrayInputStream import java.net.URL @@ -14,7 +14,7 @@ import plugins.repository.Resource import plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ -private[xsbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull +private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) with NotNull diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 485a6fcf4..a92e818b6 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ -package xsbt +package sbt import Artifact.{defaultExtension, defaultType} @@ -21,7 +21,7 @@ import util.Message final class IvySbt(configuration: IvyConfiguration) { - import configuration._ + import configuration.{log, baseDirectory} /** ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, @@ -39,12 +39,15 @@ final class IvySbt(configuration: IvyConfiguration) private lazy val settings = { val is = new IvySettings - is.setBaseDir(paths.baseDirectory) - IvySbt.configureCache(is, paths.cacheDirectory) - if(resolvers.isEmpty) - autodetectConfiguration(is) - else - IvySbt.setResolvers(is, resolvers, log) + is.setBaseDir(baseDirectory) + configuration match + { + case e: ExternalIvyConfiguration => is.load(e.file) + case i: InlineIvyConfiguration => + IvySbt.configureCache(is, i.paths.cacheDirectory) + IvySbt.setResolvers(is, i.resolvers, log) + IvySbt.setModuleConfigurations(is, i.moduleConfigurations) + } is } private lazy val ivy = @@ -53,17 +56,6 @@ final class IvySbt(configuration: IvyConfiguration) i.getLoggerEngine.pushLogger(logger) i } - /** Called to configure Ivy when inline resolvers are not specified. - * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - private def autodetectConfiguration(settings: IvySettings) - { - log.debug("Autodetecting configuration.") - val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) - if(defaultIvyConfigFile.canRead) - settings.load(defaultIvyConfigFile) - else - IvySbt.setResolvers(settings, Resolver.withDefaultResolvers(Nil), log) - } /** ========== End Configuration/Setup ============*/ /** Uses the configured Ivy instance within a safe context.*/ @@ -104,9 +96,7 @@ final class IvySbt(configuration: IvyConfiguration) val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) - IvySbt.addArtifacts(moduleID, artifacts) IvySbt.addDependencies(moduleID, dependencies, parser) - IvySbt.setModuleConfigurations(settings, moduleConfigurations) IvySbt.addMainArtifact(moduleID) (moduleID, parser.getDefaultConf) } @@ -115,6 +105,7 @@ final class IvySbt(configuration: IvyConfiguration) val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) mod.setLastModified(System.currentTimeMillis) configurations.foreach(config => mod.addConfiguration(IvySbt.toIvyConfiguration(config))) + IvySbt.addArtifacts(mod, module.explicitArtifacts) mod } @@ -301,7 +292,7 @@ private object IvySbt /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]) { - val allConfigurations = moduleID.getPublicConfigurationsNames + lazy val allConfigurations = moduleID.getPublicConfigurationsNames for(artifact <- artifacts) { val configurationStrings = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index f738a3912..5c4ddf2fb 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -1,4 +1,4 @@ -package xsbt +package sbt import java.io.File diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index cfb829458..64ccfd907 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -1,4 +1,4 @@ -package xsbt +package sbt import java.io.File import java.net.URL @@ -83,7 +83,7 @@ object IvyCache { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), None) - val conf = new IvyConfiguration(paths, Seq(local), Nil, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 29cbd15ab..ed2fccc55 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -1,30 +1,70 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ -package xsbt +package sbt import java.io.File import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull -final class IvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val log: IvyLogger) extends NotNull + +sealed trait IvyConfiguration extends NotNull +{ + def baseDirectory: File + def log: IvyLogger +} +final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], + val moduleConfigurations: Seq[ModuleConfiguration], val log: IvyLogger) extends IvyConfiguration +{ + def baseDirectory = paths.baseDirectory +} +final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val log: IvyLogger) extends IvyConfiguration + +object IvyConfiguration +{ + /** Called to configure Ivy when inline resolvers are not specified. + * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ + def apply(paths: IvyPaths, log: IvyLogger): IvyConfiguration = + { + log.debug("Autodetecting configuration.") + val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) + if(defaultIvyConfigFile.canRead) + new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, log) + else + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, log) + } +} sealed trait ModuleSettings extends NotNull { def validate: Boolean def ivyScala: Option[IvyScala] + def noScala: ModuleSettings } final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +{ + def noScala = new IvyFileConfiguration(file, None, validate) +} final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +{ + def noScala = new PomConfiguration(file, None, validate) +} final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], - val artifacts: Iterable[Artifact], val validate: Boolean) extends ModuleSettings + val validate: Boolean) extends ModuleSettings +{ + def withConfigurations(configurations: Iterable[Configuration]) = + new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) + def noScala = new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) +} final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +{ + def noScala = new EmptyConfiguration(module, None, validate) +} object InlineConfiguration { - def apply(module: ModuleID, dependencies: Iterable[ModuleID], artifacts: Iterable[Artifact]) = - new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, artifacts, false) + def apply(module: ModuleID, dependencies: Iterable[ModuleID]) = + new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index d44179deb..213e959e2 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009 Mark Harrah */ -package xsbt +package sbt import java.io.File import java.net.{URI, URL} @@ -52,9 +52,9 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) extends NotNull { - private[xsbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) - private[xsbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) - private[xsbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) + private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) + private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) } object Patterns { @@ -295,11 +295,11 @@ object Configurations lazy val CompilerPlugin = config("plugin") hide - private[xsbt] val DefaultMavenConfiguration = defaultConfiguration(true) - private[xsbt] val DefaultIvyConfiguration = defaultConfiguration(false) - private[xsbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration - private[xsbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default - private[xsbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) + private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) + private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) + private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration + private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default + private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } /** Represents an Ivy configuration. */ final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) extends NotNull diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index c58ffd054..7b062d7af 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009 Mark Harrah */ -package xsbt +package sbt import org.apache.ivy.util.{Message, MessageLogger} diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 0f3332d34..38ea1bd84 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ -package xsbt +package sbt import java.util.Collections import scala.collection.mutable.HashSet @@ -12,13 +12,18 @@ import core.module.descriptor.{DefaultModuleDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import plugins.matcher.ExactPatternMatcher +object ScalaArtifacts +{ + val Organization = "org.scala-lang" + val LibraryID = "scala-library" + val CompilerID = "scala-compiler" +} + +import ScalaArtifacts._ + final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) extends NotNull private object IvyScala { - val ScalaOrganization = "org.scala-lang" - val ScalaLibraryID = "scala-library" - val ScalaCompilerID = "scala-compiler" - /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String)(check: IvyScala) { @@ -35,7 +40,7 @@ private object IvyScala for(dep <- module.getDependencies.toList) { val id = dep.getDependencyRevisionId - if(id.getOrganisation == ScalaOrganization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet.contains)) + if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet.contains)) error("Different Scala version specified in dependency ("+ id.getRevision + ") than in project (" + scalaVersion + ").") } } @@ -58,9 +63,9 @@ private object IvyScala } } def excludeScalaJar(name: String): Unit = - module.addExcludeRule(excludeRule(ScalaOrganization, name, configurationNames)) - excludeScalaJar(ScalaLibraryID) - excludeScalaJar(ScalaCompilerID) + module.addExcludeRule(excludeRule(Organization, name, configurationNames)) + excludeScalaJar(LibraryID) + excludeScalaJar(CompilerID) } /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for * the given configurations. */ diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 446cec24e..ec29ae476 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -1,4 +1,6 @@ -package xsbt +package sbt + +import xsbt.{BufferedLogger, FileUtilities} import java.io.File import org.specs._ diff --git a/ivy/src/test/scala/TestIvyLogger.scala b/ivy/src/test/scala/TestIvyLogger.scala index 9d987b806..bf4386d7f 100644 --- a/ivy/src/test/scala/TestIvyLogger.scala +++ b/ivy/src/test/scala/TestIvyLogger.scala @@ -1,4 +1,6 @@ -package xsbt +package sbt + +import xsbt.{BufferedLogger, ConsoleLogger, Level} class TestIvyLogger extends BufferedLogger(new ConsoleLogger) with IvyLogger { def verbose(msg: => String) = info(msg) } object TestIvyLogger From 088ea157547eb7b05aa864077111c0b511e124cc Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 26 Jan 2010 18:41:03 -0500 Subject: [PATCH 0017/1030] Ignore 'unknown resolver' errors, work with published version of SBinary, work towards fixing OOME:PermGen issues on reload --- ivy/IvyLogger.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index 7b062d7af..8046a3982 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -36,7 +36,9 @@ private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger def info(msg: String) = logger.info(msg) def rawinfo(msg: String) = info(msg) def warn(msg: String) = logger.warn(msg) - def error(msg: String) = logger.error(msg) + def error(msg: String) = + if(!msg.startsWith("unknown resolver")) // hack to suppress these kinds of messages + logger.error(msg) private def emptyList = java.util.Collections.emptyList[T forSome { type T}] def getProblems = emptyList @@ -52,3 +54,10 @@ private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger def isShowProgress = false def setShowProgress(progress: Boolean) {} } + +/** This is a hack to filter error messages about 'unknown resolver ...'. */ +private final class SbtMessageLoggerEngine extends MessageLoggerEngine +{ + override def error(msg: String) = if(acceptError(msg)) super.error(msg) + def acceptError(msg: String) = (msg ne null) && !msg.startsWith("unknown resolver") +} \ No newline at end of file From b85d3df26f933c386b163703276fd94e3c19286e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 26 Jan 2010 22:35:59 -0500 Subject: [PATCH 0018/1030] fix compiler error in 'ivy' --- ivy/IvyLogger.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index 8046a3982..94b1fc3dc 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -3,7 +3,7 @@ */ package sbt -import org.apache.ivy.util.{Message, MessageLogger} +import org.apache.ivy.util.{Message, MessageLogger, MessageLoggerEngine} trait IvyLogger extends NotNull { From 04346217e83cd9bfaa43381cfb1b3ccb373ebb7a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 28 Jan 2010 19:31:04 -0500 Subject: [PATCH 0019/1030] Use a machine-global lock on Ivy because caches are not safe for concurrent access --- ivy/ComponentManager.scala | 8 +++++--- ivy/Ivy.scala | 35 +++++++++++++++++++++++++++++------ ivy/IvyCache.scala | 24 ++++++++++++------------ ivy/IvyConfigurations.scala | 11 ++++++----- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 5e2c8bd51..92e34b15a 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -39,7 +39,9 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr lockLocalCache { getOrElse(fromGlobal) } } + /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action ) + /** This is used to ensure atomic access to components in the global Ivy cache.*/ private def lockGlobalCache[T](action: => T): T = lock(IvyCache.lockFile)( action ) private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ @@ -53,12 +55,12 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } /** Retrieve the file for component 'id' from the local repository. */ - private def update(id: String): Unit = IvyCache.withCachedJar(sbtModuleID(id), log)(jar => define(id, Seq(jar)) ) + private def update(id: String): Unit = IvyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar)) ) private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, ComponentManager.stampedVersion) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ - def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), log) - def clearCache(id: String): Unit = lockGlobalCache { IvyCache.clearCachedJar(sbtModuleID(id), log) } + def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) + def clearCache(id: String): Unit = lockGlobalCache { IvyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } } class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index a92e818b6..21aceedf4 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -6,6 +6,7 @@ package sbt import Artifact.{defaultExtension, defaultType} import java.io.File +import java.util.concurrent.Callable import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper @@ -29,13 +30,25 @@ final class IvySbt(configuration: IvyConfiguration) */ private lazy val logger = new IvyLoggerInterface(log) private def withDefaultLogger[T](f: => T): T = - IvySbt.synchronized // Ivy is not thread-safe. In particular, it uses a static DocumentBuilder, which is not thread-safe + { + def action() = + IvySbt.synchronized + { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(logger) + try { f } + finally { Message.setDefaultLogger(originalLogger) } + } + // Ivy is not thread-safe nor can the cache be used concurrently. + // If provided a GlobalLock, we can use that to ensure safe access to the cache. + // Otherwise, we can at least synchronize within the JVM. + // For thread-safety In particular, Ivy uses a static DocumentBuilder, which is not thread-safe. + configuration.lock match { - val originalLogger = Message.getDefaultLogger - Message.setDefaultLogger(logger) - try { f } - finally { Message.setDefaultLogger(originalLogger) } + case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) + case None => action() } + } private lazy val settings = { val is = new IvySettings @@ -56,6 +69,8 @@ final class IvySbt(configuration: IvyConfiguration) i.getLoggerEngine.pushLogger(logger) i } + // Must be the same file as is used in Update in the launcher + private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") /** ========== End Configuration/Setup ============*/ /** Uses the configured Ivy instance within a safe context.*/ @@ -178,7 +193,15 @@ private object IvySbt private def configureCache(settings: IvySettings, dir: Option[File]) { val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) - val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) + val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { + override def clean() { delete(getBasedir); true } + private final def deleteAll(fs: Seq[File]) = if(fs ne null) fs foreach delete + private final def delete(f: File) + { + if(f.isDirectory) deleteAll(f.listFiles) + try { f.delete } catch { case _: java.io.IOException => } + } + } manager.setUseOrigin(true) manager.setChangingMatcher(PatternMatcher.REGEXP); manager.setChangingPattern(".*-SNAPSHOT"); diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 64ccfd907..c23218483 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -29,36 +29,36 @@ object IvyCache { def lockFile = new File(System.getProperty("java.io.tmpdir"), "sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ - def cacheJar(moduleID: ModuleID, file: File, log: IvyLogger) + def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: IvyLogger) { val artifact = defaultArtifact(moduleID) val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) - withDefaultCache(log) { cache => + withDefaultCache(lock, log) { cache => val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) } } /** Clears the cache of the jar for the given ID.*/ - def clearCachedJar(id: ModuleID, log: IvyLogger) + def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: IvyLogger) { - try { withCachedJar(id, log)(_.delete) } + try { withCachedJar(id, lock, log)(_.delete) } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ - def retrieveCachedJar(id: ModuleID, toDirectory: File, log: IvyLogger) = - withCachedJar(id, log) { cachedFile => + def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: IvyLogger) = + withCachedJar(id, lock, log) { cachedFile => val copyTo = new File(toDirectory, cachedFile.getName) FileUtil.copy(cachedFile, copyTo, null) copyTo } /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ - def withCachedJar[T](id: ModuleID, log: IvyLogger)(f: File => T): T = + def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: IvyLogger)(f: File => T): T = { val cachedFile = try { - withDefaultCache(log) { cache => + withDefaultCache(lock, log) { cache => val artifact = defaultArtifact(id) cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) } @@ -68,9 +68,9 @@ object IvyCache if(cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } /** Calls the given function with the default Ivy cache.*/ - def withDefaultCache[T](log: IvyLogger)(f: DefaultRepositoryCacheManager => T): T = + def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: IvyLogger)(f: DefaultRepositoryCacheManager => T): T = { - val (ivy, local) = basicLocalIvy(log) + val (ivy, local) = basicLocalIvy(lock, log) ivy.withIvy { ivy => val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] cache.setUseOrigin(false) @@ -79,11 +79,11 @@ object IvyCache } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ - private def basicLocalIvy(log: IvyLogger) = + private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: IvyLogger) = { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), None) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, lock, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index ed2fccc55..dbec791d6 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -10,28 +10,29 @@ final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) sealed trait IvyConfiguration extends NotNull { + def lock: Option[xsbti.GlobalLock] def baseDirectory: File def log: IvyLogger } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val log: IvyLogger) extends IvyConfiguration + val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { def baseDirectory = paths.baseDirectory } -final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val log: IvyLogger) extends IvyConfiguration +final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration object IvyConfiguration { /** Called to configure Ivy when inline resolvers are not specified. * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - def apply(paths: IvyPaths, log: IvyLogger): IvyConfiguration = + def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], log: IvyLogger): IvyConfiguration = { log.debug("Autodetecting configuration.") val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) if(defaultIvyConfigFile.canRead) - new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, log) + new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, lock, log) } } From 463f765274ea8aed225a2a34aa8a37aa19ee7c6d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 29 Jan 2010 20:29:55 -0500 Subject: [PATCH 0020/1030] Fix clean-cache --- ivy/Ivy.scala | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 21aceedf4..1c18d64b6 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -193,18 +193,11 @@ private object IvySbt private def configureCache(settings: IvySettings, dir: Option[File]) { val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) - val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { - override def clean() { delete(getBasedir); true } - private final def deleteAll(fs: Seq[File]) = if(fs ne null) fs foreach delete - private final def delete(f: File) - { - if(f.isDirectory) deleteAll(f.listFiles) - try { f.delete } catch { case _: java.io.IOException => } - } - } + val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) manager.setUseOrigin(true) manager.setChangingMatcher(PatternMatcher.REGEXP); manager.setChangingPattern(".*-SNAPSHOT"); + settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) dir.foreach(dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath)) } From c021eac274427cb843bc924a72b3ac2fda7e2c7b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 29 Jan 2010 20:31:07 -0500 Subject: [PATCH 0021/1030] Use custom pom generation instead of Ivy's built-in generation in order to support extra information like licenses. --- ivy/IvyActions.scala | 27 +++------- ivy/IvyCache.scala | 2 +- ivy/IvyConfigurations.scala | 12 ++++- ivy/IvyInterface.scala | 9 ++-- ivy/MakePom.scala | 104 ++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 26 deletions(-) create mode 100644 ivy/MakePom.scala diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 5c4ddf2fb..58a6571c8 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -1,6 +1,7 @@ package sbt import java.io.File +import scala.xml.NodeSeq import org.apache.ivy.{core, plugins, util, Ivy} import core.cache.DefaultRepositoryCacheManager @@ -35,15 +36,18 @@ object IvyActions } /** Clears the Ivy cache, as configured by 'config'. */ - def cleanCache(ivy: IvySbt) = ivy.withIvy { _.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } + def cleanCache(ivy: IvySbt) = ivy.withIvy { iv => + iv.getSettings.getResolutionCacheManager.clean() + iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) + } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], output: File) + def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File) { module.withModule { (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) val pomModule = keepConfigurations(md, configurations) - PomModuleDescriptorWriter.write(pomModule, DefaultConfigurationMapping, output) + (new PomWriter).write(pomModule, extra, output) module.logger.info("Wrote " + output.getAbsolutePath) } } @@ -132,21 +136,4 @@ object IvyActions if(resolveReport.hasError) error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n")) } -} - -private object DefaultConfigurationMapping extends PomModuleDescriptorWriter.ConfigurationScopeMapping(new java.util.HashMap) -{ - override def getScope(confs: Array[String]) = - { - Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match - { - case Some(conf) => conf.name - case None => - if(confs.isEmpty || confs(0) == Configurations.Default.name) - null - else - confs(0) - } - } - override def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) } \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index c23218483..9e7b25b80 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -81,7 +81,7 @@ object IvyCache /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: IvyLogger) = { - val local = Resolver.defaultLocal + val local = Resolver.defaultLocal(None) val paths = new IvyPaths(new File("."), None) val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, lock, log) (new IvySbt(conf), local) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index dbec791d6..83b272c6a 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -7,19 +7,29 @@ import java.io.File import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull - +{ + def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, cacheDirectory) +} sealed trait IvyConfiguration extends NotNull { + type This <: IvyConfiguration def lock: Option[xsbti.GlobalLock] def baseDirectory: File def log: IvyLogger + def withBase(newBaseDirectory: File): This } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { + type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, moduleConfigurations, lock, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration +{ + type This = ExternalIvyConfiguration + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, file, lock, log) +} object IvyConfiguration { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 213e959e2..66a831e62 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -167,7 +167,7 @@ object Resolver def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] = withDefaultResolvers(userResolvers, true, scalaTools) def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = - Seq(Resolver.defaultLocal) ++ + Seq(Resolver.defaultLocal(None)) ++ userResolvers ++ single(DefaultMavenRepository, mavenCentral)++ single(ScalaToolsReleases, scalaTools) @@ -266,10 +266,11 @@ object Resolver def userRoot = System.getProperty("user.home") def userMavenRoot = userRoot + "/.m2/repository/" def userIvyRoot = userRoot + "/.ivy2/" + private def userIvyRootFile = new File(userIvyRoot) - def defaultLocal = defaultUserFileRepository("local") - def defaultShared = defaultUserFileRepository("shared") - def defaultUserFileRepository(id: String) = file(id, new File(userIvyRoot, id))(defaultIvyPatterns) + def defaultLocal(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "local") + def defaultShared(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "shared") + def defaultUserFileRepository(ivyHome: Option[File], id: String) = file(id, new File(ivyHome.getOrElse(userIvyRootFile), id))(defaultIvyPatterns) def defaultIvyPatterns = { val pList = List(localBasePattern) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala new file mode 100644 index 000000000..06a515672 --- /dev/null +++ b/ivy/MakePom.scala @@ -0,0 +1,104 @@ +// based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0 +// http://www.apache.org/licenses/LICENSE-2.0 + +package sbt; + +import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} +import scala.xml.{Node, NodeSeq, XML} + +import org.apache.ivy.{core, Ivy} +import core.module.{descriptor, id} +import descriptor.{DependencyDescriptor, License, ModuleDescriptor} +import id.ModuleRevisionId + +class PomWriter +{ + def encoding = "UTF-8" + def write(module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(module, extra), output) + def write(node: Node, output: File) + { + output.getParentFile.mkdirs() + val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding)) + try { XML.write(out, node, encoding, true, null) } + finally { out.close() } + } + + def toPom(module: ModuleDescriptor, extra: NodeSeq): Node = + ( + 4.0.0 + { makeModuleID(module) } + { extra } + { makeDependencies(module) } + + ) + + def makeModuleID(module: ModuleDescriptor): NodeSeq = + { + val mrid = moduleDescriptor(module) + val a: NodeSeq = + ({ mrid.getOrganisation } + { mrid.getName } + { packaging(mrid) }) + val b: NodeSeq = + ( (description(module.getDescription) ++ + homePage(module.getHomePage) ++ + revision(mrid.getRevision) ++ + licenses(module.getLicenses)) : NodeSeq ) + a ++ b + } + + def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else {d} + def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else {ls.map(license)} + def license(l: License) = + + {l.getName} + {l.getUrl} + jar + + def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else {homePage} + def revision(version: String) = if(version ne null) {version} else NodeSeq.Empty + def packaging(module: ModuleRevisionId) = "jar"//module.getDefaultArtifact.getExt + + def makeDependencies(module: ModuleDescriptor): NodeSeq = + { + val dependencies = module.getDependencies + if(dependencies.isEmpty) NodeSeq.Empty + else + + { dependencies.map(makeDependency) } + + } + + def makeDependency(dependency: DependencyDescriptor): NodeSeq = + { + val mrid = dependency.getDependencyRevisionId + + {mrid.getOrganisation} + {mrid.getName} + {mrid.getRevision} + { scope(dependency)} + { optional(dependency) } + + } + + def scope(dependency: DependencyDescriptor): NodeSeq = + scope(getScope(dependency.getModuleConfigurations)) + def scope(scope: String): NodeSeq = if(scope ne null) {scope} else NodeSeq.Empty + def optional(dependency: DependencyDescriptor) = + if(isOptional(dependency.getModuleConfigurations)) true else NodeSeq.Empty + def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId + + def getScope(confs: Array[String]) = + { + Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match + { + case Some(conf) => conf.name + case None => + if(confs.isEmpty || confs(0) == Configurations.Default.name) + null + else + confs(0) + } + } + def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) +} From 1cc75faebaa1e0ed931a35d5c2945429af9c78e5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 30 Jan 2010 10:46:47 -0500 Subject: [PATCH 0022/1030] * Basic support for writing repositories to the pom in make-pom. * Pretty-print pom in make-pom --- ivy/IvyActions.scala | 2 +- ivy/MakePom.scala | 57 +++++++++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 58a6571c8..88bd731cf 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -47,7 +47,7 @@ object IvyActions module.withModule { (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) val pomModule = keepConfigurations(md, configurations) - (new PomWriter).write(pomModule, extra, output) + (new MakePom).write(ivy, pomModule, extra, output) module.logger.info("Wrote " + output.getAbsolutePath) } } diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 06a515672..f2089a254 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -4,32 +4,41 @@ package sbt; import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} -import scala.xml.{Node, NodeSeq, XML} +import scala.xml.{Node, NodeSeq, PrettyPrinter, XML} -import org.apache.ivy.{core, Ivy} +import org.apache.ivy.{core, plugins, Ivy} +import core.settings.IvySettings import core.module.{descriptor, id} import descriptor.{DependencyDescriptor, License, ModuleDescriptor} import id.ModuleRevisionId +import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} -class PomWriter +class MakePom { def encoding = "UTF-8" - def write(module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(module, extra), output) - def write(node: Node, output: File) + def write(ivy: Ivy, module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(ivy, module, extra), output) + def write(node: Node, output: File): Unit = write(toString(node), output) + def write(xmlString: String, output: File) { output.getParentFile.mkdirs() val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding)) - try { XML.write(out, node, encoding, true, null) } + try + { + out.write("") + out.newLine() + out.write(xmlString) + } finally { out.close() } } - def toPom(module: ModuleDescriptor, extra: NodeSeq): Node = + def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) + def toPom(ivy: Ivy, module: ModuleDescriptor, extra: NodeSeq): Node = ( 4.0.0 { makeModuleID(module) } { extra } { makeDependencies(module) } - + { makeRepositories(ivy.getSettings) } ) def makeModuleID(module: ModuleDescriptor): NodeSeq = @@ -101,4 +110,36 @@ class PomWriter } } def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) + + + def makeRepositories(settings: IvySettings) = + { + class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) + val repositories = resolvers(settings.getDefaultResolver) + val mavenRepositories = + repositories.flatMap { + case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => m :: Nil + case _ => Nil + } + mavenRepositories.map { repo => mavenRepository(repo.getName, repo.getRoot) } + } + def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if(rs eq null) Nil else rs.flatMap(resolvers) + def resolvers(r: DependencyResolver): Seq[DependencyResolver] = + r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } + + // cast the contents of a pre-generics collection + private def castResolvers(s: java.util.Collection[_]): Seq[DependencyResolver] = + s.toArray.map(_.asInstanceOf[DependencyResolver]) + + def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) + def isValidIDCharacter(c: Char) = c.isLetterOrDigit + private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id + def mavenRepository(name: String, root: String): Node = + mavenRepository(toID(name), name, root) + def mavenRepository(id: String, name: String, root: String): Node = + + {id} + {name} + {root} + } From aeb51e1d6c207bd82d60adfdb6e20f6844cbd9be Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 6 Feb 2010 14:14:49 -0500 Subject: [PATCH 0023/1030] Fix 'unknown resolver' errors in normal projects --- ivy/Ivy.scala | 4 +++- ivy/IvyLogger.scala | 15 ++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 1c18d64b6..48ee41ee4 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -65,7 +65,9 @@ final class IvySbt(configuration: IvyConfiguration) } private lazy val ivy = { - val i = Ivy.newInstance(settings) + val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine } + i.setSettings(settings) + i.bind() i.getLoggerEngine.pushLogger(logger) i } diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index 94b1fc3dc..a403c6622 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -36,9 +36,7 @@ private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger def info(msg: String) = logger.info(msg) def rawinfo(msg: String) = info(msg) def warn(msg: String) = logger.warn(msg) - def error(msg: String) = - if(!msg.startsWith("unknown resolver")) // hack to suppress these kinds of messages - logger.error(msg) + def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) logger.error(msg) private def emptyList = java.util.Collections.emptyList[T forSome { type T}] def getProblems = emptyList @@ -54,10 +52,13 @@ private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger def isShowProgress = false def setShowProgress(progress: Boolean) {} } - -/** This is a hack to filter error messages about 'unknown resolver ...'. */ private final class SbtMessageLoggerEngine extends MessageLoggerEngine { - override def error(msg: String) = if(acceptError(msg)) super.error(msg) - def acceptError(msg: String) = (msg ne null) && !msg.startsWith("unknown resolver") + /** This is a hack to filter error messages about 'unknown resolver ...'. */ + override def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) super.error(msg) +} +private object SbtIvyLogger +{ + val UnknownResolver = "unknown resolver" + def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) } \ No newline at end of file From 5c37531d235601320507d862a3084dc29f5fe088 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 6 Feb 2010 14:20:51 -0500 Subject: [PATCH 0024/1030] Add artifacts provided in EmptyConfiguration --- ivy/Ivy.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 48ee41ee4..01b190ff3 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -150,6 +150,7 @@ final class IvySbt(configuration: IvyConfiguration) val moduleID = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) moduleID.setLastModified(System.currentTimeMillis) moduleID.addConfiguration(IvySbt.toIvyConfiguration(Configurations.Default)) + IvySbt.addArtifacts(moduleID, module.explicitArtifacts) IvySbt.addMainArtifact(moduleID) (moduleID, defaultConf) } From f5e9b99677fdc37b52c08c42cd586e4db59c5513 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 6 Feb 2010 17:43:14 -0500 Subject: [PATCH 0025/1030] Throw a custom exception when there is an Ivy resolve error --- ivy/IvyActions.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 88bd731cf..6eb2705a4 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -134,6 +134,7 @@ object IvyActions resolveOptions.setLog(LogOptions.LOG_DOWNLOAD_ONLY) val resolveReport = ivy.resolve(module, resolveOptions) if(resolveReport.hasError) - error(Set(resolveReport.getAllProblemMessages.toArray: _*).mkString("\n")) + throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).toList.removeDuplicates) } -} \ No newline at end of file +} +final class ResolveException(messages: List[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file From c70896febe3652b2ac4f043dcd236be72385d82c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 6 Feb 2010 19:23:06 -0500 Subject: [PATCH 0026/1030] document some methods on Resolver --- ivy/IvyInterface.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 66a831e62..8df75d269 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -162,10 +162,15 @@ object Resolver val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" + /** Add the local, Maven Central, and Scala Tools releases repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = withDefaultResolvers(userResolvers, true) + /** Add the local Ivy and Maven Central repositories to the user repositories. If `scalaTools` is true, add the Scala Tools releases repository as well. */ def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] = withDefaultResolvers(userResolvers, true, scalaTools) + /** Add the local Ivy repository to the user repositories. + * If `scalaTools` is true, add the Scala Tools releases repository. + * If `mavenCentral` is true, add the Maven Central repository. */ def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = Seq(Resolver.defaultLocal(None)) ++ userResolvers ++ From 32482aac155e7a828c93115129c009a3909ea452 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 7 Feb 2010 23:45:19 -0500 Subject: [PATCH 0027/1030] legal cleanup --- ivy/ComponentManager.scala | 3 +++ ivy/ConvertResolver.scala | 2 +- ivy/CustomXmlParser.scala | 2 +- ivy/IvyActions.scala | 3 +++ ivy/IvyCache.scala | 3 +++ ivy/IvyConfigurations.scala | 2 +- ivy/IvyInterface.scala | 2 +- ivy/IvyLogger.scala | 2 +- ivy/MakePom.scala | 4 ++++ ivy/NOTICE | 28 ++++++++++++++++++++++++++++ 10 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 ivy/NOTICE diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 92e34b15a..0a67730d0 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -1,3 +1,6 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ package sbt import java.io.{File,FileOutputStream} diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 1d9ec9414..085689dca 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ package sbt diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index f80eed9b9..a8b7d9b43 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ package sbt diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 6eb2705a4..f034e7cfa 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -1,3 +1,6 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ package sbt import java.io.File diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 9e7b25b80..704192bdf 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -1,3 +1,6 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ package sbt import java.io.File diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 83b272c6a..a052b9fc2 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009, 2010 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ package sbt diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 8df75d269..ef4fc9569 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ package sbt diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index a403c6622..51f9afbb9 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -1,5 +1,5 @@ /* sbt -- Simple Build Tool - * Copyright 2008, 2009 Mark Harrah + * Copyright 2008, 2009, 2010 Mark Harrah */ package sbt diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index f2089a254..f96594a93 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -1,3 +1,7 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ + // based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 diff --git a/ivy/NOTICE b/ivy/NOTICE new file mode 100644 index 000000000..dd0df7b5a --- /dev/null +++ b/ivy/NOTICE @@ -0,0 +1,28 @@ +Simple Build Tool: Ivy Interface Component +Copyright 2008, 2009, 2010 Mark Harrah +Licensed under BSD-style license (see LICENSE) + +Portions based on Apache Ivy, +licensed under the Apache License, Version 2.0 (see licenses/LICENSE_Apache) + +It requires the following notice: + +This product includes software developed by +The Apache Software Foundation (http://www.apache.org/). + +Portions of Ivy were originally developed by +Jayasoft SARL (http://www.jayasoft.fr/) +and are licensed to the Apache Software Foundation under the +"Software Grant License Agreement" + + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From e0579ad5a882c2d018f174a51b5a0c121d1e4560 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 14 Feb 2010 20:24:33 -0500 Subject: [PATCH 0028/1030] Remove extra whitespace in pom output --- ivy/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index f96594a93..36814062e 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -51,7 +51,7 @@ class MakePom val a: NodeSeq = ({ mrid.getOrganisation } { mrid.getName } - { packaging(mrid) }) + { packaging(mrid) }) val b: NodeSeq = ( (description(module.getDescription) ++ homePage(module.getHomePage) ++ From d08517f57d11912898ca577e76cfd5095dabd185 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 14 Feb 2010 23:22:45 -0500 Subject: [PATCH 0029/1030] better choice of global lock file --- ivy/IvyCache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 704192bdf..98d50da9b 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -30,7 +30,7 @@ private object NotInCache /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ object IvyCache { - def lockFile = new File(System.getProperty("java.io.tmpdir"), "sbt.cache.lock") + def lockFile = new File(System.getProperty("user.home"), ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: IvyLogger) { From d9ad37894e051f852e90f05c06553b9da6af83ca Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 16 Feb 2010 12:30:42 -0500 Subject: [PATCH 0030/1030] wrap repositories in tag --- ivy/MakePom.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 36814062e..c59347160 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -125,7 +125,8 @@ class MakePom case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => m :: Nil case _ => Nil } - mavenRepositories.map { repo => mavenRepository(repo.getName, repo.getRoot) } + val repositoryElements = mavenRepositories.map { repo => mavenRepository(repo.getName, repo.getRoot) } + if(repositoryElements.isEmpty) repositoryElements else {repositoryElements} } def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if(rs eq null) Nil else rs.flatMap(resolvers) def resolvers(r: DependencyResolver): Seq[DependencyResolver] = From a8bc831189d38d49b9c392526cf8a01fbd573fbb Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 4 Mar 2010 00:07:12 -0500 Subject: [PATCH 0031/1030] Separate repositories for publishing from repositories for resolving/retrieving --- ivy/Ivy.scala | 25 +++++++++++++++++-------- ivy/IvyCache.scala | 2 +- ivy/IvyConfigurations.scala | 6 +++--- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 01b190ff3..76f88b1d2 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -58,7 +58,7 @@ final class IvySbt(configuration: IvyConfiguration) case e: ExternalIvyConfiguration => is.load(e.file) case i: InlineIvyConfiguration => IvySbt.configureCache(is, i.paths.cacheDirectory) - IvySbt.setResolvers(is, i.resolvers, log) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations) } is @@ -167,17 +167,26 @@ private object IvySbt def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) def defaultPOM(project: File) = new File(project, DefaultMavenFilename) - /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], log: IvyLogger) + /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. + * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], log: IvyLogger) { - val newDefault = new ChainResolver - newDefault.setName("sbt-chain") - newDefault.setReturnFirst(true) - newDefault.setCheckmodified(true) - resolvers.foreach(r => newDefault.add(ConvertResolver(r))) + val otherChain = resolverChain("sbt-other", other) + settings.addResolver(otherChain) + val newDefault = resolverChain("sbt-chain", resolvers) settings.addResolver(newDefault) settings.setDefaultResolver(newDefault.getName) log.debug("Using repositories:\n" + resolvers.mkString("\n\t")) + log.debug("Using other repositories:\n" + other.mkString("\n\t")) + } + private def resolverChain(name: String, resolvers: Seq[Resolver]): ChainResolver = + { + val newDefault = new ChainResolver + newDefault.setName(name) + newDefault.setReturnFirst(true) + newDefault.setCheckmodified(true) + resolvers.foreach(r => newDefault.add(ConvertResolver(r))) + newDefault } private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration]) { diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 98d50da9b..b7c18c0ba 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -86,7 +86,7 @@ object IvyCache { val local = Resolver.defaultLocal(None) val paths = new IvyPaths(new File("."), None) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, lock, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, lock, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index a052b9fc2..385eb260d 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -18,12 +18,12 @@ sealed trait IvyConfiguration extends NotNull def log: IvyLogger def withBase(newBaseDirectory: File): This } -final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], +final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, moduleConfigurations, lock, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, lock, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { @@ -42,7 +42,7 @@ object IvyConfiguration if(defaultIvyConfigFile.canRead) new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, lock, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, lock, log) } } From 96d60111c16d549d0183d14706552cf85158872e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 7 Mar 2010 19:07:52 -0500 Subject: [PATCH 0032/1030] Use correct xsbt.version.properties in ComponentManager --- ivy/ComponentManager.scala | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 0a67730d0..79b83fc32 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -80,9 +80,21 @@ object ComponentManager lazy val (version, timestamp) = { val properties = new java.util.Properties - val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") + val propertiesStream = versionResource.openStream try { properties.load(propertiesStream) } finally { propertiesStream.close() } (properties.getProperty("version"), properties.getProperty("timestamp")) } lazy val stampedVersion = version + "_" + timestamp + + import java.net.URL + private def versionResource: URL = + { + import java.util.Collections.list + // could be just: + // getClass.getResource("/xsbt.version.properties") + // but the launcher up until 0.7.1 contained a stale xsbt.version.properties. + // post-0.7.1, only xsbti.jar contains xsbt.version.properties + // for the transition, we take the last one, which is the one we want because of the order resources are searched + list(getClass.getClassLoader.getResources("xsbt.version.properties")).toArray(new Array[URL](0)).last + } } \ No newline at end of file From 1f17a80bbf9df7928dd9f743c64b315c81063bc0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 28 Mar 2010 14:19:43 -0400 Subject: [PATCH 0033/1030] Fix issue with scala-library.jar being retrieved --- ivy/IvyConfigurations.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 385eb260d..7f8ed9f3a 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -65,7 +65,7 @@ final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable val validate: Boolean) extends ModuleSettings { def withConfigurations(configurations: Iterable[Configuration]) = - new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) + new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, ivyScala, validate) def noScala = new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) } final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings From f6e8adfff59febd84e5db73212764640f13404fb Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 30 Mar 2010 09:19:36 -0400 Subject: [PATCH 0034/1030] detect packaging for make-pom --- ivy/Ivy.scala | 6 ++++++ ivy/IvyActions.scala | 33 +++------------------------------ ivy/MakePom.scala | 42 ++++++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 76f88b1d2..58d495237 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -343,4 +343,10 @@ private object IvySbt case dmd: DefaultModuleDescriptor => dmd case _ => error("Unknown ModuleDescriptor type.") } + def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = + configurations match + { + case Some(confs) => confs.map(_.name).toList.toArray + case None => module.getPublicConfigurationsNames + } } diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index f034e7cfa..c937f252f 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -49,8 +49,7 @@ object IvyActions { module.withModule { (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) - val pomModule = keepConfigurations(md, configurations) - (new MakePom).write(ivy, pomModule, extra, output) + (new MakePom).write(ivy, md, configurations, extra, output) module.logger.info("Wrote " + output.getAbsolutePath) } } @@ -61,32 +60,6 @@ object IvyActions parser.setMd(module) IvySbt.addDependencies(module, extraDependencies, parser) } - private def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = - configurations match - { - case Some(confs) => confs.map(_.name).toList.toArray - case None => module.getPublicConfigurationsNames - } - /** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. - * This currently only preserves the information required by makePom*/ - private def keepConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): ModuleDescriptor = - { - val keepConfigurations = getConfigurations(module, configurations) - val keepSet = Set(keepConfigurations.toSeq : _*) - def translate(dependency: DependencyDescriptor) = - { - val keep = dependency.getModuleConfigurations.filter(keepSet.contains) - if(keep.isEmpty) - None - else // TODO: translate the dependency to contain only configurations to keep - Some(dependency) - } - val newModule = new DefaultModuleDescriptor(module.getModuleRevisionId, "", null) - newModule.setHomePage(module.getHomePage) - for(dependency <- module.getDependencies; translated <- translate(dependency)) - newModule.addDependency(translated) - newModule - } def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], quiet: Boolean) { @@ -95,7 +68,7 @@ object IvyActions resolve(quiet)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(getConfigurations(md, configurations)) + options.setConfs(IvySbt.getConfigurations(md, configurations)) ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) } } @@ -108,7 +81,7 @@ object IvyActions srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) val options = (new PublishOptions).setOverwrite(true) deliveredIvyPattern.foreach(options.setSrcIvyPattern) - options.setConfs(getConfigurations(md, configurations)) + options.setConfs(IvySbt.getConfigurations(md, configurations)) ivy.publish(revID, patterns, resolverName, options) } } diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index c59347160..0670ae853 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -20,7 +20,8 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom { def encoding = "UTF-8" - def write(ivy: Ivy, module: ModuleDescriptor, extra: NodeSeq, output: File): Unit = write(toPom(ivy, module, extra), output) + def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File): Unit = + write(toPom(ivy, module, configurations, extra), output) def write(node: Node, output: File): Unit = write(toString(node), output) def write(xmlString: String, output: File) { @@ -36,12 +37,12 @@ class MakePom } def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, extra: NodeSeq): Node = + def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq): Node = ( 4.0.0 { makeModuleID(module) } { extra } - { makeDependencies(module) } + { makeDependencies(module, configurations) } { makeRepositories(ivy.getSettings) } ) @@ -51,7 +52,7 @@ class MakePom val a: NodeSeq = ({ mrid.getOrganisation } { mrid.getName } - { packaging(mrid) }) + { packaging(module) }) val b: NodeSeq = ( (description(module.getDescription) ++ homePage(module.getHomePage) ++ @@ -70,11 +71,19 @@ class MakePom def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else {homePage} def revision(version: String) = if(version ne null) {version} else NodeSeq.Empty - def packaging(module: ModuleRevisionId) = "jar"//module.getDefaultArtifact.getExt + def packaging(module: ModuleDescriptor) = + module.getAllArtifacts match + { + case Array() => "pom" + case Array(x) => x.getType + case xs => + val notpom = xs.filter(_.getType != "pom") + if(notpom.isEmpty) "pom" else notpom(0).getType + } - def makeDependencies(module: ModuleDescriptor): NodeSeq = + def makeDependencies(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): NodeSeq = { - val dependencies = module.getDependencies + val dependencies = depsInConfs(module, configurations) if(dependencies.isEmpty) NodeSeq.Empty else @@ -147,4 +156,21 @@ class MakePom {name} {root} -} + + /** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. + * This currently only preserves the information required by makePom*/ + private def depsInConfs(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): Seq[DependencyDescriptor] = + { + val keepConfigurations = IvySbt.getConfigurations(module, configurations) + val keepSet = Set(keepConfigurations.toSeq : _*) + def translate(dependency: DependencyDescriptor) = + { + val keep = dependency.getModuleConfigurations.filter(keepSet.contains) + if(keep.isEmpty) + None + else // TODO: translate the dependency to contain only configurations to keep + Some(dependency) + } + module.getDependencies flatMap translate + } +} \ No newline at end of file From 291e2dc17eee9eefd34485446402166b37d49be1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 1 Apr 2010 20:14:05 -0400 Subject: [PATCH 0035/1030] Provide empty for inline Ivy XML if a publications tag does not exist. This prevents a default artifact from being added incorrectly. --- ivy/Ivy.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 58d495237..7065e5603 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -20,6 +20,8 @@ import plugins.parser.m2.PomModuleDescriptorParser import plugins.resolver.ChainResolver import util.Message +import scala.xml.NodeSeq + final class IvySbt(configuration: IvyConfiguration) { import configuration.{log, baseDirectory} @@ -220,8 +222,6 @@ private object IvySbt import configuration._ new IvyConfig(name, if(isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) } - private def addDefaultArtifact(defaultConf: String, moduleID: DefaultModuleDescriptor) = - moduleID.addArtifact(defaultConf, new MDArtifact(moduleID, moduleID.getModuleRevisionId.getName, defaultType, defaultExtension)) /** Adds the ivy.xml main artifact. */ private def addMainArtifact(moduleID: DefaultModuleDescriptor) { @@ -266,16 +266,20 @@ private object IvySbt } } /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ - private def wrapped(module: ModuleID, dependencies: scala.xml.NodeSeq) = + private def wrapped(module: ModuleID, dependencies: NodeSeq) = { import module._ { if(hasInfo(dependencies)) - scala.xml.NodeSeq.Empty + NodeSeq.Empty else } {dependencies} + { + // this is because Ivy adds a default artifact if none are specified. + if(dependencies \\ "publications" isEmpty) else NodeSeq.Empty + } } private def hasInfo(x: scala.xml.NodeSeq) = !({x} \ "info").isEmpty From 7340febe057b77d6a4a0abe99fe3c3f4c432e55e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 23 Apr 2010 18:50:47 -0400 Subject: [PATCH 0036/1030] add checks to Artifact.extra --- ivy/IvyInterface.scala | 2 +- ivy/IvyScala.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index ef4fc9569..55ac855bc 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -323,7 +323,7 @@ final case class Configuration(name: String, description: String, isPublic: Bool final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) extends NotNull { - def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ attributes) + def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) } object Artifact { diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 38ea1bd84..b7d089a60 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -47,7 +47,7 @@ private object IvyScala private def configurationSet(configurations: Iterable[Configuration]) = HashSet(configurations.map(_.toString).toSeq : _*) /** Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is * done because normally these jars are already on the classpath and cannot/should not be overridden. The version - * of Scala to use is done by setting scala.version in the project definition. */ + * of Scala to use is done by setting build.scala.versions in the project definition. */ private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) { val configurationNames = From 262ffbf2b5595b09b8bfbe0d6b5c1a08a2759f55 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 23 Apr 2010 21:20:07 -0400 Subject: [PATCH 0037/1030] * Added pomRepositoryFilter(repo: MavenRepository): Boolean that excludes local repositories by default * Added pomPostProcess(pom: Node): Node to make advanced manipulation of the default pom easier (pomExtra covers basic cases) --- ivy/IvyActions.scala | 16 +++++++++++++--- ivy/IvyConfigurations.scala | 2 +- ivy/MakePom.scala | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index c937f252f..e478df5eb 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -4,7 +4,7 @@ package sbt import java.io.File -import scala.xml.NodeSeq +import scala.xml.{Node,NodeSeq} import org.apache.ivy.{core, plugins, util, Ivy} import core.cache.DefaultRepositoryCacheManager @@ -20,6 +20,13 @@ import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val quiet: Boolean) extends NotNull +final class MakePomConfiguration(val extraDependencies: Iterable[ModuleID], val configurations: Option[Iterable[Configuration]], + val extra: NodeSeq, val process: Node => Node, val filterRepositories: MavenRepository => Boolean) extends NotNull +object MakePomConfiguration +{ + def apply(extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq) = + new MakePomConfiguration(extraDependencies, configurations, extra, identity, _ => true) +} object IvyActions { @@ -45,11 +52,14 @@ object IvyActions } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File) + @deprecated def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File): Unit = + makePom(module, MakePomConfiguration(extraDependencies, configurations, extra), output) + def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, output: File) { + import configuration.{configurations, extra, extraDependencies, filterRepositories, process} module.withModule { (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) - (new MakePom).write(ivy, md, configurations, extra, output) + (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, output) module.logger.info("Wrote " + output.getAbsolutePath) } } diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 7f8ed9f3a..7b57364cd 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -4,7 +4,7 @@ package sbt import java.io.File -import scala.xml.NodeSeq +import scala.xml.{Node, NodeSeq} final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull { diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 0670ae853..d6a392fc8 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -20,8 +20,8 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom { def encoding = "UTF-8" - def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File): Unit = - write(toPom(ivy, module, configurations, extra), output) + def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: Node => Node, filterRepositories: MavenRepository => Boolean, output: File): Unit = + write(process(toPom(ivy, module, configurations, extra, filterRepositories)), output) def write(node: Node, output: File): Unit = write(toString(node), output) def write(xmlString: String, output: File) { @@ -37,13 +37,13 @@ class MakePom } def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq): Node = + def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean): Node = ( 4.0.0 { makeModuleID(module) } { extra } { makeDependencies(module, configurations) } - { makeRepositories(ivy.getSettings) } + { makeRepositories(ivy.getSettings, filterRepositories) } ) def makeModuleID(module: ModuleDescriptor): NodeSeq = @@ -125,16 +125,17 @@ class MakePom def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) - def makeRepositories(settings: IvySettings) = + def makeRepositories(settings: IvySettings, filterRepositories: MavenRepository => Boolean) = { class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) val repositories = resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { - case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => m :: Nil + case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => + MavenRepository(m.getName, m.getRoot) :: Nil case _ => Nil } - val repositoryElements = mavenRepositories.map { repo => mavenRepository(repo.getName, repo.getRoot) } + val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) if(repositoryElements.isEmpty) repositoryElements else {repositoryElements} } def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if(rs eq null) Nil else rs.flatMap(resolvers) @@ -148,8 +149,8 @@ class MakePom def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id - def mavenRepository(name: String, root: String): Node = - mavenRepository(toID(name), name, root) + def mavenRepository(repo: MavenRepository): Node = + mavenRepository(toID(repo.name), repo.name, repo.root) def mavenRepository(id: String, name: String, root: String): Node = {id} From e3c7cb2ff94e1e7e05035a99f108716729f90332 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 27 Apr 2010 17:58:05 -0400 Subject: [PATCH 0038/1030] * synchronize types for doc/src artifacts with the wiki documentation * Artifact.{sources, javadoc} methods for defining additional artifacts --- ivy/IvyInterface.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 55ac855bc..68e878eb2 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -20,12 +20,12 @@ final case class ModuleID(organization: String, name: String, revision: String, def classifier(c: String) = artifacts(Artifact(name, c)) def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes) def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ ModuleID.checkE(attributes)) - def sources() = artifacts(Artifact(name, "sources", "jar", "sources")) - def javadoc() = artifacts(Artifact(name, "javadoc", "jar", "javadoc")) + def sources() = artifacts(Artifact.sources(name)) + def javadoc() = artifacts(Artifact.javadoc(name)) def withSources() = jarIfEmpty.sources() def withJavadoc() = jarIfEmpty.javadoc() private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this - def jar() = artifacts(Artifact(name, "jar", "jar")) + def jar() = artifacts(Artifact(name)) } object ModuleID { @@ -337,6 +337,8 @@ object Artifact Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) val defaultExtension = "jar" val defaultType = "jar" + def sources(name: String) = Artifact(name, "src", "jar", "sources") + def javadoc(name: String) = Artifact(name, "doc", "jar", "javadoc") def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = { From a2d8bd1bee0ac14c5e42649223bc2cb985a06ad2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 28 Apr 2010 20:45:35 -0400 Subject: [PATCH 0039/1030] support ssh/sftp with keyfiles (needed to add user name parameter to 'as') --- ivy/ConvertResolver.scala | 7 ++++--- ivy/IvyInterface.scala | 12 ++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 085689dca..7901eb744 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -85,10 +85,11 @@ private object ConvertResolver { case RepositoryHelpers.PasswordAuthentication(user, password) => setUser(user) - setUserPassword(password) - case RepositoryHelpers.KeyFileAuthentication(file, password) => + password.foreach(setUserPassword) + case RepositoryHelpers.KeyFileAuthentication(user, file, password) => setKeyFile(file) - setKeyFilePassword(password) + password.foreach(setKeyFilePassword) + setUser(user) } } private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 68e878eb2..531597e19 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -76,8 +76,8 @@ object RepositoryHelpers def nonlocal() = FileConfiguration(false, isTransactional) } sealed trait SshAuthentication extends NotNull - final case class PasswordAuthentication(user: String, password: String) extends SshAuthentication - final case class KeyFileAuthentication(keyfile: File, password: String) extends SshAuthentication + final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication + final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication } import RepositoryHelpers.{SshConnection, FileConfiguration} import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} @@ -124,9 +124,13 @@ sealed abstract class SshBasedRepository extends PatternsBasedRepository def connection: SshConnection /** Configures this to use the specified user name and password when connecting to the remote repository. */ - def as(user: String, password: String): RepositoryType = copy(new PasswordAuthentication(user, password)) + def as(user: String, password: String): RepositoryType = as(user, Some(password)) + def as(user: String): RepositoryType = as(user, None) + def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ - def as(keyfile: File, password: String): RepositoryType = copy(new KeyFileAuthentication(keyfile, password)) + def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) + def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) + def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) } /** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository From 3d7051ad079d8f461f679db20dd15657760f21f7 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 2 May 2010 19:15:01 -0400 Subject: [PATCH 0040/1030] * can now set 'offline' property to 'true' to not refresh dynamic revisions (not needed if no -SNAPSHOT versions used) * more control over Ivy logging: override ivyUpdateLogging = UpdateLogging.Full,DownloadOnly (default), or Quiet --- ivy/Ivy.scala | 42 +++++++++++++++++++++++-------------- ivy/IvyActions.scala | 31 ++++++++++++++++++++------- ivy/IvyCache.scala | 2 +- ivy/IvyConfigurations.scala | 10 +++++---- 4 files changed, 57 insertions(+), 28 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 7065e5603..b2d59c60d 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -59,8 +59,8 @@ final class IvySbt(configuration: IvyConfiguration) { case e: ExternalIvyConfiguration => is.load(e.file) case i: InlineIvyConfiguration => - IvySbt.configureCache(is, i.paths.cacheDirectory) - IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, log) + IvySbt.configureCache(is, i.paths.cacheDirectory, i.localOnly) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations) } is @@ -171,23 +171,28 @@ private object IvySbt /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], log: IvyLogger) + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: IvyLogger) { - val otherChain = resolverChain("sbt-other", other) - settings.addResolver(otherChain) - val newDefault = resolverChain("sbt-chain", resolvers) - settings.addResolver(newDefault) - settings.setDefaultResolver(newDefault.getName) - log.debug("Using repositories:\n" + resolvers.mkString("\n\t")) - log.debug("Using other repositories:\n" + other.mkString("\n\t")) + def makeChain(label: String, name: String, rs: Seq[Resolver]) = { + log.debug(label + " repositories:") + val chain = resolverChain(name, rs, localOnly, log) + settings.addResolver(chain) + chain + } + val otherChain = makeChain("Other", "sbt-other", other) + val mainChain = makeChain("Default", "sbt-chain", resolvers) + settings.setDefaultResolver(mainChain.getName) } - private def resolverChain(name: String, resolvers: Seq[Resolver]): ChainResolver = + private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, log: IvyLogger): ChainResolver = { val newDefault = new ChainResolver newDefault.setName(name) newDefault.setReturnFirst(true) - newDefault.setCheckmodified(true) - resolvers.foreach(r => newDefault.add(ConvertResolver(r))) + newDefault.setCheckmodified(!localOnly) + for(sbtResolver <- resolvers) { + log.debug("\t" + sbtResolver) + newDefault.add(ConvertResolver(sbtResolver)) + } newDefault } private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration]) @@ -204,13 +209,18 @@ private object IvySbt settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private def configureCache(settings: IvySettings, dir: Option[File]) + private def configureCache(settings: IvySettings, dir: Option[File], localOnly: Boolean) { val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) manager.setUseOrigin(true) - manager.setChangingMatcher(PatternMatcher.REGEXP); - manager.setChangingPattern(".*-SNAPSHOT"); + if(localOnly) + manager.setDefaultTTL(java.lang.Long.MAX_VALUE); + else + { + manager.setChangingMatcher(PatternMatcher.REGEXP); + manager.setChangingPattern(".*-SNAPSHOT"); + } settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) dir.foreach(dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath)) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index e478df5eb..d80b12e13 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -19,7 +19,7 @@ import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} -final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val quiet: Boolean) extends NotNull +final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val logging: UpdateLogging.Value) extends NotNull final class MakePomConfiguration(val extraDependencies: Iterable[ModuleID], val configurations: Option[Iterable[Configuration]], val extra: NodeSeq, val process: Node => Node, val filterRepositories: MavenRepository => Boolean) extends NotNull object MakePomConfiguration @@ -27,6 +27,14 @@ object MakePomConfiguration def apply(extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq) = new MakePomConfiguration(extraDependencies, configurations, extra, identity, _ => true) } +/** Configures logging during an 'update'. `level` determines the amount of other information logged. +* `Full` is the default and logs the most. +* `DownloadOnly` only logs what is downloaded. +* `Quiet` only displays errors.*/ +object UpdateLogging extends Enumeration +{ + val Full, DownloadOnly, Quiet = Value +} object IvyActions { @@ -71,11 +79,11 @@ object IvyActions IvySbt.addDependencies(module, extraDependencies, parser) } - def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], quiet: Boolean) + def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], logging: UpdateLogging.Value) { module.withModule { case (ivy, md, default) => addLateDependencies(ivy, md, default, extraDependencies) - resolve(quiet)(ivy, md, default) // todo: set download = false for resolve + resolve(logging)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) options.setConfs(IvySbt.getConfigurations(md, configurations)) @@ -101,7 +109,7 @@ object IvyActions { module.withModule { case (ivy, md, default) => import configuration._ - resolve(quiet)(ivy, md, default) + resolve(logging)(ivy, md, default) val retrieveOptions = new RetrieveOptions retrieveOptions.setSync(synchronize) val patternBase = retrieveDirectory.getAbsolutePath @@ -113,14 +121,23 @@ object IvyActions ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) } } - private def resolve(quiet: Boolean)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) = + private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) = { val resolveOptions = new ResolveOptions - if(quiet) - resolveOptions.setLog(LogOptions.LOG_DOWNLOAD_ONLY) + resolveOptions.setLog(ivyLogLevel(logging)) val resolveReport = ivy.resolve(module, resolveOptions) if(resolveReport.hasError) throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).toList.removeDuplicates) } + + import UpdateLogging.{Quiet, Full, DownloadOnly} + import LogOptions.{LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY} + private def ivyLogLevel(level: UpdateLogging.Value) = + level match + { + case Quiet => LOG_QUIET + case DownloadOnly => LOG_DOWNLOAD_ONLY + case Full => LOG_DEFAULT + } } final class ResolveException(messages: List[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index b7c18c0ba..43b714231 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -86,7 +86,7 @@ object IvyCache { val local = Resolver.defaultLocal(None) val paths = new IvyPaths(new File("."), None) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, lock, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 7b57364cd..c047f1dda 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -19,11 +19,13 @@ sealed trait IvyConfiguration extends NotNull def withBase(newBaseDirectory: File): This } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration + val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], + val log: IvyLogger) extends IvyConfiguration { type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, lock, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration { @@ -35,14 +37,14 @@ object IvyConfiguration { /** Called to configure Ivy when inline resolvers are not specified. * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], log: IvyLogger): IvyConfiguration = + def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, log: IvyLogger): IvyConfiguration = { log.debug("Autodetecting configuration.") val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) if(defaultIvyConfigFile.canRead) new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, lock, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, log) } } From f56c0ac37f9ee66999c7014164508895a7b8dcda Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 15 Jun 2010 20:38:18 -0400 Subject: [PATCH 0041/1030] more 2.8 updates, launcher compiles and runs with 2.8 --- ivy/ComponentManager.scala | 2 +- ivy/CustomXmlParser.scala | 4 ++-- ivy/Ivy.scala | 10 ++-------- ivy/IvyActions.scala | 6 ++---- 4 files changed, 7 insertions(+), 15 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 79b83fc32..6e6e3d95e 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -25,7 +25,7 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr try { update(id); getOrElse(createAndCache) } catch { case e: NotInCache => createAndCache } } - def getOrElse(orElse: => Iterable[File]) = + def getOrElse(orElse: => Iterable[File]): Iterable[File] = { val existing = provider.component(id) if(existing.isEmpty) orElse else existing diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index a8b7d9b43..f773b1ce9 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -14,10 +14,10 @@ import plugins.repository.Resource import plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ -private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser with NotNull +private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { import XmlModuleDescriptorParser.Parser - class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) with NotNull + class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) { if(defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index b2d59c60d..e0d880a94 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -257,13 +257,7 @@ private object IvySbt javaMap(ea.extraAttributes) } private def javaMap(map: Map[String,String]) = - if(map.isEmpty) null - else - { - val wrap = scala.collection.jcl.Map(new java.util.HashMap[String,String]) - wrap ++= map - wrap.underlying - } + if(map.isEmpty) null else scala.collection.JavaConversions.asMap(map) private object javaMap { @@ -337,7 +331,7 @@ private object IvySbt lazy val allConfigurations = moduleID.getPublicConfigurationsNames for(artifact <- artifacts) { - val configurationStrings = + val configurationStrings: Iterable[String] = { val artifactConfigurations = artifact.configurations if(artifactConfigurations.isEmpty) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index d80b12e13..b566258a5 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -60,8 +60,6 @@ object IvyActions } /** Creates a Maven pom from the given Ivy configuration*/ - @deprecated def makePom(module: IvySbt#Module, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq, output: File): Unit = - makePom(module, MakePomConfiguration(extraDependencies, configurations, extra), output) def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, output: File) { import configuration.{configurations, extra, extraDependencies, filterRepositories, process} @@ -127,7 +125,7 @@ object IvyActions resolveOptions.setLog(ivyLogLevel(logging)) val resolveReport = ivy.resolve(module, resolveOptions) if(resolveReport.hasError) - throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).toList.removeDuplicates) + throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct) } import UpdateLogging.{Quiet, Full, DownloadOnly} @@ -140,4 +138,4 @@ object IvyActions case Full => LOG_DEFAULT } } -final class ResolveException(messages: List[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file +final class ResolveException(messages: Seq[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file From 68da4c8ae570974f949aa3724d6e8416af0fa898 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 5 Jul 2010 12:53:37 -0400 Subject: [PATCH 0042/1030] - Stuart's improvements to triggered execution - continue splitting original sbt module * separated process, testing modules * various IO, logging, classpath migration * split out javac interface --- ivy/src/test/scala/ComponentManagerTest.scala | 6 ++---- ivy/src/test/scala/TestIvyLogger.scala | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index ec29ae476..8ad4c0999 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -1,10 +1,8 @@ package sbt -import xsbt.{BufferedLogger, FileUtilities} - import java.io.File import org.specs._ -import FileUtilities.{createDirectory, delete, touch, withTemporaryDirectory} +import IO.{createDirectory, delete, touch, withTemporaryDirectory} import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail @@ -76,7 +74,7 @@ object ComponentManagerTest extends Specification manager.define(id, files) f(files) } - private def writeRandomContent(file: File) = FileUtilities.write(file, randomString) + private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) diff --git a/ivy/src/test/scala/TestIvyLogger.scala b/ivy/src/test/scala/TestIvyLogger.scala index bf4386d7f..c173b43fd 100644 --- a/ivy/src/test/scala/TestIvyLogger.scala +++ b/ivy/src/test/scala/TestIvyLogger.scala @@ -1,8 +1,6 @@ package sbt -import xsbt.{BufferedLogger, ConsoleLogger, Level} - -class TestIvyLogger extends BufferedLogger(new ConsoleLogger) with IvyLogger { def verbose(msg: => String) = info(msg) } +class TestIvyLogger extends BufferedLogger(new ConsoleLogger) with IvyLogger object TestIvyLogger { def apply[T](f: IvyLogger => T): T = From d4965daf2aa82d9fc939dfac3eb12e06fad7b453 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 14 Jul 2010 19:24:50 -0400 Subject: [PATCH 0043/1030] * move Environment classes to util/env module * move TrapExit, SelectMainClass to run module * rearrange some compilation-related code * Jetty-related code moved to web module --- ivy/IvyInterface.scala | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 531597e19..cbbede0ca 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -365,41 +365,4 @@ object ModuleConfiguration { def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) -} -/* -object Credentials -{ - /** Add the provided credentials to Ivy's credentials cache.*/ - def add(realm: String, host: String, userName: String, passwd: String): Unit = - CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) - /** Load credentials from the given file into Ivy's credentials cache.*/ - def apply(file: String, log: Logger): Unit = apply(Path.fromFile(file), log) - /** Load credentials from the given file into Ivy's credentials cache.*/ - def apply(file: File, log: Logger): Unit = apply(Path.fromFile(file), log) - /** Load credentials from the given file into Ivy's credentials cache.*/ - def apply(path: Path, log: Logger) - { - val msg = - if(path.exists) - { - val properties = new scala.collection.mutable.HashMap[String, String] - def get(keys: List[String]) = keys.flatMap(properties.get).firstOption.toRight(keys.head + " not specified in credentials file: " + path) - - impl.MapUtilities.read(properties, path, log) orElse - { - List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match - { - case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass); None - case (errors, _) => Some(errors.mkString("\n")) - } - } - } - else - Some("Credentials file " + path + " does not exist") - msg.foreach(x => log.warn(x)) - } - private[this] val RealmKeys = List("realm") - private[this] val HostKeys = List("host", "hostname") - private[this] val UserKeys = List("user", "user.name", "username") - private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") -}*/ \ No newline at end of file +} \ No newline at end of file From 3d0d640a9cfd56390c43fbd30b6b3293e19769f6 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 4 Sep 2010 08:19:58 -0400 Subject: [PATCH 0044/1030] rework ConsoleLogger can send output to a PrintWriter control over color, still need custom formatter replace IvyLogger with normal Logger --- ivy/ComponentManager.scala | 2 +- ivy/Ivy.scala | 4 ++-- ivy/IvyCache.scala | 12 ++++++------ ivy/IvyConfigurations.scala | 10 +++++----- ivy/IvyLogger.scala | 11 +---------- 5 files changed, 15 insertions(+), 24 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 6e6e3d95e..bb1047b3d 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -15,7 +15,7 @@ import java.util.concurrent.Callable * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, val log: IvyLogger) extends NotNull +class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, val log: Logger) extends NotNull { /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String)(ifMissing: IfMissing): Iterable[File] = diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index e0d880a94..1b6866d84 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -171,7 +171,7 @@ private object IvySbt /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: IvyLogger) + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: Logger) { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") @@ -183,7 +183,7 @@ private object IvySbt val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } - private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, log: IvyLogger): ChainResolver = + private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, log: Logger): ChainResolver = { val newDefault = new ChainResolver newDefault.setName(name) diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 43b714231..072be22a0 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -32,7 +32,7 @@ object IvyCache { def lockFile = new File(System.getProperty("user.home"), ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ - def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: IvyLogger) + def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger) { val artifact = defaultArtifact(moduleID) val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) @@ -42,13 +42,13 @@ object IvyCache } } /** Clears the cache of the jar for the given ID.*/ - def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: IvyLogger) + def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger) { try { withCachedJar(id, lock, log)(_.delete) } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ - def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: IvyLogger) = + def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: Logger) = withCachedJar(id, lock, log) { cachedFile => val copyTo = new File(toDirectory, cachedFile.getName) FileUtil.copy(cachedFile, copyTo, null) @@ -56,7 +56,7 @@ object IvyCache } /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ - def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: IvyLogger)(f: File => T): T = + def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)(f: File => T): T = { val cachedFile = try @@ -71,7 +71,7 @@ object IvyCache if(cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } /** Calls the given function with the default Ivy cache.*/ - def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: IvyLogger)(f: DefaultRepositoryCacheManager => T): T = + def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = { val (ivy, local) = basicLocalIvy(lock, log) ivy.withIvy { ivy => @@ -82,7 +82,7 @@ object IvyCache } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ - private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: IvyLogger) = + private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal(None) val paths = new IvyPaths(new File("."), None) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index c047f1dda..7a7531b13 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -15,19 +15,19 @@ sealed trait IvyConfiguration extends NotNull type This <: IvyConfiguration def lock: Option[xsbti.GlobalLock] def baseDirectory: File - def log: IvyLogger + def log: Logger def withBase(newBaseDirectory: File): This } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val log: IvyLogger) extends IvyConfiguration + val log: Logger) extends IvyConfiguration { type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) } -final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: IvyLogger) extends IvyConfiguration +final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: Logger) extends IvyConfiguration { type This = ExternalIvyConfiguration def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, file, lock, log) @@ -37,7 +37,7 @@ object IvyConfiguration { /** Called to configure Ivy when inline resolvers are not specified. * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, log: IvyLogger): IvyConfiguration = + def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, log: Logger): IvyConfiguration = { log.debug("Autodetecting configuration.") val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) @@ -93,7 +93,7 @@ object InlineConfiguration } object ModuleSettings { - def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: IvyLogger) = + def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: Logger) = { log.debug("Autodetecting dependencies.") val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index 51f9afbb9..b06d477a2 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -5,17 +5,8 @@ package sbt import org.apache.ivy.util.{Message, MessageLogger, MessageLoggerEngine} -trait IvyLogger extends NotNull -{ - def info(msg: => String) - def debug(msg: => String) - def warn(msg: => String) - def error(msg: => String) - def verbose(msg: => String) -} - /** Interface to Ivy logging. */ -private final class IvyLoggerInterface(logger: IvyLogger) extends MessageLogger +private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def rawlog(msg: String, level: Int) = log(msg, level) def log(msg: String, level: Int) From 8097558fb284a83c604dbf671427d16f1da4702a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 4 Sep 2010 08:42:37 -0400 Subject: [PATCH 0045/1030] first part of fixing #44 --- ivy/IvyActions.scala | 20 +++++++++++++------ ivy/IvyRetrieve.scala | 46 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 ivy/IvyRetrieve.scala diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index b566258a5..9b90d007b 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import scala.xml.{Node,NodeSeq} -import org.apache.ivy.{core, plugins, util, Ivy} +import org.apache.ivy.{core, plugins, Ivy} import core.cache.DefaultRepositoryCacheManager import core.LogOptions import core.deliver.DeliverOptions @@ -15,6 +15,7 @@ import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescrip import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.publish.PublishOptions +import core.report.ResolveReport import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} @@ -103,12 +104,18 @@ object IvyActions } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - def update(module: IvySbt#Module, configuration: UpdateConfiguration) + def update(module: IvySbt#Module, configuration: UpdateConfiguration) = { module.withModule { case (ivy, md, default) => import configuration._ - resolve(logging)(ivy, md, default) - val retrieveOptions = new RetrieveOptions + val report = resolve(logging)(ivy, md, default) + import IvyRetrieve._ + /*if(synchronize) + IO delete retrieveDirectory + IO createDirectory retrieveDirectory + retrieve( cachePaths(report), , retrieveDirectory)*/ + cachePaths(report) + /*val retrieveOptions = new RetrieveOptions retrieveOptions.setSync(synchronize) val patternBase = retrieveDirectory.getAbsolutePath val pattern = @@ -116,16 +123,17 @@ object IvyActions patternBase + outputPattern else patternBase + File.separatorChar + outputPattern - ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) + ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions)*/ } } - private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String) = + private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): ResolveReport = { val resolveOptions = new ResolveOptions resolveOptions.setLog(ivyLogLevel(logging)) val resolveReport = ivy.resolve(module, resolveOptions) if(resolveReport.hasError) throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct) + resolveReport } import UpdateLogging.{Quiet, Full, DownloadOnly} diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala new file mode 100644 index 000000000..cfa384f7a --- /dev/null +++ b/ivy/IvyRetrieve.scala @@ -0,0 +1,46 @@ +/* sbt -- Simple Build Tool + * Copyright 2010 Mark Harrah + */ +package sbt + +import java.io.File + +import org.apache.ivy.core.{module, report} +import module.id.ModuleRevisionId +import report.{ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport} + +object IvyRetrieve +{ + def reports(report: ResolveReport): Map[String, ConfigurationResolveReport] = + ( for( conf <- report.getConfigurations) yield (conf, report.getConfigurationReport(conf)) ).toMap + + def artifactReports(confReport: ConfigurationResolveReport): Seq[ArtifactDownloadReport] = + { + val all = new scala.collection.mutable.HashSet[ArtifactDownloadReport] + for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) + all ++= confReport.getDownloadReports(revId) + all.toSeq + } + + def cachePath(reports: Seq[ArtifactDownloadReport]): Seq[File] = + reports map( _.getLocalFile ) + + def cachePaths(report: ResolveReport): Map[String, Seq[File]] = + reports(report).mapValues(confReport => cachePath(artifactReports(confReport))) + + def copy(files: Set[File], cacheBase: File, to: File): Map[File, File] = + { + import Path._ + val copyDef = files x rebase(cacheBase, to) + IO.copy( copyDef, overwrite = true, preserveLastModified = true ) + copyDef.toMap + } + + // TODO: not a sufficient way to do it: cacheBase is not necessarily common to all files + def retrieve(result: Map[String, Seq[File]], cacheBase: File, to: File): Map[String, Seq[File]] = + { + val all = result.values.flatten.toSet + val copyMap = copy(all, cacheBase, to) + result mapValues (_ map copyMap) + } +} \ No newline at end of file From 568887b9e869888e4224a97d05cbda0710a8c225 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Sep 2010 23:13:48 -0400 Subject: [PATCH 0046/1030] add RawRepository to wrap raw Ivy Resolvers --- ivy/ConvertResolver.scala | 1 + ivy/IvyInterface.scala | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 7901eb744..50e511e3d 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -60,6 +60,7 @@ private object ConvertResolver initializePatterns(resolver, repo.patterns) resolver } + case repo: RawRepository => repo.resolver } } private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index cbbede0ca..2e4038074 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import java.net.{URI, URL} import scala.xml.NodeSeq -import org.apache.ivy.plugins.resolver.IBiblioResolver +import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact], extraAttributes: Map[String,String]) extends NotNull @@ -45,6 +45,10 @@ sealed trait Resolver extends NotNull { def name: String } +final class RawRepository(val resolver: DependencyResolver) extends Resolver +{ + def name = resolver.getName +} sealed case class MavenRepository(name: String, root: String) extends Resolver { override def toString = name + ": " + root From 42d4323d2b3bef90d8e38e6c187b2eab26380e31 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Sep 2010 23:14:30 -0400 Subject: [PATCH 0047/1030] minor cleanup of some Ivy-related code --- ivy/Ivy.scala | 2 +- ivy/IvyScala.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 1b6866d84..d4b2c0a2f 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -92,7 +92,7 @@ final class IvySbt(configuration: IvyConfiguration) def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } - private lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = + lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = { val (baseModule, baseConfiguration) = moduleSettings match diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index b7d089a60..ce254f06a 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -21,7 +21,7 @@ object ScalaArtifacts import ScalaArtifacts._ -final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) extends NotNull +final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ From 2532cc57792ee861d2bc5bc30d53983f4004bab2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Sep 2010 23:14:55 -0400 Subject: [PATCH 0048/1030] only filter Scala artifacts of type 'jar' --- ivy/IvyScala.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index ce254f06a..edfe274a6 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -71,7 +71,7 @@ private object IvyScala * the given configurations. */ private def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "*", "*") + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "jar", "*") val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, Collections.emptyMap[AnyRef,AnyRef]) configurationNames.foreach(rule.addConfiguration) rule From bc77cb8070c376bfb4fa956282edeaa1def0e87f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Sep 2010 23:15:51 -0400 Subject: [PATCH 0049/1030] ProjectResolver for inter-project dependencies --- ivy/ProjectResolver.scala | 83 +++++++++++++++++++++++++++++++++++++++ ivy/ResolverAdapter.java | 12 ++++++ 2 files changed, 95 insertions(+) create mode 100644 ivy/ProjectResolver.scala create mode 100644 ivy/ResolverAdapter.java diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala new file mode 100644 index 000000000..1282808ee --- /dev/null +++ b/ivy/ProjectResolver.scala @@ -0,0 +1,83 @@ +package sbt + + import java.io.File + import java.util.Date + + import org.apache.ivy.{core,plugins} + import core.{cache,module, report, resolve,search} + import cache.{ArtifactOrigin,RepositoryCacheManager} + import search.{ModuleEntry, OrganisationEntry, RevisionEntry} + import module.id.ModuleRevisionId + import module.descriptor.{Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor} + import plugins.namespace.Namespace + import plugins.resolver.{DependencyResolver,ResolverSettings} + import report.{ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport} + import resolve.{DownloadOptions, ResolveData, ResolvedModuleRevision} + +/**A Resolver that uses a predefined mapping from module ids to in-memory descriptors. +* It does not handle artifacts.*/ +class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) extends ResolverAdapter +{ + def getName = name + def setName(name: String) = error("Setting name not supported by ProjectResolver") + + def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = + { + val revisionId = dd.getDependencyRevisionId + def constructResult(descriptor: ModuleDescriptor) = new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) + val dep = (map get revisionId map constructResult).orNull + dep + } + + def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = + { + val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) + val r = new MetadataArtifactDownloadReport(artifact) + r.setSearched(false) + r.setDownloadStatus(DownloadStatus.NO) + r + } + + def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null + + // this resolver nevers locates artifacts, only resolves dependencies + def exists(artifact: IArtifact) = false + def locate(artifact: IArtifact) = null + + def notDownloaded(artifact: IArtifact): ArtifactDownloadReport= + { + val r = new ArtifactDownloadReport(artifact) + r.setDownloadStatus(DownloadStatus.NO) + r + } + def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = + { + val r = new DownloadReport + for(artifact <- artifacts) + r addArtifactReport notDownloaded(artifact) + r + } + def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = + notDownloaded(artifact.getArtifact) + + // doesn't support publishing + def publish(artifact: IArtifact, src: File, overwrite: Boolean) = error("Publish not supported by ProjectResolver") + def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} + def abortPublishTransaction() {} + def commitPublishTransaction() {} + + def reportFailure() {} + def reportFailure(art: IArtifact) {} + + def listOrganisations() = new Array[OrganisationEntry](0) + def listModules(org: OrganisationEntry) = new Array[ModuleEntry](0) + def listRevisions(module: ModuleEntry) = new Array[RevisionEntry](0) + + def getNamespace = Namespace.SYSTEM_NAMESPACE + + private[this] var settings: Option[ResolverSettings] = None + + def dumpSettings() {} + def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } + def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => error("No settings defined for ProjectResolver") } +} diff --git a/ivy/ResolverAdapter.java b/ivy/ResolverAdapter.java new file mode 100644 index 000000000..40b1b6268 --- /dev/null +++ b/ivy/ResolverAdapter.java @@ -0,0 +1,12 @@ +package sbt; + + import java.util.Map; + import org.apache.ivy.plugins.resolver.DependencyResolver; + +// implements the methods with raw types +public abstract class ResolverAdapter implements DependencyResolver +{ + public String[] listTokenValues(String token, Map otherTokenValues) { return new String[0]; } + + public Map[] listTokenValues(String[] tokens, Map criteria) { return new Map[0]; } +} \ No newline at end of file From 71455032c8fc36b360c8b7b88ab1ef4c70401f15 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 13 Sep 2010 19:42:11 -0400 Subject: [PATCH 0050/1030] put ResolverAdapter.java in proper location --- ivy/{ => src/main/java}/ResolverAdapter.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename ivy/{ => src/main/java}/ResolverAdapter.java (100%) diff --git a/ivy/ResolverAdapter.java b/ivy/src/main/java/ResolverAdapter.java similarity index 100% rename from ivy/ResolverAdapter.java rename to ivy/src/main/java/ResolverAdapter.java From 988c526ef5a37a0009ed7fbc4aed156146971aca Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Sep 2010 22:04:12 -0400 Subject: [PATCH 0051/1030] fix ProjectResolver to properly signal that it can't retrieve artifacts --- ivy/ProjectResolver.scala | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala index 1282808ee..45f473120 100644 --- a/ivy/ProjectResolver.scala +++ b/ivy/ProjectResolver.scala @@ -34,22 +34,13 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) val r = new MetadataArtifactDownloadReport(artifact) r.setSearched(false) - r.setDownloadStatus(DownloadStatus.NO) + r.setDownloadStatus(DownloadStatus.FAILED) r } - def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null - // this resolver nevers locates artifacts, only resolves dependencies def exists(artifact: IArtifact) = false def locate(artifact: IArtifact) = null - - def notDownloaded(artifact: IArtifact): ArtifactDownloadReport= - { - val r = new ArtifactDownloadReport(artifact) - r.setDownloadStatus(DownloadStatus.NO) - r - } def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = { val r = new DownloadReport @@ -57,14 +48,22 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] r addArtifactReport notDownloaded(artifact) r } - def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = + def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = notDownloaded(artifact.getArtifact) + def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null + + def notDownloaded(artifact: IArtifact): ArtifactDownloadReport= + { + val r = new ArtifactDownloadReport(artifact) + r.setDownloadStatus(DownloadStatus.FAILED) + r + } // doesn't support publishing def publish(artifact: IArtifact, src: File, overwrite: Boolean) = error("Publish not supported by ProjectResolver") def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} - def abortPublishTransaction() {} - def commitPublishTransaction() {} + def abortPublishTransaction() {} + def commitPublishTransaction() {} def reportFailure() {} def reportFailure(art: IArtifact) {} @@ -73,7 +72,7 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def listModules(org: OrganisationEntry) = new Array[ModuleEntry](0) def listRevisions(module: ModuleEntry) = new Array[RevisionEntry](0) - def getNamespace = Namespace.SYSTEM_NAMESPACE + def getNamespace = Namespace.SYSTEM_NAMESPACE private[this] var settings: Option[ResolverSettings] = None From 28386190114ab05c3d5e817a56cbf7325c69e2c8 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Sep 2010 22:05:57 -0400 Subject: [PATCH 0052/1030] update to Scala 2.8.1.RC1, Ivy 2.2.0-rc1 use dependencies compiled against Scala 2.8.0 --- ivy/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index d4b2c0a2f..1e0b59bf1 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -257,7 +257,7 @@ private object IvySbt javaMap(ea.extraAttributes) } private def javaMap(map: Map[String,String]) = - if(map.isEmpty) null else scala.collection.JavaConversions.asMap(map) + if(map.isEmpty) null else scala.collection.JavaConversions.asJavaMap(map) private object javaMap { From d53f7703737740459ebb888b7b2420b60da9b060 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Sep 2010 22:10:21 -0400 Subject: [PATCH 0053/1030] add sbt package object for use from project definitions only- it is a top-level project add dependency and repository builders cross-versioning will be a post-construction transformation --- ivy/IvyInterface.scala | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 2e4038074..5bc230b5f 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,17 +9,18 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact], extraAttributes: Map[String,String]) extends NotNull +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) { override def toString = organization + ":" + name + ":" + revision // () required for chaining + def cross(v: Boolean) = copy(crossVersion = v) def notTransitive() = intransitive() - def intransitive() = ModuleID(organization, name, revision, configurations, isChanging, false, explicitArtifacts, extraAttributes) - def changing() = ModuleID(organization, name, revision, configurations, true, isTransitive, explicitArtifacts, extraAttributes) + def intransitive() = copy(isTransitive = false) + def changing() = copy(isChanging = true) def from(url: String) = artifacts(Artifact(name, new URL(url))) def classifier(c: String) = artifacts(Artifact(name, c)) - def artifacts(newArtifacts: Artifact*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, newArtifacts ++ explicitArtifacts, extraAttributes) - def extra(attributes: (String,String)*) = ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, extraAttributes ++ ModuleID.checkE(attributes)) + def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) def sources() = artifacts(Artifact.sources(name)) def javadoc() = artifacts(Artifact.javadoc(name)) def withSources() = jarIfEmpty.sources() @@ -29,14 +30,6 @@ final case class ModuleID(organization: String, name: String, revision: String, } object ModuleID { - def apply(organization: String, name: String, revision: String): ModuleID = ModuleID(organization, name, revision, None) - def apply(organization: String, name: String, revision: String, configurations: Option[String]): ModuleID = - ModuleID(organization, name, revision, configurations, false, true) - def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean): ModuleID = - ModuleID(organization, name, revision, configurations, isChanging, isTransitive, Nil) - def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, explicitArtifacts: Seq[Artifact]): ModuleID = - ModuleID(organization, name, revision, configurations, isChanging, isTransitive, explicitArtifacts, Map.empty) - def checkE(attributes: Seq[(String, String)]) = for ( (key, value) <- attributes) yield if(key.startsWith("e:")) (key, value) else ("e:" + key, value) From ccd465d0468264a27619412c0f5024ac2fbdc4b4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Sep 2010 22:26:04 -0400 Subject: [PATCH 0054/1030] check for non-existing local file after retrieve this is almost always an error condition, but we need to translate the null for a better error message --- ivy/IvyRetrieve.scala | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index cfa384f7a..7cfd7f026 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -23,24 +23,12 @@ object IvyRetrieve } def cachePath(reports: Seq[ArtifactDownloadReport]): Seq[File] = - reports map( _.getLocalFile ) + for(r <- reports) yield + { + val file = r.getLocalFile + if(file eq null) error("No file for " + r.getArtifact) else file + } def cachePaths(report: ResolveReport): Map[String, Seq[File]] = reports(report).mapValues(confReport => cachePath(artifactReports(confReport))) - - def copy(files: Set[File], cacheBase: File, to: File): Map[File, File] = - { - import Path._ - val copyDef = files x rebase(cacheBase, to) - IO.copy( copyDef, overwrite = true, preserveLastModified = true ) - copyDef.toMap - } - - // TODO: not a sufficient way to do it: cacheBase is not necessarily common to all files - def retrieve(result: Map[String, Seq[File]], cacheBase: File, to: File): Map[String, Seq[File]] = - { - val all = result.values.flatten.toSet - val copyMap = copy(all, cacheBase, to) - result mapValues (_ map copyMap) - } } \ No newline at end of file From c4fba6b8a585c384983bfa2a1f1a21e89bda6c8d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Sep 2010 22:38:18 -0400 Subject: [PATCH 0055/1030] fix update, default project supports triggered execution --- ivy/IvyActions.scala | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 9b90d007b..bcda71dc1 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -15,14 +15,15 @@ import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescrip import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.publish.PublishOptions -import core.report.ResolveReport +import core.report.{ArtifactDownloadReport,ResolveReport} import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} -final class UpdateConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean, val logging: UpdateLogging.Value) extends NotNull +final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean) final class MakePomConfiguration(val extraDependencies: Iterable[ModuleID], val configurations: Option[Iterable[Configuration]], - val extra: NodeSeq, val process: Node => Node, val filterRepositories: MavenRepository => Boolean) extends NotNull + val extra: NodeSeq, val process: Node => Node, val filterRepositories: MavenRepository => Boolean) object MakePomConfiguration { def apply(extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq) = @@ -107,15 +108,20 @@ object IvyActions def update(module: IvySbt#Module, configuration: UpdateConfiguration) = { module.withModule { case (ivy, md, default) => - import configuration._ + import configuration.{retrieve => rConf, logging} val report = resolve(logging)(ivy, md, default) - import IvyRetrieve._ - /*if(synchronize) - IO delete retrieveDirectory - IO createDirectory retrieveDirectory - retrieve( cachePaths(report), , retrieveDirectory)*/ - cachePaths(report) - /*val retrieveOptions = new RetrieveOptions + rConf match + { + case None => IvyRetrieve.cachePaths(report) + case Some(conf) => retrieve(ivy, md, conf, logging) + } + } + } + // doesn't work. perhaps replace retrieve/determineArtifactsToCopy with custom code + private def retrieve(ivy: Ivy, md: ModuleDescriptor, conf: RetrieveConfiguration, logging: UpdateLogging.Value) = + { + import conf._ + val retrieveOptions = new RetrieveOptions retrieveOptions.setSync(synchronize) val patternBase = retrieveDirectory.getAbsolutePath val pattern = @@ -123,8 +129,19 @@ object IvyActions patternBase + outputPattern else patternBase + File.separatorChar + outputPattern - ivy.retrieve(md.getModuleRevisionId, pattern, retrieveOptions)*/ - } + + val engine = ivy.getRetrieveEngine + engine.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) + + //TODO: eliminate the duplication for better efficiency (retrieve already calls determineArtifactsToCopy once) + val rawMap = engine.determineArtifactsToCopy(md.getModuleRevisionId, pattern, retrieveOptions) + val map = rawMap.asInstanceOf[java.util.Map[ArtifactDownloadReport,java.util.Set[String]]] + val confMap = new collection.mutable.HashMap[String, Seq[File]] + + import collection.JavaConversions.{asScalaMap,asScalaSet} + for( (report, all) <- map; retrieved <- all; val file = new File(retrieved); conf <- report.getArtifact.getConfigurations) + confMap.put(conf, file +: confMap.getOrElse(conf, Nil)) + confMap.toMap } private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): ResolveReport = { From 46f51b6e103b8144706afbd31e3557e1f2e112e0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 27 Sep 2010 19:06:52 -0400 Subject: [PATCH 0056/1030] disable check modified. need to verify it doesn't break -SNAPSHOT --- ivy/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 1e0b59bf1..f727bbf58 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -188,7 +188,7 @@ private object IvySbt val newDefault = new ChainResolver newDefault.setName(name) newDefault.setReturnFirst(true) - newDefault.setCheckmodified(!localOnly) + newDefault.setCheckmodified(false) for(sbtResolver <- resolvers) { log.debug("\t" + sbtResolver) newDefault.add(ConvertResolver(sbtResolver)) From c3f54347efcb3c7d2850f59231ebfa3827db8cea Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 6 Oct 2010 08:24:13 -0400 Subject: [PATCH 0057/1030] fix tests, discovery updated compile tests for new minimal AnalysisCallback moved discovery to discovery/ subproject and updated for new approach fixed discovery to only find public methods when searching for annotated definitions extracting inherited definitions unimplemented in api/, so some discovery tests fail moved discovery classes from sbt.inc package to sbt.compile --- ivy/src/test/scala/ComponentManagerTest.scala | 2 +- ivy/src/test/scala/TestIvyLogger.scala | 12 ------------ 2 files changed, 1 insertion(+), 13 deletions(-) delete mode 100644 ivy/src/test/scala/TestIvyLogger.scala diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 8ad4c0999..537361fcb 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestIvyLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) + TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) } \ No newline at end of file diff --git a/ivy/src/test/scala/TestIvyLogger.scala b/ivy/src/test/scala/TestIvyLogger.scala deleted file mode 100644 index c173b43fd..000000000 --- a/ivy/src/test/scala/TestIvyLogger.scala +++ /dev/null @@ -1,12 +0,0 @@ -package sbt - -class TestIvyLogger extends BufferedLogger(new ConsoleLogger) with IvyLogger -object TestIvyLogger -{ - def apply[T](f: IvyLogger => T): T = - { - val log = new TestIvyLogger - log.setLevel(Level.Debug) - log.bufferQuietly(f(log)) - } -} \ No newline at end of file From 9090cd621890cd1e92498c803621b2231491eccc Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 26 Oct 2010 17:59:24 -0400 Subject: [PATCH 0058/1030] drop some NotNulls from ivy/ plus some adjustments --- ivy/ConvertResolver.scala | 2 +- ivy/Ivy.scala | 5 +++-- ivy/IvyConfigurations.scala | 14 +++++++------- ivy/IvyInterface.scala | 13 +++++++------ 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 50e511e3d..cd4d1a2a0 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -21,7 +21,7 @@ private object ConvertResolver initializeMavenStyle(resolver, repo.name, repo.root) resolver } - case JavaNet1Repository => + case r: JavaNet1Repository => { // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index f727bbf58..49cdf2720 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -22,7 +22,7 @@ import util.Message import scala.xml.NodeSeq -final class IvySbt(configuration: IvyConfiguration) +final class IvySbt(val configuration: IvyConfiguration) { import configuration.{log, baseDirectory} /** ========== Configuration/Setup ============ @@ -86,8 +86,9 @@ final class IvySbt(configuration: IvyConfiguration) finally { ivy.popContext() } } - final class Module(val moduleSettings: ModuleSettings) extends NotNull + final class Module(val moduleSettings: ModuleSettings) { + def owner = IvySbt.this def logger = configuration.log def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 7a7531b13..6ba3d63a3 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -6,11 +6,11 @@ package sbt import java.io.File import scala.xml.{Node, NodeSeq} -final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) extends NotNull +final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) { def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, cacheDirectory) } -sealed trait IvyConfiguration extends NotNull +sealed trait IvyConfiguration { type This <: IvyConfiguration def lock: Option[xsbti.GlobalLock] @@ -48,7 +48,7 @@ object IvyConfiguration } } -sealed trait ModuleSettings extends NotNull +sealed trait ModuleSettings { def validate: Boolean def ivyScala: Option[IvyScala] @@ -62,11 +62,11 @@ final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val { def noScala = new PomConfiguration(file, None, validate) } -final class InlineConfiguration(val module: ModuleID, val dependencies: Iterable[ModuleID], val ivyXML: NodeSeq, - val configurations: Iterable[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], +final class InlineConfiguration(val module: ModuleID, val dependencies: Seq[ModuleID], val ivyXML: NodeSeq, + val configurations: Seq[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings { - def withConfigurations(configurations: Iterable[Configuration]) = + def withConfigurations(configurations: Seq[Configuration]) = new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, ivyScala, validate) def noScala = new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) } @@ -76,7 +76,7 @@ final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvySca } object InlineConfiguration { - def apply(module: ModuleID, dependencies: Iterable[ModuleID]) = + def apply(module: ModuleID, dependencies: Seq[ModuleID]) = new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 5bc230b5f..74f7fa876 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -34,7 +34,7 @@ object ModuleID for ( (key, value) <- attributes) yield if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } -sealed trait Resolver extends NotNull +sealed trait Resolver { def name: String } @@ -47,7 +47,7 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver override def toString = name + ": " + root } -final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) extends NotNull +final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) { private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) @@ -61,12 +61,12 @@ object Patterns } object RepositoryHelpers { - final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) extends NotNull + final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) { def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) } /** Configuration specific to an Ivy filesystem resolver. */ - final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) extends NotNull + final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) { def transactional() = FileConfiguration(isLocal, Some(true)) def nontransactional() = FileConfiguration(isLocal, Some(false)) @@ -151,7 +151,8 @@ import Resolver._ object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) -object JavaNet1Repository extends Resolver +object JavaNet1Repository extends JavaNet1Repository +sealed trait JavaNet1Repository extends Resolver { def name = "java.net Maven1 Repository" } @@ -357,7 +358,7 @@ object Artifact Artifact(name, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } } -final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) extends NotNull +final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration { def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) From d91f3c14c95cc0cf8ae22786aecb788bcca5a4d8 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 13 Nov 2010 20:21:06 -0500 Subject: [PATCH 0059/1030] work on products+configurations --- ivy/IvyInterface.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 74f7fa876..52d02d876 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -292,11 +292,11 @@ object Configurations lazy val Default = config("default") lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") hide + lazy val IntegrationTest = config("it") extend(Runtime) hide; lazy val Provided = config("provided") lazy val Javadoc = config("javadoc") - lazy val Runtime = config("runtime") - lazy val Test = config("test") hide + lazy val Runtime = config("runtime") extend(Compile) + lazy val Test = config("test") extend(Runtime) hide; lazy val Sources = config("sources") lazy val System = config("system") lazy val Optional = config("optional") @@ -310,7 +310,7 @@ object Configurations private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } /** Represents an Ivy configuration. */ -final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) extends NotNull +final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) { require(name != null && !name.isEmpty) require(description != null) @@ -323,7 +323,7 @@ final case class Configuration(name: String, description: String, isPublic: Bool override def toString = name } -final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) extends NotNull +final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) { def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) } From ff119a0bbee7469d031d5fb46666af6d017dfabe Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 2 Dec 2010 19:56:19 -0500 Subject: [PATCH 0060/1030] update deliver,make-pom,publish-local to be usable --- ivy/IvyActions.scala | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index bcda71dc1..966d68753 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -8,7 +8,7 @@ import scala.xml.{Node,NodeSeq} import org.apache.ivy.{core, plugins, Ivy} import core.cache.DefaultRepositoryCacheManager -import core.LogOptions +import core.{IvyPatternHelper,LogOptions} import core.deliver.DeliverOptions import core.install.InstallOptions import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} @@ -20,15 +20,13 @@ import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} +final class PublishPatterns(val deliverIvyPattern: Option[String], val srcArtifactPatterns: Seq[String]) +final class PublishConfiguration(val patterns: PublishPatterns, val status: String, val resolverName: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) + final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean) -final class MakePomConfiguration(val extraDependencies: Iterable[ModuleID], val configurations: Option[Iterable[Configuration]], - val extra: NodeSeq, val process: Node => Node, val filterRepositories: MavenRepository => Boolean) -object MakePomConfiguration -{ - def apply(extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], extra: NodeSeq) = - new MakePomConfiguration(extraDependencies, configurations, extra, identity, _ => true) -} +final class MakePomConfiguration(val file: File, val configurations: Option[Iterable[Configuration]] = None, val extra: NodeSeq = NodeSeq.Empty, val process: Node => Node = n => n, val filterRepositories: MavenRepository => Boolean = _ => true) + /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. * `DownloadOnly` only logs what is downloaded. @@ -62,43 +60,45 @@ object IvyActions } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, output: File) + def makePom(module: IvySbt#Module, configuration: MakePomConfiguration) { - import configuration.{configurations, extra, extraDependencies, filterRepositories, process} + import configuration.{configurations, extra, file, filterRepositories, process} module.withModule { (ivy, md, default) => - addLateDependencies(ivy, md, default, extraDependencies) - (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, output) - module.logger.info("Wrote " + output.getAbsolutePath) + (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, file) + module.logger.info("Wrote " + file.getAbsolutePath) } } - // todo: correct default configuration for extra dependencies - private def addLateDependencies(ivy: Ivy, module: DefaultModuleDescriptor, defaultConfiguration: String, extraDependencies: Iterable[ModuleID]) - { - val parser = new CustomXmlParser.CustomParser(ivy.getSettings, Some(defaultConfiguration)) - parser.setMd(module) - IvySbt.addDependencies(module, extraDependencies, parser) - } - def deliver(module: IvySbt#Module, status: String, deliverIvyPattern: String, extraDependencies: Iterable[ModuleID], configurations: Option[Iterable[Configuration]], logging: UpdateLogging.Value) + def deliver(module: IvySbt#Module, configuration: PublishConfiguration) { + import configuration._ + import patterns._ module.withModule { case (ivy, md, default) => - addLateDependencies(ivy, md, default, extraDependencies) resolve(logging)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + ivy.deliver(revID, revID.getRevision, getDeliverIvyPattern(patterns), options) } } + // because Ivy.deliver does not provide the delivered File location, we duplicate the logic here + def deliverFile(module: IvySbt#Module, configuration: PublishConfiguration): File = + module.withModule { (ivy,md,_) => + ivy.getSettings.resolveFile(IvyPatternHelper.substitute(getDeliverIvyPattern(configuration.patterns), md.getResolvedModuleRevisionId)) + } + def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified")) + // todo: map configurations, extra dependencies - def publish(module: IvySbt#Module, resolverName: String, srcArtifactPatterns: Iterable[String], deliveredIvyPattern: Option[String], configurations: Option[Iterable[Configuration]]) + def publish(module: IvySbt#Module, configuration: PublishConfiguration) { + import configuration._ + import patterns._ module.withModule { case (ivy, md, default) => val revID = md.getModuleRevisionId val patterns = new java.util.ArrayList[String] srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) val options = (new PublishOptions).setOverwrite(true) - deliveredIvyPattern.foreach(options.setSrcIvyPattern) + deliverIvyPattern.foreach(options.setSrcIvyPattern) options.setConfs(IvySbt.getConfigurations(md, configurations)) ivy.publish(revID, patterns, resolverName, options) } From 1c9cad21c5ad8af3f7a4ae050ee69392dd06f2fe Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 4 Jan 2011 11:10:31 -0500 Subject: [PATCH 0061/1030] always use 'jar' as packaging type if there is an artifact with a 'jar' type --- ivy/MakePom.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index d6a392fc8..be09ecc48 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -77,8 +77,9 @@ class MakePom case Array() => "pom" case Array(x) => x.getType case xs => - val notpom = xs.filter(_.getType != "pom") - if(notpom.isEmpty) "pom" else notpom(0).getType + val types = xs.map(_.getType) + val notpom = types.toList - "pom" + if(notpom.isEmpty) "pom" else if(notpom contains "jar") "jar" else notpom.head } def makeDependencies(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): NodeSeq = From 6ceba21615bf06b40c22adf94e27f2fef0117a8b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 18 Jan 2011 18:24:11 -0500 Subject: [PATCH 0062/1030] multi-project model based on Settings and ProjectRef --- ivy/IvyInterface.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 52d02d876..415cc1b09 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -288,6 +288,7 @@ object Resolver object Configurations { def config(name: String) = new Configuration(name) + def default = defaultMavenConfigurations def defaultMavenConfigurations = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil lazy val Default = config("default") From 3f0633c06fea511eea185d7dc75e4614a08a16c7 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 2 Feb 2011 19:32:24 -0500 Subject: [PATCH 0063/1030] Configuration-related tweaks --- ivy/IvyInterface.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 415cc1b09..30427c299 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -288,8 +288,8 @@ object Resolver object Configurations { def config(name: String) = new Configuration(name) - def default = defaultMavenConfigurations - def defaultMavenConfigurations = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil + def default: Seq[Configuration] = defaultMavenConfigurations + def defaultMavenConfigurations: Seq[Configuration] = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil lazy val Default = config("default") lazy val Compile = config("compile") @@ -297,7 +297,7 @@ object Configurations lazy val Provided = config("provided") lazy val Javadoc = config("javadoc") lazy val Runtime = config("runtime") extend(Compile) - lazy val Test = config("test") extend(Runtime) hide; + lazy val Test = config("test") extend(Runtime); lazy val Sources = config("sources") lazy val System = config("system") lazy val Optional = config("optional") From 191c19dc2bf2a7c0346b970f97708c19f37fd516 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 5 Feb 2011 21:34:17 -0500 Subject: [PATCH 0064/1030] fix deadlock caused by lazy val synchronization --- ivy/Ivy.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 49cdf2720..f5d2bd2bb 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -34,7 +34,7 @@ final class IvySbt(val configuration: IvyConfiguration) private def withDefaultLogger[T](f: => T): T = { def action() = - IvySbt.synchronized + IvySbt.synchronized { val originalLogger = Message.getDefaultLogger Message.setDefaultLogger(logger) @@ -93,7 +93,9 @@ final class IvySbt(val configuration: IvyConfiguration) def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } - lazy val (moduleDescriptor: DefaultModuleDescriptor, defaultConfig: String) = + def moduleDescriptor = IvySbt.synchronized { moduleDescriptor0 } + def defaultConfig = IvySbt.synchronized { defaultConfig0 } + private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = { val (baseModule, baseConfiguration) = moduleSettings match From 91b95ee23a5fffb5e85a7cd468737bb2272789c3 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 8 Feb 2011 20:32:11 -0500 Subject: [PATCH 0065/1030] fix ProjectResolver to properly ignore artifacts --- ivy/ProjectResolver.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala index 45f473120..4d1ae4f37 100644 --- a/ivy/ProjectResolver.scala +++ b/ivy/ProjectResolver.scala @@ -42,12 +42,7 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def exists(artifact: IArtifact) = false def locate(artifact: IArtifact) = null def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = - { - val r = new DownloadReport - for(artifact <- artifacts) - r addArtifactReport notDownloaded(artifact) - r - } + new DownloadReport def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = notDownloaded(artifact.getArtifact) def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null From 48f9fdbdb2dd20f071bc3fc44e30ce14bba513e5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Feb 2011 08:16:07 -0500 Subject: [PATCH 0066/1030] package, package-doc, package-src --- ivy/ArtifactName.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ivy/ArtifactName.scala diff --git a/ivy/ArtifactName.scala b/ivy/ArtifactName.scala new file mode 100644 index 000000000..a4adef5cd --- /dev/null +++ b/ivy/ArtifactName.scala @@ -0,0 +1,16 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ +package sbt + +final case class ArtifactName(base: String, version: String, config: String, tpe: String, ext: String) +object ArtifactName +{ + def show(name: ArtifactName) = + { + import name._ + val confStr = if(config.isEmpty || config == "compile") "" else "-" + config + val tpeStr = if(tpe.isEmpty) "" else "-" + tpe + base + "-" + version + confStr + tpeStr + "." + ext + } +} \ No newline at end of file From 2e7eaac15be3904634ab50e64876bbf93c70e819 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 11 Feb 2011 20:09:42 -0500 Subject: [PATCH 0067/1030] fix stray Ivy logging message when directly accessing IvySbt#Module --- ivy/Ivy.scala | 8 +++++--- ivy/IvyInterface.scala | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index f5d2bd2bb..ff2412554 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -91,10 +91,12 @@ final class IvySbt(val configuration: IvyConfiguration) def owner = IvySbt.this def logger = configuration.log def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = - withIvy[T] { ivy => f(ivy, moduleDescriptor, defaultConfig) } + withIvy[T] { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } - def moduleDescriptor = IvySbt.synchronized { moduleDescriptor0 } - def defaultConfig = IvySbt.synchronized { defaultConfig0 } + def moduleDescriptor = withModule((_,md,_) => md) + def defaultConfig = withModule( (_,_,dc) => dc) + // these should only be referenced by withModule because lazy vals synchronize on this object + // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = { val (baseModule, baseConfiguration) = diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 30427c299..b56187ad9 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -356,7 +356,7 @@ object Artifact val name = file.getName val i = name.lastIndexOf('.') val base = if(i >= 0) name.substring(0, i) else name - Artifact(name, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) + Artifact(base, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) From 75bfabb38101f576415ee357eafa10b88415a88d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 14 Feb 2011 18:57:10 -0500 Subject: [PATCH 0068/1030] implement %% --- ivy/Ivy.scala | 26 +++++++++++++++++++++++++- ivy/IvyConfigurations.scala | 23 +++++++++++------------ ivy/IvyInterface.scala | 2 +- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index ff2412554..9490ad61c 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -86,8 +86,9 @@ final class IvySbt(val configuration: IvyConfiguration) finally { ivy.popContext() } } - final class Module(val moduleSettings: ModuleSettings) + final class Module(rawModuleSettings: ModuleSettings) { + val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) def owner = IvySbt.this def logger = configuration.log def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = @@ -250,6 +251,29 @@ private object IvySbt import m._ ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes)) } + + private def substituteCross(m: ModuleSettings): ModuleSettings = + m.ivyScala match { case None => m; case Some(is) => substituteCross(m, is.scalaVersion) } + private def substituteCross(m: ModuleSettings, cross: String): ModuleSettings = + m match { + case ec: EmptyConfiguration => ec.copy(module = substituteCross(ec.module, cross)) + case ic: InlineConfiguration => ic.copy(module = substituteCross(ic.module, cross), dependencies = substituteCrossM(ic.dependencies, cross)) + case _ => m + } + private def crossName(name: String, cross: String): String = + name + "_" + cross + private def substituteCross(a: Artifact, cross: String): Artifact = + a.copy(name = crossName(a.name, cross)) + private def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] = + as.map(art => substituteCross(art, cross)) + private def substituteCrossM(ms: Seq[ModuleID], cross: String): Seq[ModuleID] = + ms.map(m => substituteCross(m, cross)) + private def substituteCross(m: ModuleID, cross: String): ModuleID = + if(m.crossVersion) + m.copy(name = crossName(m.name, cross), crossVersion = false, explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + else + m + private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a)) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 6ba3d63a3..6903c44d8 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -54,25 +54,24 @@ sealed trait ModuleSettings def ivyScala: Option[IvyScala] def noScala: ModuleSettings } -final class IvyFileConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { - def noScala = new IvyFileConfiguration(file, None, validate) + def noScala = copy(ivyScala = None) } -final class PomConfiguration(val file: File, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { - def noScala = new PomConfiguration(file, None, validate) + def noScala = copy(ivyScala = None) } -final class InlineConfiguration(val module: ModuleID, val dependencies: Seq[ModuleID], val ivyXML: NodeSeq, - val configurations: Seq[Configuration], val defaultConfiguration: Option[Configuration], val ivyScala: Option[IvyScala], - val validate: Boolean) extends ModuleSettings +final case class InlineConfiguration(module: ModuleID, dependencies: Seq[ModuleID], ivyXML: NodeSeq, + configurations: Seq[Configuration], defaultConfiguration: Option[Configuration], ivyScala: Option[IvyScala], + validate: Boolean) extends ModuleSettings { - def withConfigurations(configurations: Seq[Configuration]) = - new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, ivyScala, validate) - def noScala = new InlineConfiguration(module, dependencies, ivyXML, configurations, defaultConfiguration, None, validate) + def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) + def noScala = copy(ivyScala = None) } -final class EmptyConfiguration(val module: ModuleID, val ivyScala: Option[IvyScala], val validate: Boolean) extends ModuleSettings +final case class EmptyConfiguration(module: ModuleID, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { - def noScala = new EmptyConfiguration(module, None, validate) + def noScala = copy(ivyScala = None) } object InlineConfiguration { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index b56187ad9..b6f4909e0 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -12,8 +12,8 @@ import org.apache.ivy.util.url.CredentialsStore final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) { override def toString = organization + ":" + name + ":" + revision - // () required for chaining def cross(v: Boolean) = copy(crossVersion = v) + // () required for chaining def notTransitive() = intransitive() def intransitive() = copy(isTransitive = false) def changing() = copy(isChanging = true) From 7ad8785fc4703bf7aebce53acb29fff53b2e6dac Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 17 Feb 2011 16:20:30 -0500 Subject: [PATCH 0069/1030] configure Ivy cache to ignore original resolver --- ivy/Ivy.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 9490ad61c..c9922f9ca 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -10,9 +10,9 @@ import java.util.concurrent.Callable import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper -import core.cache.DefaultRepositoryCacheManager +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor} +import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.settings.IvySettings import plugins.matcher.PatternMatcher @@ -218,7 +218,10 @@ private object IvySbt private def configureCache(settings: IvySettings, dir: Option[File], localOnly: Boolean) { val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) - val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) + val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { + override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = + super.findModuleInCache(dd,revId,options,null) + } manager.setUseOrigin(true) if(localOnly) manager.setDefaultTTL(java.lang.Long.MAX_VALUE); From 3326d8ac527e8d36a047464c826465742ef56af4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 21 Feb 2011 10:22:39 -0500 Subject: [PATCH 0070/1030] include Scala version to artifact names to match expected names for publishing --- ivy/ArtifactName.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/ArtifactName.scala b/ivy/ArtifactName.scala index a4adef5cd..beb2b5cac 100644 --- a/ivy/ArtifactName.scala +++ b/ivy/ArtifactName.scala @@ -3,7 +3,7 @@ */ package sbt -final case class ArtifactName(base: String, version: String, config: String, tpe: String, ext: String) +final case class ArtifactName(base: String, version: String, config: String, tpe: String, ext: String, cross: String) object ArtifactName { def show(name: ArtifactName) = @@ -11,6 +11,7 @@ object ArtifactName import name._ val confStr = if(config.isEmpty || config == "compile") "" else "-" + config val tpeStr = if(tpe.isEmpty) "" else "-" + tpe - base + "-" + version + confStr + tpeStr + "." + ext + val addCross = if(cross.isEmpty) "" else "_" + cross + base + addCross + "-" + version + confStr + tpeStr + "." + ext } } \ No newline at end of file From c7d920caf253c16007a0097d8dcdc25c52b80368 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 4 Mar 2011 05:25:40 -0500 Subject: [PATCH 0071/1030] 2.9 compatibility fixes --- ivy/IvyActions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 966d68753..a685ed2e7 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -138,7 +138,7 @@ object IvyActions val map = rawMap.asInstanceOf[java.util.Map[ArtifactDownloadReport,java.util.Set[String]]] val confMap = new collection.mutable.HashMap[String, Seq[File]] - import collection.JavaConversions.{asScalaMap,asScalaSet} + import collection.JavaConversions._ for( (report, all) <- map; retrieved <- all; val file = new File(retrieved); conf <- report.getArtifact.getConfigurations) confMap.put(conf, file +: confMap.getOrElse(conf, Nil)) confMap.toMap From c0f36778440f5ea2b1155adbdac3d7a23ba9594d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 12 Mar 2011 10:28:53 -0500 Subject: [PATCH 0072/1030] more consistent configuration of the Ivy user directory --- ivy/ConvertResolver.scala | 11 ++++++----- ivy/Ivy.scala | 8 ++++---- ivy/IvyCache.scala | 2 +- ivy/IvyInterface.scala | 17 ++++++++--------- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index cd4d1a2a0..eec6a5121 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -5,13 +5,14 @@ package sbt import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId +import core.settings.IvySettings import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} private object ConvertResolver { /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver) = + def apply(r: Resolver)(implicit settings: IvySettings) = { r match { @@ -69,7 +70,7 @@ private object ConvertResolver resolver.setM2compatible(true) resolver.setRoot(root) } - private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository) + private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)(implicit settings: IvySettings) { resolver.setName(repo.name) resolver.setPassfile(null) @@ -93,10 +94,10 @@ private object ConvertResolver setUser(user) } } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns) + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns)(implicit settings: IvySettings) { resolver.setM2compatible(patterns.isMavenCompatible) - patterns.ivyPatterns.foreach(resolver.addIvyPattern) - patterns.artifactPatterns.foreach(resolver.addArtifactPattern) + patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) + patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) } } diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index c9922f9ca..e04e486bd 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -181,7 +181,7 @@ private object IvySbt { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") - val chain = resolverChain(name, rs, localOnly, log) + val chain = resolverChain(name, rs, localOnly, settings, log) settings.addResolver(chain) chain } @@ -189,7 +189,7 @@ private object IvySbt val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } - private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, log: Logger): ChainResolver = + private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): ChainResolver = { val newDefault = new ChainResolver newDefault.setName(name) @@ -197,7 +197,7 @@ private object IvySbt newDefault.setCheckmodified(false) for(sbtResolver <- resolvers) { log.debug("\t" + sbtResolver) - newDefault.add(ConvertResolver(sbtResolver)) + newDefault.add(ConvertResolver(sbtResolver)(settings)) } newDefault } @@ -210,7 +210,7 @@ private object IvySbt import IvyPatternHelper._ import PatternMatcher._ if(!existing.contains(resolver.name)) - settings.addResolver(ConvertResolver(resolver)) + settings.addResolver(ConvertResolver(resolver)(settings)) val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 072be22a0..9724e1009 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -84,7 +84,7 @@ object IvyCache /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { - val local = Resolver.defaultLocal(None) + val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), None) val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, log) (new IvySbt(conf), local) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index b6f4909e0..3f25ef617 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -174,7 +174,7 @@ object Resolver * If `scalaTools` is true, add the Scala Tools releases repository. * If `mavenCentral` is true, add the Maven Central repository. */ def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = - Seq(Resolver.defaultLocal(None)) ++ + Seq(Resolver.defaultLocal) ++ userResolvers ++ single(DefaultMavenRepository, mavenCentral)++ single(ScalaToolsReleases, scalaTools) @@ -270,14 +270,13 @@ object Resolver def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]" - def userRoot = System.getProperty("user.home") - def userMavenRoot = userRoot + "/.m2/repository/" - def userIvyRoot = userRoot + "/.ivy2/" - private def userIvyRootFile = new File(userIvyRoot) - - def defaultLocal(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "local") - def defaultShared(ivyHome: Option[File]) = defaultUserFileRepository(ivyHome, "shared") - def defaultUserFileRepository(ivyHome: Option[File], id: String) = file(id, new File(ivyHome.getOrElse(userIvyRootFile), id))(defaultIvyPatterns) + def defaultLocal = defaultUserFileRepository("local") + def defaultShared = defaultUserFileRepository("shared") + def defaultUserFileRepository(id: String) = + { + val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil + FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) + } def defaultIvyPatterns = { val pList = List(localBasePattern) From 39a6475b2e63a094fcd34d8a5a32a16ced21d2aa Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 13 Mar 2011 21:40:49 -0400 Subject: [PATCH 0073/1030] detailed UpdateReport replaces Map[String,Seq[File]] the information included is: configuration -> module -> artifact -> file --- ivy/IvyActions.scala | 34 ++------------------------ ivy/IvyRetrieve.scala | 55 +++++++++++++++++++++++++++++++++---------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a685ed2e7..8310fb955 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -105,44 +105,14 @@ object IvyActions } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - def update(module: IvySbt#Module, configuration: UpdateConfiguration) = + def update(module: IvySbt#Module, configuration: UpdateConfiguration): UpdateReport = { module.withModule { case (ivy, md, default) => import configuration.{retrieve => rConf, logging} val report = resolve(logging)(ivy, md, default) - rConf match - { - case None => IvyRetrieve.cachePaths(report) - case Some(conf) => retrieve(ivy, md, conf, logging) - } + IvyRetrieve.updateReport(report) } } - // doesn't work. perhaps replace retrieve/determineArtifactsToCopy with custom code - private def retrieve(ivy: Ivy, md: ModuleDescriptor, conf: RetrieveConfiguration, logging: UpdateLogging.Value) = - { - import conf._ - val retrieveOptions = new RetrieveOptions - retrieveOptions.setSync(synchronize) - val patternBase = retrieveDirectory.getAbsolutePath - val pattern = - if(patternBase.endsWith(File.separator)) - patternBase + outputPattern - else - patternBase + File.separatorChar + outputPattern - - val engine = ivy.getRetrieveEngine - engine.retrieve(md.getModuleRevisionId, pattern, retrieveOptions) - - //TODO: eliminate the duplication for better efficiency (retrieve already calls determineArtifactsToCopy once) - val rawMap = engine.determineArtifactsToCopy(md.getModuleRevisionId, pattern, retrieveOptions) - val map = rawMap.asInstanceOf[java.util.Map[ArtifactDownloadReport,java.util.Set[String]]] - val confMap = new collection.mutable.HashMap[String, Seq[File]] - - import collection.JavaConversions._ - for( (report, all) <- map; retrieved <- all; val file = new File(retrieved); conf <- report.getArtifact.getConfigurations) - confMap.put(conf, file +: confMap.getOrElse(conf, Nil)) - confMap.toMap - } private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): ResolveReport = { val resolveOptions = new ResolveOptions diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index 7cfd7f026..f9eecfff4 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -6,6 +6,7 @@ package sbt import java.io.File import org.apache.ivy.core.{module, report} +import module.descriptor.{Artifact => IvyArtifact} import module.id.ModuleRevisionId import report.{ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport} @@ -14,21 +15,49 @@ object IvyRetrieve def reports(report: ResolveReport): Map[String, ConfigurationResolveReport] = ( for( conf <- report.getConfigurations) yield (conf, report.getConfigurationReport(conf)) ).toMap - def artifactReports(confReport: ConfigurationResolveReport): Seq[ArtifactDownloadReport] = + def moduleReports(confReport: ConfigurationResolveReport): Map[ModuleID, ModuleReport] = + moduleReportMap(confReport) map { case (mid, arts) => (mid, new ModuleReport(mid, artifactReports(arts)) ) } + + def moduleReportMap(confReport: ConfigurationResolveReport): Map[ModuleID, Seq[ArtifactDownloadReport]] = { - val all = new scala.collection.mutable.HashSet[ArtifactDownloadReport] - for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) - all ++= confReport.getDownloadReports(revId) - all.toSeq + val modules = + for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield + (toModuleID(revId), (confReport getDownloadReports revId).toSeq) + modules.toMap + } + def artifactReports(artReport: Seq[ArtifactDownloadReport]): Map[Artifact, File] = + artReport map { r => + val art = r.getArtifact + val file0 = r.getLocalFile + val file = if(file0 eq null) error("No file for " + art) else file0 + (toArtifact(art), file) + } toMap; + + def toModuleID(revID: ModuleRevisionId): ModuleID = + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) + + def toArtifact(art: IvyArtifact): Artifact = + { + import art._ + Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl)) } - def cachePath(reports: Seq[ArtifactDownloadReport]): Seq[File] = - for(r <- reports) yield - { - val file = r.getLocalFile - if(file eq null) error("No file for " + r.getArtifact) else file - } + def updateReport(report: ResolveReport): UpdateReport = + new UpdateReport(reports(report) mapValues configurationReport) - def cachePaths(report: ResolveReport): Map[String, Seq[File]] = - reports(report).mapValues(confReport => cachePath(artifactReports(confReport))) + def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport)) +} + +final class UpdateReport(val configurations: Map[String, ConfigurationReport]) +{ + override def toString = "Update report:\n" + configurations.values.mkString +} +final class ConfigurationReport(val configuration: String, val modules: Map[ModuleID, ModuleReport]) +{ + override def toString = "\t" + configuration + ":\n" + modules.values.mkString +} +final class ModuleReport(val module: ModuleID, val artifacts: Map[Artifact, File]) +{ + override def toString = "\t\t" + module + ": " + (if(artifacts.size <= 1) "" else "\n") + artifacts.mkString("\n\t\t\t") + "\n" } \ No newline at end of file From 4e55503d64ed98905a7d192015f211b598c1f3bb Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 15 Mar 2011 20:35:43 -0400 Subject: [PATCH 0074/1030] retrieve to build, update-classifiers action set retrieve := true to have dependencies retrieved to the build the location is by default shared by all projects in a build (/lib_managed/), but can be per-project update-classifiers and update-sbt-classifiers retrieves artifacts with classifiers for project dependencies and for sbt, respectively The default setting is classifiers := Seq("javadoc", "sources") --- ivy/Ivy.scala | 9 +++-- ivy/IvyActions.scala | 77 ++++++++++++++++++++++++++++++++++-------- ivy/IvyInterface.scala | 2 +- ivy/IvyRetrieve.scala | 41 ++++++++++++++++------ 4 files changed, 100 insertions(+), 29 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index e04e486bd..a2d03f269 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -283,13 +283,16 @@ private object IvySbt configurations.foreach(artifact.addConfiguration) artifact } - private def extra(artifact: Artifact) = + private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = { val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } - javaMap(ea.extraAttributes) + javaMap(ea.extraAttributes, unqualify) } - private def javaMap(map: Map[String,String]) = + private[sbt] def javaMap(m: Map[String,String], unqualify: Boolean = false) = + { + val map = m map { case (k, v) => (k.stripPrefix("e:"), v) } if(map.isEmpty) null else scala.collection.JavaConversions.asJavaMap(map) + } private object javaMap { diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 8310fb955..203331e21 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -23,8 +23,8 @@ import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} final class PublishPatterns(val deliverIvyPattern: Option[String], val srcArtifactPatterns: Seq[String]) final class PublishConfiguration(val patterns: PublishPatterns, val status: String, val resolverName: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) -final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value) -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val synchronize: Boolean) +final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) final class MakePomConfiguration(val file: File, val configurations: Option[Iterable[Configuration]] = None, val extra: NodeSeq = NodeSeq.Empty, val process: Node => Node = n => n, val filterRepositories: MavenRepository => Boolean = _ => true) /** Configures logging during an 'update'. `level` determines the amount of other information logged. @@ -81,11 +81,7 @@ object IvyActions ivy.deliver(revID, revID.getRevision, getDeliverIvyPattern(patterns), options) } } - // because Ivy.deliver does not provide the delivered File location, we duplicate the logic here - def deliverFile(module: IvySbt#Module, configuration: PublishConfiguration): File = - module.withModule { (ivy,md,_) => - ivy.getSettings.resolveFile(IvyPatternHelper.substitute(getDeliverIvyPattern(configuration.patterns), md.getResolvedModuleRevisionId)) - } + def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified")) // todo: map configurations, extra dependencies @@ -106,21 +102,72 @@ object IvyActions /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ def update(module: IvySbt#Module, configuration: UpdateConfiguration): UpdateReport = - { module.withModule { case (ivy, md, default) => - import configuration.{retrieve => rConf, logging} - val report = resolve(logging)(ivy, md, default) - IvyRetrieve.updateReport(report) + val (report, err) = resolve(configuration.logging)(ivy, md, default) + err match + { + case Some(x) if !configuration.missingOk => throw x + case _ => + val uReport = IvyRetrieve updateReport report + configuration.retrieve match + { + case Some(rConf) => retrieve(ivy, uReport, rConf) + case None => uReport + } + } } + + def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = + { + val base = id.copy(name = id.name + "$" + label) + val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) + val report = update(module, c) + transitive(ivySbt, id, report, classifiers, c, ivyScala) } - private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): ResolveReport = + def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = + updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala) + def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = + { + assert(!classifiers.isEmpty, "classifiers cannot be empty") + val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) } + val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact(m.name, c) }) } + val base = id.copy(name = id.name + classifiers.mkString("$","_","")) + val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) + update(module, configuration) + } + private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions resolveOptions.setLog(ivyLogLevel(logging)) val resolveReport = ivy.resolve(module, resolveOptions) - if(resolveReport.hasError) - throw new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct) - resolveReport + val err = + if(resolveReport.hasError) + Some(new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct)) + else None + (resolveReport, err) + } + private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = + retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) + + private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = + { + val toCopy = new collection.mutable.HashSet[(File,File)] + val retReport = report retrieve { (conf, mid, art, cached) => + val to = retrieveTarget(conf, mid, art, base, pattern) + toCopy += ((cached, to)) + to + } + IO.copy( toCopy ) + retReport + } + private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = + new File(base, substitute(conf, mid, art, pattern)) + + private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = + { + val mextra = IvySbt.javaMap(mid.extraAttributes, true) + val aextra = IvySbt.extra(art, true) + IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra) } import UpdateLogging.{Quiet, Full, DownloadOnly} diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 3f25ef617..4efd8c88f 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -11,7 +11,7 @@ import org.apache.ivy.util.url.CredentialsStore final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) { - override def toString = organization + ":" + name + ":" + revision + override def toString = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) def cross(v: Boolean) = copy(crossVersion = v) // () required for chaining def notTransitive() = intransitive() diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index f9eecfff4..6afd05530 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -4,6 +4,7 @@ package sbt import java.io.File +import collection.mutable import org.apache.ivy.core.{module, report} import module.descriptor.{Artifact => IvyArtifact} @@ -16,7 +17,7 @@ object IvyRetrieve ( for( conf <- report.getConfigurations) yield (conf, report.getConfigurationReport(conf)) ).toMap def moduleReports(confReport: ConfigurationResolveReport): Map[ModuleID, ModuleReport] = - moduleReportMap(confReport) map { case (mid, arts) => (mid, new ModuleReport(mid, artifactReports(arts)) ) } + moduleReportMap(confReport) map { case (mid, arts) => (mid, artifactReports(mid, arts) ) } def moduleReportMap(confReport: ConfigurationResolveReport): Map[ModuleID, Seq[ArtifactDownloadReport]] = { @@ -25,13 +26,20 @@ object IvyRetrieve (toModuleID(revId), (confReport getDownloadReports revId).toSeq) modules.toMap } - def artifactReports(artReport: Seq[ArtifactDownloadReport]): Map[Artifact, File] = - artReport map { r => - val art = r.getArtifact - val file0 = r.getLocalFile - val file = if(file0 eq null) error("No file for " + art) else file0 - (toArtifact(art), file) - } toMap; + def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = + { + val missing = new mutable.ListBuffer[Artifact] + val resolved = new mutable.ListBuffer[(Artifact,File)] + for(r <- artReport) { + val file = r.getLocalFile + val art = toArtifact(r.getArtifact) + if(file eq null) + missing += art + else + resolved += ((art,file)) + } + new ModuleReport(mid, resolved.toMap, missing.toSet) + } def toModuleID(revID: ModuleRevisionId): ModuleID = ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) @@ -52,12 +60,25 @@ object IvyRetrieve final class UpdateReport(val configurations: Map[String, ConfigurationReport]) { override def toString = "Update report:\n" + configurations.values.mkString + def allModules: Seq[ModuleID] = configurations.values.toSeq.flatMap(_.allModules).distinct + def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = + new UpdateReport(configurations map { case (k,v) => (k, v retrieve f)} ) } final class ConfigurationReport(val configuration: String, val modules: Map[ModuleID, ModuleReport]) { override def toString = "\t" + configuration + ":\n" + modules.values.mkString + def allModules: Seq[ModuleID] = modules.keys.toSeq + def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = + new ConfigurationReport(configuration, modules map { case (k,v) => (k, v.retrieve( (mid,art,file) => f(configuration, mid, art, file)) ) }) } -final class ModuleReport(val module: ModuleID, val artifacts: Map[Artifact, File]) +final class ModuleReport(val module: ModuleID, val artifacts: Map[Artifact, File], val missingArtifacts: Set[Artifact]) { - override def toString = "\t\t" + module + ": " + (if(artifacts.size <= 1) "" else "\n") + artifacts.mkString("\n\t\t\t") + "\n" + override def toString = + { + val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + "\t\t" + module + ": " + + (if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" + } + def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = + new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts) } \ No newline at end of file From 7046b84954ed48e2cd7750f06002b54f0ab5861f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 Mar 2011 20:10:41 -0400 Subject: [PATCH 0075/1030] make default conflict manager ignore force see comment on IvySbt.latestNoForce --- ivy/Ivy.scala | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index a2d03f269..1a25cb1d1 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -7,6 +7,7 @@ import Artifact.{defaultExtension, defaultType} import java.io.File import java.util.concurrent.Callable +import java.util.{Collection, Collections} import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper @@ -14,7 +15,10 @@ import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import core.resolve.IvyNode import core.settings.IvySettings +import plugins.conflict.{ConflictManager, LatestConflictManager} +import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser import plugins.resolver.ChainResolver @@ -44,7 +48,7 @@ final class IvySbt(val configuration: IvyConfiguration) // Ivy is not thread-safe nor can the cache be used concurrently. // If provided a GlobalLock, we can use that to ensure safe access to the cache. // Otherwise, we can at least synchronize within the JVM. - // For thread-safety In particular, Ivy uses a static DocumentBuilder, which is not thread-safe. + // For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe. configuration.lock match { case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) @@ -55,6 +59,7 @@ final class IvySbt(val configuration: IvyConfiguration) { val is = new IvySettings is.setBaseDir(baseDirectory) + is.setDefaultConflictManager(IvySbt.latestNoForce(is)) configuration match { case e: ExternalIvyConfiguration => is.load(e.file) @@ -392,4 +397,36 @@ private object IvySbt case Some(confs) => confs.map(_.name).toList.toArray case None => module.getPublicConfigurationsNames } + + // same as Ivy's builtin latest-revision manager except that it ignores the force setting, + // which seems to be added to dependencies read from poms (perhaps only in certain circumstances) + // causing revisions of indirect dependencies other than latest to be selected + def latestNoForce(settings: IvySettings): ConflictManager = + { + import collection.JavaConversions._ + + new LatestConflictManager("latest-revision-no-force", new LatestRevisionStrategy) + { + setSettings(settings) + + override def resolveConflicts(parent: IvyNode, conflicts: Collection[_]): Collection[_] = + if(conflicts.size < 2) + conflicts + else + resolveMultiple(parent, conflicts.asInstanceOf[Collection[IvyNode]]).asInstanceOf[Collection[_]] + + def resolveMultiple(parent: IvyNode, conflicts: Collection[IvyNode]): Collection[IvyNode] = + { + val matcher = settings.getVersionMatcher + val dynamic = conflicts.exists { node => matcher.isDynamic(node.getResolvedId) } + if(dynamic) null else { + try { + val l = getStrategy.findLatest(toArtifactInfo(conflicts), null).asInstanceOf[{def getNode(): IvyNode}] + if(l eq null) conflicts else Collections.singleton(l.getNode) + } + catch { case e: LatestConflictManager.NoConflictResolvedYetException => null } + } + } + } + } } From 2a4805ac411adb9e26685dd3077f185b02de6c10 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 Mar 2011 22:21:02 -0400 Subject: [PATCH 0076/1030] more stable managed classpath ordering --- ivy/IvyRetrieve.scala | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index 6afd05530..f706fc66f 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -13,19 +13,13 @@ import report.{ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport object IvyRetrieve { - def reports(report: ResolveReport): Map[String, ConfigurationResolveReport] = - ( for( conf <- report.getConfigurations) yield (conf, report.getConfigurationReport(conf)) ).toMap + def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = + report.getConfigurations map report.getConfigurationReport - def moduleReports(confReport: ConfigurationResolveReport): Map[ModuleID, ModuleReport] = - moduleReportMap(confReport) map { case (mid, arts) => (mid, artifactReports(mid, arts) ) } + def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] = + for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield + artifactReports(toModuleID(revId), confReport getDownloadReports revId) - def moduleReportMap(confReport: ConfigurationResolveReport): Map[ModuleID, Seq[ArtifactDownloadReport]] = - { - val modules = - for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield - (toModuleID(revId), (confReport getDownloadReports revId).toSeq) - modules.toMap - } def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = { val missing = new mutable.ListBuffer[Artifact] @@ -38,7 +32,7 @@ object IvyRetrieve else resolved += ((art,file)) } - new ModuleReport(mid, resolved.toMap, missing.toSet) + new ModuleReport(mid, resolved.toSeq, missing.toSeq) } def toModuleID(revID: ModuleRevisionId): ModuleID = @@ -51,27 +45,28 @@ object IvyRetrieve } def updateReport(report: ResolveReport): UpdateReport = - new UpdateReport(reports(report) mapValues configurationReport) + new UpdateReport(reports(report) map configurationReport) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport)) } -final class UpdateReport(val configurations: Map[String, ConfigurationReport]) +final class UpdateReport(val configurations: Seq[ConfigurationReport]) { - override def toString = "Update report:\n" + configurations.values.mkString - def allModules: Seq[ModuleID] = configurations.values.toSeq.flatMap(_.allModules).distinct + override def toString = "Update report:\n" + configurations.mkString + def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(configurations map { case (k,v) => (k, v retrieve f)} ) + new UpdateReport(configurations map { _ retrieve f} ) + def configuration(s: String) = configurations.find(_.configuration == s) } -final class ConfigurationReport(val configuration: String, val modules: Map[ModuleID, ModuleReport]) +final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport]) { - override def toString = "\t" + configuration + ":\n" + modules.values.mkString - def allModules: Seq[ModuleID] = modules.keys.toSeq + override def toString = "\t" + configuration + ":\n" + modules.mkString + def allModules: Seq[ModuleID] = modules.map(_.module) def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { case (k,v) => (k, v.retrieve( (mid,art,file) => f(configuration, mid, art, file)) ) }) + new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }) } -final class ModuleReport(val module: ModuleID, val artifacts: Map[Artifact, File], val missingArtifacts: Set[Artifact]) +final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) { override def toString = { From f10012df8758ee3550d19a2272ef96c1e2a15c23 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 22 Mar 2011 18:19:48 -0400 Subject: [PATCH 0077/1030] clean up Ivy-related logging --- ivy/Ivy.scala | 42 ++++++++++++++++++++++++------------------ ivy/IvyActions.scala | 40 ++++++++++++++++++++-------------------- ivy/IvyCache.scala | 2 +- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 1a25cb1d1..21ba28bff 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -22,20 +22,20 @@ import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser import plugins.resolver.ChainResolver -import util.Message +import util.{Message, MessageLogger} import scala.xml.NodeSeq final class IvySbt(val configuration: IvyConfiguration) { - import configuration.{log, baseDirectory} + import configuration.baseDirectory + /** ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). */ - private lazy val logger = new IvyLoggerInterface(log) - private def withDefaultLogger[T](f: => T): T = + private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = { def action() = IvySbt.synchronized @@ -55,7 +55,7 @@ final class IvySbt(val configuration: IvyConfiguration) case None => action() } } - private lazy val settings = + private lazy val settings: IvySettings = { val is = new IvySettings is.setBaseDir(baseDirectory) @@ -65,17 +65,17 @@ final class IvySbt(val configuration: IvyConfiguration) case e: ExternalIvyConfiguration => is.load(e.file) case i: InlineIvyConfiguration => IvySbt.configureCache(is, i.paths.cacheDirectory, i.localOnly) - IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, log) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations) } is } - private lazy val ivy = + private lazy val ivy: Ivy = { val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine } i.setSettings(settings) i.bind() - i.getLoggerEngine.pushLogger(logger) + i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) i } // Must be the same file as is used in Update in the launcher @@ -83,24 +83,30 @@ final class IvySbt(val configuration: IvyConfiguration) /** ========== End Configuration/Setup ============*/ /** Uses the configured Ivy instance within a safe context.*/ - def withIvy[T](f: Ivy => T): T = - withDefaultLogger + def withIvy[T](log: Logger)(f: Ivy => T): T = + withIvy(new IvyLoggerInterface(log))(f) + + def withIvy[T](log: MessageLogger)(f: Ivy => T): T = + withDefaultLogger(log) { ivy.pushContext() + ivy.getLoggerEngine.pushLogger(log) try { f(ivy) } - finally { ivy.popContext() } + finally { + ivy.getLoggerEngine.popLogger() + ivy.popContext() + } } final class Module(rawModuleSettings: ModuleSettings) { val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) def owner = IvySbt.this - def logger = configuration.log - def withModule[T](f: (Ivy,DefaultModuleDescriptor,String) => T): T = - withIvy[T] { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } + def withModule[T](log: Logger)(f: (Ivy,DefaultModuleDescriptor,String) => T): T = + withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } - def moduleDescriptor = withModule((_,md,_) => md) - def defaultConfig = withModule( (_,_,dc) => dc) + def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_,md,_) => md) + def defaultConfig(log: Logger): String = withModule(log)( (_,_,dc) => dc) // these should only be referenced by withModule because lazy vals synchronize on this object // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = @@ -108,7 +114,7 @@ final class IvySbt(val configuration: IvyConfiguration) val (baseModule, baseConfiguration) = moduleSettings match { - case ic: InlineConfiguration => configureInline(ic) + case ic: InlineConfiguration => configureInline(ic, configuration.log) case ec: EmptyConfiguration => configureEmpty(ec.module) case pc: PomConfiguration => readPom(pc.file, pc.validate) case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate) @@ -117,7 +123,7 @@ final class IvySbt(val configuration: IvyConfiguration) baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra") (baseModule, baseConfiguration) } - private def configureInline(ic: InlineConfiguration) = + private def configureInline(ic: InlineConfiguration, log: Logger) = { import ic._ val moduleID = newConfiguredModuleID(module, configurations) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 203331e21..95e779e43 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -39,12 +39,12 @@ object UpdateLogging extends Enumeration object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ - def install(module: IvySbt#Module, from: String, to: String) + def install(module: IvySbt#Module, from: String, to: String, log: Logger) { - module.withModule { (ivy, md, default) => + module.withModule(log) { (ivy, md, default) => for(dependency <- md.getDependencies) { - module.logger.info("Installing " + dependency) + log.info("Installing " + dependency) val options = new InstallOptions options.setValidate(module.moduleSettings.validate) options.setTransitive(dependency.isTransitive) @@ -54,26 +54,26 @@ object IvyActions } /** Clears the Ivy cache, as configured by 'config'. */ - def cleanCache(ivy: IvySbt) = ivy.withIvy { iv => + def cleanCache(ivy: IvySbt, log: Logger) = ivy.withIvy(log) { iv => iv.getSettings.getResolutionCacheManager.clean() iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, configuration: MakePomConfiguration) + def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { import configuration.{configurations, extra, file, filterRepositories, process} - module.withModule { (ivy, md, default) => + module.withModule(log) { (ivy, md, default) => (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, file) - module.logger.info("Wrote " + file.getAbsolutePath) + log.info("Wrote " + file.getAbsolutePath) } } - def deliver(module: IvySbt#Module, configuration: PublishConfiguration) + def deliver(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { import configuration._ import patterns._ - module.withModule { case (ivy, md, default) => + module.withModule(log) { case (ivy, md, default) => resolve(logging)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) @@ -85,11 +85,11 @@ object IvyActions def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified")) // todo: map configurations, extra dependencies - def publish(module: IvySbt#Module, configuration: PublishConfiguration) + def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { import configuration._ import patterns._ - module.withModule { case (ivy, md, default) => + module.withModule(log) { case (ivy, md, default) => val revID = md.getModuleRevisionId val patterns = new java.util.ArrayList[String] srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) @@ -101,8 +101,8 @@ object IvyActions } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - def update(module: IvySbt#Module, configuration: UpdateConfiguration): UpdateReport = - module.withModule { case (ivy, md, default) => + def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = + module.withModule(log) { case (ivy, md, default) => val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { @@ -117,23 +117,23 @@ object IvyActions } } - def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = + def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = { val base = id.copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) - val report = update(module, c) - transitive(ivySbt, id, report, classifiers, c, ivyScala) + val report = update(module, c, log) + transitive(ivySbt, id, report, classifiers, c, ivyScala, log) } - def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = - updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala) - def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]): UpdateReport = + def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = + updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala, log) + def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = { assert(!classifiers.isEmpty, "classifiers cannot be empty") val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) } val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact(m.name, c) }) } val base = id.copy(name = id.name + classifiers.mkString("$","_","")) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) - update(module, configuration) + update(module, configuration, log) } private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index 9724e1009..c46d0fce7 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -74,7 +74,7 @@ object IvyCache def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = { val (ivy, local) = basicLocalIvy(lock, log) - ivy.withIvy { ivy => + ivy.withIvy(log) { ivy => val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] cache.setUseOrigin(false) f(cache) From bb533acd621c0f22cf780d914c5dac8d18ed9b00 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 1 Apr 2011 21:06:07 -0400 Subject: [PATCH 0078/1030] fix publish patterns for maven style publishing --- ivy/IvyActions.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 95e779e43..a8ede1d3c 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -20,7 +20,7 @@ import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} -final class PublishPatterns(val deliverIvyPattern: Option[String], val srcArtifactPatterns: Seq[String]) +final class PublishPatterns(val deliverIvyPattern: String, val srcArtifactPatterns: Seq[String], val publishIvy: Boolean) final class PublishConfiguration(val patterns: PublishPatterns, val status: String, val resolverName: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) @@ -78,12 +78,10 @@ object IvyActions val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, getDeliverIvyPattern(patterns), options) + ivy.deliver(revID, revID.getRevision, patterns.deliverIvyPattern, options) } } - def getDeliverIvyPattern(patterns: PublishPatterns) = patterns.deliverIvyPattern.getOrElse(error("No Ivy pattern specified")) - // todo: map configurations, extra dependencies def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { @@ -94,7 +92,7 @@ object IvyActions val patterns = new java.util.ArrayList[String] srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) val options = (new PublishOptions).setOverwrite(true) - deliverIvyPattern.foreach(options.setSrcIvyPattern) + if(publishIvy) options.setSrcIvyPattern(deliverIvyPattern) options.setConfs(IvySbt.getConfigurations(md, configurations)) ivy.publish(revID, patterns, resolverName, options) } From c2d344683678179b1b28d17f33617b1616a84890 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 4 Apr 2011 18:14:27 -0400 Subject: [PATCH 0079/1030] Credentials for publishing --- ivy/Credentials.scala | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 ivy/Credentials.scala diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala new file mode 100644 index 000000000..f4ad3c488 --- /dev/null +++ b/ivy/Credentials.scala @@ -0,0 +1,42 @@ +/* sbt -- Simple Build Tool + * Copyright 2009 Mark Harrah + */ +package sbt + +import java.io.File +import org.apache.ivy.util.url.CredentialsStore + +object Credentials +{ + /** Add the provided credentials to Ivy's credentials cache.*/ + def add(realm: String, host: String, userName: String, passwd: String): Unit = + CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) + /** Load credentials from the given file into Ivy's credentials cache.*/ + def apply(path: File, log: Logger): Unit = + if(path.exists) + { + val properties = read(path) + def get(keys: List[String]) = keys.flatMap(properties.get).firstOption.toRight(keys.head + " not specified in credentials file: " + path) + + List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match + { + case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass); None + case (errors, _) => log.warn(errors.mkString("\n")) + } + } + else + log.warn("Credentials file " + path + " does not exist") + + private[this] val RealmKeys = List("realm") + private[this] val HostKeys = List("host", "hostname") + private[this] val UserKeys = List("user", "user.name", "username") + private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") + + import collection.JavaConversions._ + private[this] def read(from: File): Map[String,String] = + { + val properties = new java.util.Properties + IO.load(properties, from) + properties map { case (k,v) => (k.toString, v.toString) } toMap; + } +} \ No newline at end of file From 82f1904202032cd0c9e7660f4a7485e19d399fa0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 5 Apr 2011 18:44:47 -0400 Subject: [PATCH 0080/1030] credentials and patterns for resolvers --- ivy/Credentials.scala | 21 ++++++++++++++++++--- ivy/IvyInterface.scala | 2 ++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index f4ad3c488..a2a3c9d2b 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -8,11 +8,16 @@ import org.apache.ivy.util.url.CredentialsStore object Credentials { + def apply(realm: String, host: String, userName: String, passwd: String): Credentials = + new DirectCredentials(realm, host, userName, passwd) + def apply(file: File): Credentials = + new FileCredentials(file) + /** Add the provided credentials to Ivy's credentials cache.*/ def add(realm: String, host: String, userName: String, passwd: String): Unit = CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) /** Load credentials from the given file into Ivy's credentials cache.*/ - def apply(path: File, log: Logger): Unit = + def add(path: File, log: Logger): Unit = if(path.exists) { val properties = read(path) @@ -20,13 +25,19 @@ object Credentials List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match { - case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass); None + case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass) case (errors, _) => log.warn(errors.mkString("\n")) } } else log.warn("Credentials file " + path + " does not exist") + def register(cs: Seq[Credentials], log: Logger): Unit = + cs foreach { + case f: FileCredentials => add(f.path, log) + case d: DirectCredentials => add(d.realm, d.host, d.userName, d.passwd) + } + private[this] val RealmKeys = List("realm") private[this] val HostKeys = List("host", "hostname") private[this] val UserKeys = List("user", "user.name", "username") @@ -39,4 +50,8 @@ object Credentials IO.load(properties, from) properties map { case (k,v) => (k.toString, v.toString) } toMap; } -} \ No newline at end of file +} + +sealed trait Credentials +final class FileCredentials(val path: File) extends Credentials +final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 4efd8c88f..e3383766c 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -55,6 +55,8 @@ final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[Str } object Patterns { + implicit def defaultPatterns: Patterns = Resolver.defaultPatterns + def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(Nil, artifactPatterns, isMavenCompatible) def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) From d9e7dd8392801b104e9d2f8665b09b8a83e0299d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 8 Apr 2011 19:15:13 -0400 Subject: [PATCH 0081/1030] reorganize main --- ivy/DependencyBuilders.scala | 62 ++++++++++++++++++++++++++++++++++++ ivy/StringUtilities.scala | 14 ++++++++ 2 files changed, 76 insertions(+) create mode 100644 ivy/DependencyBuilders.scala create mode 100644 ivy/StringUtilities.scala diff --git a/ivy/DependencyBuilders.scala b/ivy/DependencyBuilders.scala new file mode 100644 index 000000000..00168d7c1 --- /dev/null +++ b/ivy/DependencyBuilders.scala @@ -0,0 +1,62 @@ +/* sbt -- Simple Build Tool + * Copyright 2009,2010 Mark Harrah + */ +package sbt +package impl + + import StringUtilities.{appendable,nonEmpty} + +trait DependencyBuilders +{ + final implicit def toGroupID(groupID: String): GroupID = + { + nonEmpty(groupID, "Group ID") + new GroupID(groupID) + } + final implicit def toRepositoryName(name: String): RepositoryName = + { + nonEmpty(name, "Repository name") + new RepositoryName(name) + } + final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = + { + require(m.configurations.isEmpty, "Configurations already specified for module " + m) + new ModuleIDConfigurable(m) + } +} + +final class GroupID private[sbt] (groupID: String) +{ + def % (artifactID: String) = groupArtifact(artifactID, false) + def %% (artifactID: String) = groupArtifact(artifactID, true) + private def groupArtifact(artifactID: String, cross: Boolean) = + { + nonEmpty(artifactID, "Artifact ID") + new GroupArtifactID(groupID, artifactID, cross) + } +} +final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: Boolean) +{ + def % (revision: String): ModuleID = + { + nonEmpty(revision, "Revision") + ModuleID(groupID, artifactID, revision).cross(crossVersion) + } +} +final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) +{ + def % (configurations: String): ModuleID = + { + nonEmpty(configurations, "Configurations") + val c = configurations + moduleID.copy(configurations = Some(c)) + } +} +final class RepositoryName private[sbt] (name: String) +{ + def at (location: String) = + { + nonEmpty(location, "Repository location") + new MavenRepository(name, location) + } +} diff --git a/ivy/StringUtilities.scala b/ivy/StringUtilities.scala new file mode 100644 index 000000000..3a0075bb4 --- /dev/null +++ b/ivy/StringUtilities.scala @@ -0,0 +1,14 @@ +/* sbt -- Simple Build Tool + * Copyright 2009 Mark Harrah + */ +package sbt + +object StringUtilities +{ + def normalize(s: String) = s.toLowerCase.replaceAll("""\s+""", "-") + def nonEmpty(s: String, label: String) + { + require(s.trim.length > 0, label + " cannot be empty.") + } + def appendable(s: String) = if(s.isEmpty) "" else "_" + s +} From a53ed46ce45215d269d79982ae742104aedb2258 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 10 Apr 2011 16:22:48 -0400 Subject: [PATCH 0082/1030] dependency filters, selecting/filtering UpdateReport --- ivy/DependencyFilter.scala | 66 ++++++++++++++++++++++++++++++++++++ ivy/IvyRetrieve.scala | 27 --------------- ivy/UpdateReport.scala | 68 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 ivy/DependencyFilter.scala create mode 100644 ivy/UpdateReport.scala diff --git a/ivy/DependencyFilter.scala b/ivy/DependencyFilter.scala new file mode 100644 index 000000000..1773525c6 --- /dev/null +++ b/ivy/DependencyFilter.scala @@ -0,0 +1,66 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ +package sbt + +trait DependencyFilterExtra +{ + def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = + new ModuleFilter { + def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) + } + def artifactFilter(name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, extension: NameFilter = AllPassFilter, classifier: NameFilter = AllPassFilter): ArtifactFilter = + new ArtifactFilter { + def apply(a: Artifact): Boolean = name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier.accept(a.classifier getOrElse "") + } + def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = + new ConfigurationFilter { + def apply(c: String): Boolean = name.accept(c) + } +} +object DependencyFilter extends DependencyFilterExtra +{ + def make(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): DependencyFilter = + new DependencyFilter { + def apply(c: String, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a) + } + def apply(x: DependencyFilter, y: DependencyFilter, combine: (Boolean, Boolean) => Boolean): DependencyFilter = + new DependencyFilter { + def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) + } + def allPass: DependencyFilter = configurationFilter() + implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) } + implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } + implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) } +} +trait DependencyFilter +{ + def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean + final def &&(o: DependencyFilter) = DependencyFilter(this, o, _ && _) + final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _) + final def -- (o: DependencyFilter) = DependencyFilter(this, o, _ && !_) +} +sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter +{ self: Self => + def apply(a: Arg): Boolean + protected def make(f: Arg => Boolean): Self + final def &(o: Self): Self = combine(o, _ && _) + final def |(o: Self): Self = combine(o, _ || _) + final def -(o: Self): Self = combine(o, _ && !_) + private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = make( (m: Arg) => f(this(m), o(m)) ) +} +trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter] +{ + protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(module) +} +trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] +{ + protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(artifact) +} +trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] +{ + protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) +} \ No newline at end of file diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index f706fc66f..328a33078 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -50,30 +50,3 @@ object IvyRetrieve def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport)) } - -final class UpdateReport(val configurations: Seq[ConfigurationReport]) -{ - override def toString = "Update report:\n" + configurations.mkString - def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct - def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(configurations map { _ retrieve f} ) - def configuration(s: String) = configurations.find(_.configuration == s) -} -final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport]) -{ - override def toString = "\t" + configuration + ":\n" + modules.mkString - def allModules: Seq[ModuleID] = modules.map(_.module) - def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }) -} -final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) -{ - override def toString = - { - val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) - "\t\t" + module + ": " + - (if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" - } - def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = - new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts) -} \ No newline at end of file diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala new file mode 100644 index 000000000..50097eeeb --- /dev/null +++ b/ivy/UpdateReport.scala @@ -0,0 +1,68 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ +package sbt + + import java.io.File + +final class UpdateReport(val configurations: Seq[ConfigurationReport]) +{ + override def toString = "Update report:\n" + configurations.mkString + def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = + new UpdateReport(configurations map { _ retrieve f} ) + def configuration(s: String) = configurations.find(_.configuration == s) +} +final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport]) +{ + override def toString = "\t" + configuration + ":\n" + modules.mkString + def allModules: Seq[ModuleID] = modules.map(_.module) + def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = + new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }) +} +final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) +{ + override def toString = + { + val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + "\t\t" + module + ": " + + (if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" + } + def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = + new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts) +} +object UpdateReport +{ + implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) + final class RichUpdateReport(report: UpdateReport) + { + import DependencyFilter._ + + def allFiles: Seq[File] = matching(DependencyFilter.allPass) + def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = + matching(DependencyFilter.make(configuration, module, artifact)) + + private[this] def select0(f: DependencyFilter): Seq[File] = + for(cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { + if(file == null) error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) + file + } + + def filter(f: DependencyFilter): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = + modules map { modReport => + import modReport._ + val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } + val newMissing = missingArtifacts filter { art => f(configuration, module, art) } + new ModuleReport(module, newArtifacts, newMissing) + } + new ConfigurationReport(configuration, newModules) + } + new UpdateReport(newConfigurations) + } + } +} \ No newline at end of file From 0d6984aa88f41976979c7a52a73a3a466d621faa Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 10 Apr 2011 21:30:03 -0400 Subject: [PATCH 0083/1030] some API documentation for UpdateReport --- ivy/UpdateReport.scala | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 50097eeeb..999103e86 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -5,21 +5,51 @@ package sbt import java.io.File +/** Provides information about dependency resolution. +* It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. +* This means that for a given configuration, there should only be one revision for a given organization and module name. +* @param configurations a sequence containing one report for each configuration resolved. +* @see sbt.RichUpdateReport + */ final class UpdateReport(val configurations: Seq[ConfigurationReport]) { override def toString = "Update report:\n" + configurations.mkString + + /** All resolved modules in all configurations. */ def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = new UpdateReport(configurations map { _ retrieve f} ) + + /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ def configuration(s: String) = configurations.find(_.configuration == s) + + /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ + def configurations: Seq[String] = configurations.map(_.configuration) } + +/** Provides information about resolution of a single configuration. +* @param configuration the configuration this report is for. +* @param modules a seqeuence containing one report for each module resolved for this configuration. +*/ final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport]) { override def toString = "\t" + configuration + ":\n" + modules.mkString + + /** All resolved modules for this configuration. + * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. + */ def allModules: Seq[ModuleID] = modules.map(_.module) + def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }) } + +/** Provides information about the resolution of a module. +* This information is in the context of a specific configuration. +* @param module the `ModuleID` this report is for. +* @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. This File may be in the +*/ final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) { override def toString = @@ -34,12 +64,18 @@ final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, Fil object UpdateReport { implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) + + /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ final class RichUpdateReport(report: UpdateReport) { import DependencyFilter._ - + /** Obtains all successfully retrieved files in all configurations and modules. */ def allFiles: Seq[File] = matching(DependencyFilter.allPass) + + /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + + /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = matching(DependencyFilter.make(configuration, module, artifact)) @@ -49,6 +85,7 @@ object UpdateReport file } + /** Constructs a new report that only contains files matching the specified filter.*/ def filter(f: DependencyFilter): UpdateReport = { val newConfigurations = report.configurations.map { confReport => From 53b7b6f70179912d958b0e808d165f6b9c11569f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 11 Apr 2011 10:19:04 -0400 Subject: [PATCH 0084/1030] fix configurations name --- ivy/UpdateReport.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 999103e86..76befd5a0 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -25,7 +25,7 @@ final class UpdateReport(val configurations: Seq[ConfigurationReport]) def configuration(s: String) = configurations.find(_.configuration == s) /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ - def configurations: Seq[String] = configurations.map(_.configuration) + def allConfigurations: Seq[String] = configurations.map(_.configuration) } /** Provides information about resolution of a single configuration. From e73a49c467c7102de68b0605b5a63c52c57f8942 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 13 Apr 2011 19:01:22 -0400 Subject: [PATCH 0085/1030] Ivy home configurable instead of cache directory, work on artifact test --- ivy/Ivy.scala | 10 +++++----- ivy/IvyConfigurations.scala | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 21ba28bff..22d52a6a6 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -63,8 +63,9 @@ final class IvySbt(val configuration: IvyConfiguration) configuration match { case e: ExternalIvyConfiguration => is.load(e.file) - case i: InlineIvyConfiguration => - IvySbt.configureCache(is, i.paths.cacheDirectory, i.localOnly) + case i: InlineIvyConfiguration => + i.paths.ivyHome foreach settings.setDefaultIvyUserDir + IvySbt.configureCache(is, i.localOnly) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations) } @@ -226,9 +227,9 @@ private object IvySbt settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private def configureCache(settings: IvySettings, dir: Option[File], localOnly: Boolean) + private def configureCache(settings: IvySettings, localOnly: Boolean) { - val cacheDir = dir.getOrElse(settings.getDefaultRepositoryCacheBasedir()) + val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = super.findModuleInCache(dd,revId,options,null) @@ -243,7 +244,6 @@ private object IvySbt } settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) - dir.foreach(dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath)) } def toIvyConfiguration(configuration: Configuration) = { diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 6903c44d8..cc8bbd46f 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -6,9 +6,9 @@ package sbt import java.io.File import scala.xml.{Node, NodeSeq} -final class IvyPaths(val baseDirectory: File, val cacheDirectory: Option[File]) +final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { - def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, cacheDirectory) + def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) } sealed trait IvyConfiguration { From 40e1904615b061a6b1e5a505ce8fcf30afbbe4e2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 14 Apr 2011 07:32:42 -0400 Subject: [PATCH 0086/1030] direct Artifact->File map, removing source patterns build and publish main sources and docs by default control built-in artifacts with 'publish-artifact' // disable publishing docs publishArtifact in (Compile,packageDoc) := false // enable publishing test jar, docs, and sources publishArtifact in Test := true --- ivy/ArtifactName.scala | 17 --------------- ivy/Ivy.scala | 18 ++++++++++------ ivy/IvyActions.scala | 48 ++++++++++++++++++++++++++++-------------- ivy/IvyInterface.scala | 6 ++++++ 4 files changed, 49 insertions(+), 40 deletions(-) delete mode 100644 ivy/ArtifactName.scala diff --git a/ivy/ArtifactName.scala b/ivy/ArtifactName.scala deleted file mode 100644 index beb2b5cac..000000000 --- a/ivy/ArtifactName.scala +++ /dev/null @@ -1,17 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2011 Mark Harrah - */ -package sbt - -final case class ArtifactName(base: String, version: String, config: String, tpe: String, ext: String, cross: String) -object ArtifactName -{ - def show(name: ArtifactName) = - { - import name._ - val confStr = if(config.isEmpty || config == "compile") "" else "-" + config - val tpeStr = if(tpe.isEmpty) "" else "-" + tpe - val addCross = if(cross.isEmpty) "" else "_" + cross - base + addCross + "-" + version + confStr + tpeStr + "." + ext - } -} \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 22d52a6a6..261706f20 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -12,7 +12,7 @@ import java.util.{Collection, Collections} import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} -import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.IvyNode @@ -290,7 +290,7 @@ private object IvySbt private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { - val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a)) + val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) configurations.foreach(artifact.addConfiguration) artifact } @@ -301,7 +301,7 @@ private object IvySbt } private[sbt] def javaMap(m: Map[String,String], unqualify: Boolean = false) = { - val map = m map { case (k, v) => (k.stripPrefix("e:"), v) } + val map = if(unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m if(map.isEmpty) null else scala.collection.JavaConversions.asJavaMap(map) } @@ -372,10 +372,14 @@ private object IvySbt } } /** This method is used to add inline artifacts to the provided module. */ - def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]) + def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = + for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) + moduleID.addArtifact(c, art) + + def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = { lazy val allConfigurations = moduleID.getPublicConfigurationsNames - for(artifact <- artifacts) + for(artifact <- artifacts) yield { val configurationStrings: Iterable[String] = { @@ -385,10 +389,10 @@ private object IvySbt else artifactConfigurations.map(_.name) } - val ivyArtifact = toIvyArtifact(moduleID, artifact, configurationStrings) - configurationStrings.foreach(configuration => moduleID.addArtifact(configuration, ivyArtifact)) + toIvyArtifact(moduleID, artifact, configurationStrings) } } + /** This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. * Ivy 2.0.0 always produces a DefaultModuleDescriptor. */ private def toDefaultModuleDescriptor(md: ModuleDescriptor) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a8ede1d3c..e3105e254 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -11,7 +11,7 @@ import core.cache.DefaultRepositoryCacheManager import core.{IvyPatternHelper,LogOptions} import core.deliver.DeliverOptions import core.install.InstallOptions -import core.module.descriptor.{DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.publish.PublishOptions @@ -19,9 +19,10 @@ import core.report.{ArtifactDownloadReport,ResolveReport} import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} +import plugins.resolver.DependencyResolver -final class PublishPatterns(val deliverIvyPattern: String, val srcArtifactPatterns: Seq[String], val publishIvy: Boolean) -final class PublishConfiguration(val patterns: PublishPatterns, val status: String, val resolverName: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) +final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) +final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val logging: UpdateLogging.Value) final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) @@ -69,34 +70,36 @@ object IvyActions } } - def deliver(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) + def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = { import configuration._ - import patterns._ module.withModule(log) { case (ivy, md, default) => - resolve(logging)(ivy, md, default) // todo: set download = false for resolve val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, patterns.deliverIvyPattern, options) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } } + def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = + ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) - // todo: map configurations, extra dependencies def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { import configuration._ - import patterns._ module.withModule(log) { case (ivy, md, default) => - val revID = md.getModuleRevisionId - val patterns = new java.util.ArrayList[String] - srcArtifactPatterns.foreach(pattern => patterns.add(pattern)) - val options = (new PublishOptions).setOverwrite(true) - if(publishIvy) options.setSrcIvyPattern(deliverIvyPattern) - options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.publish(revID, patterns, resolverName, options) + val resolver = ivy.getSettings.getResolver(resolverName) + val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } + val as = mapArtifacts(md, artifacts) ++ ivyArtifact.toList + publish(md, as, resolver, overwrite = true) } } + def mapArtifacts(module: ModuleDescriptor, artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + { + val seqa = artifacts.keys.toSeq + val zipped = seqa zip IvySbt.mapArtifacts(module, seqa) + zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } + } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = @@ -177,5 +180,18 @@ object IvyActions case DownloadOnly => LOG_DOWNLOAD_ONLY case Full => LOG_DEFAULT } + + def publish(module: ModuleDescriptor, artifacts: Iterable[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = + try { + resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); + for( (artifact, file) <- artifacts) if(file.exists) + resolver.publish(artifact, file, overwrite) + resolver.commitPublishTransaction() + } catch { + case e => + try { resolver.abortPublishTransaction() } + finally { throw e } + } + } final class ResolveException(messages: Seq[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index e3383766c..79e1fc4ac 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -359,6 +359,12 @@ object Artifact val base = if(i >= 0) name.substring(0, i) else name Artifact(base, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } + def artifactName(module: ModuleID, artifact: Artifact): String = + { + import artifact._ + val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } + artifact.name + "-" + module.revision + classifierStr + "." + artifact.extension + } } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration From 14f53192ac52f449aeac30f7d8543ff6bb15965d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 14 Apr 2011 21:48:12 -0400 Subject: [PATCH 0087/1030] fix Scala version transitively (by default) --- ivy/IvyScala.scala | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index edfe274a6..bb2f3dce7 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -8,7 +8,7 @@ import scala.collection.mutable.HashSet import org.apache.ivy.{core, plugins} import core.module.descriptor.{DefaultExcludeRule, ExcludeRule} -import core.module.descriptor.{DefaultModuleDescriptor, ModuleDescriptor} +import core.module.descriptor.{DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import plugins.matcher.ExactPatternMatcher @@ -21,7 +21,7 @@ object ScalaArtifacts import ScalaArtifacts._ -final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean) +final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean, val overrideScalaVersion: Boolean) private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ @@ -31,7 +31,21 @@ private object IvyScala checkDependencies(module, check.scalaVersion, check.configurations) if(check.filterImplicit) excludeScalaJars(module, check.configurations) + if(check.overrideScalaVersion) + overrideScalaVersion(module, check.scalaVersion) } + def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) + { + overrideVersion(module, Organization, LibraryID, version) + overrideVersion(module, Organization, CompilerID, version) + } + def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String) + { + val id = new ModuleId(org, name) + val over = new OverrideDependencyDescriptorMediator(null, version) + module.addDependencyDescriptorMediator(id, ExactPatternMatcher.INSTANCE, over) + } + /** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration]) From cb02e3c8525acc5582ce91f45612df695d63e0b6 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 18:25:54 -0400 Subject: [PATCH 0088/1030] support checksum generation and checking, enable by default --- ivy/Ivy.scala | 2 ++ ivy/IvyCache.scala | 2 +- ivy/IvyConfigurations.scala | 10 +++++----- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 261706f20..1614d7cd2 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -64,6 +64,7 @@ final class IvySbt(val configuration: IvyConfiguration) { case e: ExternalIvyConfiguration => is.load(e.file) case i: InlineIvyConfiguration => + is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach settings.setDefaultIvyUserDir IvySbt.configureCache(is, i.localOnly) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) @@ -182,6 +183,7 @@ private object IvySbt val DefaultIvyConfigFilename = "ivysettings.xml" val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" + val DefaultChecksums = Seq("sha1", "md5") def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index c46d0fce7..d7c524a84 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -86,7 +86,7 @@ object IvyCache { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), None) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index cc8bbd46f..8906018f8 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -20,12 +20,12 @@ sealed trait IvyConfiguration } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val log: Logger) extends IvyConfiguration + val checksums: Seq[String], val log: Logger) extends IvyConfiguration { type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: Logger) extends IvyConfiguration { @@ -37,14 +37,14 @@ object IvyConfiguration { /** Called to configure Ivy when inline resolvers are not specified. * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, log: Logger): IvyConfiguration = + def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration = { log.debug("Autodetecting configuration.") val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) if(defaultIvyConfigFile.canRead) new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, log) } } From 9b64b75c2fb2a1a4b664df1f2a4498cd718c3d6c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 18:31:16 -0400 Subject: [PATCH 0089/1030] Hack to avoid Ivy checking for sources/javadocs for every module --- ivy/Ivy.scala | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 1614d7cd2..f570a0761 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -21,7 +21,7 @@ import plugins.conflict.{ConflictManager, LatestConflictManager} import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser -import plugins.resolver.ChainResolver +import plugins.resolver.{ChainResolver, DependencyResolver} import util.{Message, MessageLogger} import scala.xml.NodeSeq @@ -203,9 +203,15 @@ private object IvySbt val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } - private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): ChainResolver = + private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = { - val newDefault = new ChainResolver + val newDefault = new ChainResolver { + // Technically, this should be applied to module configurations. + // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). + // It would be better to get proper support into Ivy. + override def locate(artifact: IArtifact) = + if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + } newDefault.setName(name) newDefault.setReturnFirst(true) newDefault.setCheckmodified(false) @@ -215,6 +221,14 @@ private object IvySbt } newDefault } + /** A hack to detect if the given artifact is an automatically generated request for a classifier, + * as opposed to a user-initiated declaration. It relies on Ivy prefixing classifier with m:, while sbt uses e:. + * Clearly, it would be better to have an explicit option in Ivy to control this.*/ + def hasImplicitClassifier(artifact: IArtifact): Boolean = + { + import collection.JavaConversions._ + artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") + } private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration]) { val existing = settings.getResolverNames From 0ff73e5791523eeef72419c7cd3be51f158ea8ce Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 18:32:20 -0400 Subject: [PATCH 0090/1030] inject sbt-managed Scala libraries into the UpdateReport --- ivy/IvyScala.scala | 16 +++++++++++----- ivy/ProjectResolver.scala | 3 +++ ivy/UpdateReport.scala | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index bb2f3dce7..511a3e997 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -22,6 +22,11 @@ object ScalaArtifacts import ScalaArtifacts._ final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean, val overrideScalaVersion: Boolean) +{ + // otherwise, Ivy produces the error: "impossible to get artifacts when data has not been loaded" + // which may be related to sbt's custom conflict manager, to IVY-987, or both + assert(if(overrideScalaVersion) checkExplicit else true, "Explicit Scala version checking cannot be disabled when forcing the Scala version.") +} private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ @@ -50,18 +55,19 @@ private object IvyScala * dependencies matches scalaVersion. */ private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration]) { - val configSet = configurationSet(configurations) + val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) for(dep <- module.getDependencies.toList) { val id = dep.getDependencyRevisionId - if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet.contains)) + if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet)) error("Different Scala version specified in dependency ("+ id.getRevision + ") than in project (" + scalaVersion + ").") } } - private def configurationSet(configurations: Iterable[Configuration]) = HashSet(configurations.map(_.toString).toSeq : _*) + private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet + /** Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is - * done because normally these jars are already on the classpath and cannot/should not be overridden. The version - * of Scala to use is done by setting build.scala.versions in the project definition. */ + * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use + * is done by setting scalaVersion in the project definition. */ private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) { val configurationNames = diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala index 4d1ae4f37..aee0cb772 100644 --- a/ivy/ProjectResolver.scala +++ b/ivy/ProjectResolver.scala @@ -1,3 +1,6 @@ +/* sbt -- Simple Build Tool + * Copyright 2011 Mark Harrah + */ package sbt import java.io.File diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 76befd5a0..5ecad5d17 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -101,5 +101,18 @@ object UpdateReport } new UpdateReport(newConfigurations) } + def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = + modules map { modReport => + val newArtifacts = f(configuration, modReport.module, modReport.artifacts) + new ModuleReport(modReport.module, newArtifacts, Nil) + } + new ConfigurationReport(configuration, newModules) + } + new UpdateReport(newConfigurations) + } } -} \ No newline at end of file +} From 8d797e7951716bd395d8dc8889ac145f26ff191f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 19:55:22 -0400 Subject: [PATCH 0091/1030] artifact and cross-naming fixes/improvements --- ivy/Ivy.scala | 12 ++++++------ ivy/IvyActions.scala | 21 ++++++++++++++++----- ivy/IvyInterface.scala | 6 ++++-- ivy/IvyRetrieve.scala | 4 ++-- ivy/UpdateReport.scala | 9 +++++---- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index f570a0761..888b15b1a 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -290,17 +290,17 @@ private object IvySbt case ic: InlineConfiguration => ic.copy(module = substituteCross(ic.module, cross), dependencies = substituteCrossM(ic.dependencies, cross)) case _ => m } - private def crossName(name: String, cross: String): String = + def crossName(name: String, cross: String): String = name + "_" + cross - private def substituteCross(a: Artifact, cross: String): Artifact = + def substituteCross(a: Artifact, cross: String): Artifact = a.copy(name = crossName(a.name, cross)) - private def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] = + def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] = as.map(art => substituteCross(art, cross)) - private def substituteCrossM(ms: Seq[ModuleID], cross: String): Seq[ModuleID] = + def substituteCrossM(ms: Seq[ModuleID], cross: String): Seq[ModuleID] = ms.map(m => substituteCross(m, cross)) - private def substituteCross(m: ModuleID, cross: String): ModuleID = + def substituteCross(m: ModuleID, cross: String): ModuleID = if(m.crossVersion) - m.copy(name = crossName(m.name, cross), crossVersion = false, explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + m.copy(name = crossName(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) else m diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index e3105e254..a9b835976 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -90,14 +90,24 @@ object IvyActions module.withModule(log) { case (ivy, md, default) => val resolver = ivy.getSettings.getResolver(resolverName) val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } - val as = mapArtifacts(md, artifacts) ++ ivyArtifact.toList + val is = crossIvyScala(module.moduleSettings) + val as = mapArtifacts(md, is, artifacts) ++ ivyArtifact.toList publish(md, as, resolver, overwrite = true) } } - def mapArtifacts(module: ModuleDescriptor, artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + private def crossIvyScala(moduleSettings: ModuleSettings): Option[IvyScala] = + moduleSettings match { + case i: InlineConfiguration if i.module.crossVersion => i.ivyScala + case e: EmptyConfiguration if e.module.crossVersion => e.ivyScala + case _ => None + } + def substituteCross(ivyScala: Option[IvyScala], artifacts: Seq[Artifact]): Seq[Artifact] = + ivyScala match { case None => artifacts; case Some(is) => IvySbt.substituteCrossA(artifacts, is.scalaVersion) } + def mapArtifacts(module: ModuleDescriptor, ivyScala: Option[IvyScala], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = { - val seqa = artifacts.keys.toSeq - val zipped = seqa zip IvySbt.mapArtifacts(module, seqa) + val rawa = artifacts.keys.toSeq + val seqa = substituteCross(ivyScala, rawa) + val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } } /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. @@ -109,7 +119,8 @@ object IvyActions { case Some(x) if !configuration.missingOk => throw x case _ => - val uReport = IvyRetrieve updateReport report + val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) + val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) configuration.retrieve match { case Some(rConf) => retrieve(ivy, uReport, rConf) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 79e1fc4ac..ab011eed3 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -359,12 +359,14 @@ object Artifact val base = if(i >= 0) name.substring(0, i) else name Artifact(base, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) } - def artifactName(module: ModuleID, artifact: Artifact): String = + def artifactName(scalaVersion: String, module: ModuleID, artifact: Artifact): String = { import artifact._ val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - artifact.name + "-" + module.revision + classifierStr + "." + artifact.extension + val base = if(module.crossVersion) IvySbt.crossName(artifact.name, scalaVersion) else artifact.name + base + "-" + module.revision + classifierStr + "." + artifact.extension } + def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index 328a33078..84947a5ae 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -44,8 +44,8 @@ object IvyRetrieve Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl)) } - def updateReport(report: ResolveReport): UpdateReport = - new UpdateReport(reports(report) map configurationReport) + def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = + new UpdateReport(cachedDescriptor, reports(report) map configurationReport) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport)) diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 5ecad5d17..d86a3cf9e 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -8,10 +8,11 @@ package sbt /** Provides information about dependency resolution. * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. * This means that for a given configuration, there should only be one revision for a given organization and module name. +* @param cachedDescriptor the location of the resolved module descriptor in the cache * @param configurations a sequence containing one report for each configuration resolved. * @see sbt.RichUpdateReport */ -final class UpdateReport(val configurations: Seq[ConfigurationReport]) +final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport]) { override def toString = "Update report:\n" + configurations.mkString @@ -19,7 +20,7 @@ final class UpdateReport(val configurations: Seq[ConfigurationReport]) def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(configurations map { _ retrieve f} ) + new UpdateReport(cachedDescriptor, configurations map { _ retrieve f} ) /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ def configuration(s: String) = configurations.find(_.configuration == s) @@ -99,7 +100,7 @@ object UpdateReport } new ConfigurationReport(configuration, newModules) } - new UpdateReport(newConfigurations) + new UpdateReport(report.cachedDescriptor, newConfigurations) } def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = { @@ -112,7 +113,7 @@ object UpdateReport } new ConfigurationReport(configuration, newModules) } - new UpdateReport(newConfigurations) + new UpdateReport(report.cachedDescriptor, newConfigurations) } } } From 0ad9d58c8a824713a2b5a5f52c4db06b7a18cc8b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 15 Apr 2011 20:08:35 -0400 Subject: [PATCH 0092/1030] fix handling of custom ivy home directory --- ivy/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 888b15b1a..116f95418 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -65,7 +65,7 @@ final class IvySbt(val configuration: IvyConfiguration) case e: ExternalIvyConfiguration => is.load(e.file) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") - i.paths.ivyHome foreach settings.setDefaultIvyUserDir + i.paths.ivyHome foreach is.setDefaultIvyUserDir IvySbt.configureCache(is, i.localOnly) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations) From 367ada5aca245dfdb82c5d81df567828e9dabe57 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 16 Apr 2011 11:14:45 -0400 Subject: [PATCH 0093/1030] more work on dependency management tests --- ivy/Ivy.scala | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 116f95418..57e19ec4b 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -336,7 +336,7 @@ private object IvySbt { import module._ - { if(hasInfo(dependencies)) + { if(hasInfo(module, dependencies)) NodeSeq.Empty else @@ -348,7 +348,24 @@ private object IvySbt } } - private def hasInfo(x: scala.xml.NodeSeq) = !({x} \ "info").isEmpty + private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = + { + val info = {x} \ "info" + if(!info.isEmpty) + { + def check(found: NodeSeq, expected: String, label: String) = + if(found.isEmpty) + error("Missing " + label + " in inline Ivy XML.") + else { + val str = found.text + if(str != expected) error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") + } + check(info \ "@organisation", module.organization, "organisation") + check(info \ "@module", module.name, "name") + check(info \ "@revision", module.revision, "version") + } + !info.isEmpty + } /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) From db81db25e6cf926171cd557bdc264eb7840f8b87 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 16 Apr 2011 14:40:13 -0400 Subject: [PATCH 0094/1030] work on dependency management tests --- ivy/IvyActions.scala | 2 +- ivy/IvyScala.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a9b835976..028c2dab5 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -26,7 +26,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final class MakePomConfiguration(val file: File, val configurations: Option[Iterable[Configuration]] = None, val extra: NodeSeq = NodeSeq.Empty, val process: Node => Node = n => n, val filterRepositories: MavenRepository => Boolean = _ => true) +final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: Node => Node = n => n, filterRepositories: MavenRepository => Boolean = _ => true) /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 511a3e997..c79909698 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -21,7 +21,7 @@ object ScalaArtifacts import ScalaArtifacts._ -final class IvyScala(val scalaVersion: String, val configurations: Iterable[Configuration], val checkExplicit: Boolean, val filterImplicit: Boolean, val overrideScalaVersion: Boolean) +final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) { // otherwise, Ivy produces the error: "impossible to get artifacts when data has not been loaded" // which may be related to sbt's custom conflict manager, to IVY-987, or both From b7ffd26c28a29dc25565e4ed1953e0e37100f033 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 19 Apr 2011 22:24:52 -0400 Subject: [PATCH 0095/1030] Implement optional/provided configurations, closes #8 --- ivy/IvyInterface.scala | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index ab011eed3..025d5f50f 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -290,11 +290,29 @@ object Configurations { def config(name: String) = new Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = Compile :: Runtime :: Test :: Provided :: System :: Optional :: Sources :: Javadoc :: Nil + def defaultMavenConfigurations: Seq[Configuration] = Compile :: Runtime :: Test :: Provided :: Optional :: Nil + def defaultInternal: Seq[Configuration] = CompileInternal :: RuntimeInternal :: TestInternal :: Nil + + lazy val RuntimeInternal = optionalInternal(Runtime) + lazy val TestInternal = fullInternal(Test) + lazy val IntegrationTestInternal = fullInternal(IntegrationTest) + lazy val CompileInternal = fullInternal(Compile) + + def internalMap(c: Configuration) = c match { + case Compile => CompileInternal + case Test => TestInternal + case Runtime => RuntimeInternal + case IntegrationTest => IntegrationTestInternal + case _ => c + } + + def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend(ext : _*) hide; + def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) + def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) lazy val Default = config("default") lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend(Runtime) hide; + lazy val IntegrationTest = config("it") extend(Runtime); lazy val Provided = config("provided") lazy val Javadoc = config("javadoc") lazy val Runtime = config("runtime") extend(Compile) From b470d8ad80a4bdb9d48ab259f368c03a31ec5a60 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 17 May 2011 20:09:20 -0400 Subject: [PATCH 0096/1030] build sxr, api docs and use sbinary 0.4.0 --- ivy/Ivy.scala | 5 +++-- ivy/IvyActions.scala | 4 ++-- ivy/IvyConfigurations.scala | 2 +- ivy/IvyScala.scala | 4 ++-- ivy/MakePom.scala | 14 +++++++------- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 57e19ec4b..7bc2d33fc 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -7,7 +7,8 @@ import Artifact.{defaultExtension, defaultType} import java.io.File import java.util.concurrent.Callable -import java.util.{Collection, Collections} +import java.util.{Collection, Collections => CS} +import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper @@ -465,7 +466,7 @@ private object IvySbt if(dynamic) null else { try { val l = getStrategy.findLatest(toArtifactInfo(conflicts), null).asInstanceOf[{def getNode(): IvyNode}] - if(l eq null) conflicts else Collections.singleton(l.getNode) + if(l eq null) conflicts else singleton(l.getNode) } catch { case e: LatestConflictManager.NoConflictResolvedYetException => null } } diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 028c2dab5..f2b382f22 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -4,7 +4,7 @@ package sbt import java.io.File -import scala.xml.{Node,NodeSeq} +import scala.xml.{Node => XNode,NodeSeq} import org.apache.ivy.{core, plugins, Ivy} import core.cache.DefaultRepositoryCacheManager @@ -26,7 +26,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: Node => Node = n => n, filterRepositories: MavenRepository => Boolean = _ => true) +final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true) /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 8906018f8..b151054bd 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -4,7 +4,7 @@ package sbt import java.io.File -import scala.xml.{Node, NodeSeq} +import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index c79909698..1e0406138 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -3,7 +3,7 @@ */ package sbt -import java.util.Collections +import java.util.Collections.emptyMap import scala.collection.mutable.HashSet import org.apache.ivy.{core, plugins} @@ -92,7 +92,7 @@ private object IvyScala private def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = { val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "jar", "*") - val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, Collections.emptyMap[AnyRef,AnyRef]) + val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef,AnyRef]) configurationNames.foreach(rule.addConfiguration) rule } diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index be09ecc48..7fbc42056 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -8,7 +8,7 @@ package sbt; import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} -import scala.xml.{Node, NodeSeq, PrettyPrinter, XML} +import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter, XML} import org.apache.ivy.{core, plugins, Ivy} import core.settings.IvySettings @@ -20,9 +20,9 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom { def encoding = "UTF-8" - def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: Node => Node, filterRepositories: MavenRepository => Boolean, output: File): Unit = + def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, output: File): Unit = write(process(toPom(ivy, module, configurations, extra, filterRepositories)), output) - def write(node: Node, output: File): Unit = write(toString(node), output) + def write(node: XNode, output: File): Unit = write(toString(node), output) def write(xmlString: String, output: File) { output.getParentFile.mkdirs() @@ -36,8 +36,8 @@ class MakePom finally { out.close() } } - def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean): Node = + def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) + def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean): XNode = ( 4.0.0 { makeModuleID(module) } @@ -150,9 +150,9 @@ class MakePom def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id - def mavenRepository(repo: MavenRepository): Node = + def mavenRepository(repo: MavenRepository): XNode = mavenRepository(toID(repo.name), repo.name, repo.root) - def mavenRepository(id: String, name: String, root: String): Node = + def mavenRepository(id: String, name: String, root: String): XNode = {id} {name} From 6ba42e0d2be9cbfe0ec2685cef68887af4aa844e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 19 May 2011 22:04:05 -0400 Subject: [PATCH 0097/1030] locking of boot directory can be disabled by with [boot].lock: true in boot.properties --- ivy/src/test/scala/ComponentManagerTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 537361fcb..923304fde 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp), logger)) } ) + TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), logger)) } ) } \ No newline at end of file From 65acdde031f98d0525afc98ab2f7275a850dcc3b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 25 May 2011 22:44:22 -0400 Subject: [PATCH 0098/1030] settle scala-library situation --- ivy/IvyScala.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 1e0406138..e5f946be5 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -17,6 +17,7 @@ object ScalaArtifacts val Organization = "org.scala-lang" val LibraryID = "scala-library" val CompilerID = "scala-compiler" + def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) } import ScalaArtifacts._ From 5f7a6a192ac412bbdceaeaa16b3f62438ab00fe4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 29 May 2011 19:17:31 -0400 Subject: [PATCH 0099/1030] drop custom conflict manager to fix IvyNode-related exception --- ivy/Ivy.scala | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 7bc2d33fc..e5ab87aa9 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -18,7 +18,7 @@ import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescrip import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.IvyNode import core.settings.IvySettings -import plugins.conflict.{ConflictManager, LatestConflictManager} +import plugins.conflict.{ConflictManager, LatestCompatibleConflictManager, LatestConflictManager} import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser @@ -60,7 +60,6 @@ final class IvySbt(val configuration: IvyConfiguration) { val is = new IvySettings is.setBaseDir(baseDirectory) - is.setDefaultConflictManager(IvySbt.latestNoForce(is)) configuration match { case e: ExternalIvyConfiguration => is.load(e.file) @@ -441,36 +440,4 @@ private object IvySbt case Some(confs) => confs.map(_.name).toList.toArray case None => module.getPublicConfigurationsNames } - - // same as Ivy's builtin latest-revision manager except that it ignores the force setting, - // which seems to be added to dependencies read from poms (perhaps only in certain circumstances) - // causing revisions of indirect dependencies other than latest to be selected - def latestNoForce(settings: IvySettings): ConflictManager = - { - import collection.JavaConversions._ - - new LatestConflictManager("latest-revision-no-force", new LatestRevisionStrategy) - { - setSettings(settings) - - override def resolveConflicts(parent: IvyNode, conflicts: Collection[_]): Collection[_] = - if(conflicts.size < 2) - conflicts - else - resolveMultiple(parent, conflicts.asInstanceOf[Collection[IvyNode]]).asInstanceOf[Collection[_]] - - def resolveMultiple(parent: IvyNode, conflicts: Collection[IvyNode]): Collection[IvyNode] = - { - val matcher = settings.getVersionMatcher - val dynamic = conflicts.exists { node => matcher.isDynamic(node.getResolvedId) } - if(dynamic) null else { - try { - val l = getStrategy.findLatest(toArtifactInfo(conflicts), null).asInstanceOf[{def getNode(): IvyNode}] - if(l eq null) conflicts else singleton(l.getNode) - } - catch { case e: LatestConflictManager.NoConflictResolvedYetException => null } - } - } - } - } } From 2bf2fdf98f32df95fcd9b80d98f4d516bf308468 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 30 May 2011 22:10:00 -0400 Subject: [PATCH 0100/1030] Include dependency ID in explicit Scala version checking error message --- ivy/IvyScala.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index e5f946be5..62230a1c6 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -61,7 +61,7 @@ private object IvyScala { val id = dep.getDependencyRevisionId if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet)) - error("Different Scala version specified in dependency ("+ id.getRevision + ") than in project (" + scalaVersion + ").") + error("Version specified for dependency " + id + " differs from Scala version in project (" + scalaVersion + ").") } } private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet From 806dc7a638d1b242a4f31ec19f9139b7e9ae70a2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 2 Jun 2011 18:35:25 -0400 Subject: [PATCH 0101/1030] use artifact patterns as ivy pattern defaults --- ivy/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 025d5f50f..578ad2a59 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -58,7 +58,7 @@ object Patterns implicit def defaultPatterns: Patterns = Resolver.defaultPatterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) - def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(Nil, artifactPatterns, isMavenCompatible) + def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) } object RepositoryHelpers From ea07c941fb4ab5758500efa3ab2cb8c39ddf0619 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 10 Jun 2011 07:48:53 -0400 Subject: [PATCH 0102/1030] remove code obsolete after 0.7.1 --- ivy/ComponentManager.scala | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index bb1047b3d..16ff083da 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -87,14 +87,5 @@ object ComponentManager lazy val stampedVersion = version + "_" + timestamp import java.net.URL - private def versionResource: URL = - { - import java.util.Collections.list - // could be just: - // getClass.getResource("/xsbt.version.properties") - // but the launcher up until 0.7.1 contained a stale xsbt.version.properties. - // post-0.7.1, only xsbti.jar contains xsbt.version.properties - // for the transition, we take the last one, which is the one we want because of the order resources are searched - list(getClass.getClassLoader.getResources("xsbt.version.properties")).toArray(new Array[URL](0)).last - } + private def versionResource: URL = getClass.getResource("/xsbt.version.properties") } \ No newline at end of file From dcc74da6658d55efef1002989fb668f86e38f013 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 10 Jun 2011 07:48:53 -0400 Subject: [PATCH 0103/1030] make provided intransitive, fixes #42 --- ivy/IvyInterface.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 578ad2a59..58e44b89f 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -312,11 +312,11 @@ object Configurations lazy val Default = config("default") lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend(Runtime); - lazy val Provided = config("provided") + lazy val IntegrationTest = config("it") extend(Runtime) + lazy val Provided = config("provided") intransitive ; lazy val Javadoc = config("javadoc") lazy val Runtime = config("runtime") extend(Compile) - lazy val Test = config("test") extend(Runtime); + lazy val Test = config("test") extend(Runtime) lazy val Sources = config("sources") lazy val System = config("system") lazy val Optional = config("optional") From 69afc20bf1267940614b006a78dd8cc00263ea5c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 10 Jun 2011 07:48:53 -0400 Subject: [PATCH 0104/1030] convenience method on UpdateReport for extracting contents as sequence of tuples --- ivy/UpdateReport.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index d86a3cf9e..47a8dd5de 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -115,5 +115,9 @@ object UpdateReport } new UpdateReport(report.cachedDescriptor, newConfigurations) } + + def toSeq: Seq[(String, ModuleID, Artifact, File)] = + for(confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield + (confReport.configuration, modReport.module, artifact, file) } } From 51b8d3835626c5b965de0648024294337f331a03 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 11 Jun 2011 20:09:15 -0400 Subject: [PATCH 0105/1030] define type for artifacts looked up by update-classifiers, fixes #49 --- ivy/IvyActions.scala | 2 +- ivy/IvyInterface.scala | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index f2b382f22..a53179575 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -142,7 +142,7 @@ object IvyActions { assert(!classifiers.isEmpty, "classifiers cannot be empty") val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) } - val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact(m.name, c) }) } + val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact.classified(m.name, c) }) } val base = id.copy(name = id.name + classifiers.mkString("$","_","")) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) update(module, configuration, log) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 58e44b89f..66a87d1b3 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -359,8 +359,10 @@ object Artifact Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) val defaultExtension = "jar" val defaultType = "jar" - def sources(name: String) = Artifact(name, "src", "jar", "sources") - def javadoc(name: String) = Artifact(name, "doc", "jar", "javadoc") + def sources(name: String) = classified(name, SourceClassifier) + def javadoc(name: String) = classified(name, DocClassifier) + val DocClassifier = "javadoc" + val SourceClassifier = "sources" def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = { @@ -385,6 +387,9 @@ object Artifact base + "-" + module.revision + classifierStr + "." + artifact.extension } def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" + + val classifierTypeMap = Map("sources" -> "src", "javadoc" -> "doc") + def classified(name: String, classifier: String): Artifact = Artifact(name, classifierTypeMap.getOrElse(classifier, defaultType), defaultExtension, classifier) } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration From 1b0359fff99c932f6d160dbb1b419ba8b28824d5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Jun 2011 21:32:51 -0400 Subject: [PATCH 0106/1030] add pomAllRepositories option to include module configuration resolvers in pom. closes #39 --- ivy/IvyActions.scala | 6 +++--- ivy/MakePom.scala | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a53179575..5149fb3cf 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -26,7 +26,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true) +final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. @@ -63,9 +63,9 @@ object IvyActions /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { - import configuration.{configurations, extra, file, filterRepositories, process} + import configuration.{allRepositories, configurations, extra, file, filterRepositories, process} module.withModule(log) { (ivy, md, default) => - (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, file) + (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, allRepositories, file) log.info("Wrote " + file.getAbsolutePath) } } diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 7fbc42056..9a20e11e5 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -20,8 +20,8 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom { def encoding = "UTF-8" - def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, output: File): Unit = - write(process(toPom(ivy, module, configurations, extra, filterRepositories)), output) + def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + write(process(toPom(ivy, module, configurations, extra, filterRepositories, allRepositories)), output) def write(node: XNode, output: File): Unit = write(toString(node), output) def write(xmlString: String, output: File) { @@ -37,13 +37,13 @@ class MakePom } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean): XNode = + def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = ( 4.0.0 { makeModuleID(module) } { extra } { makeDependencies(module, configurations) } - { makeRepositories(ivy.getSettings, filterRepositories) } + { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) def makeModuleID(module: ModuleDescriptor): NodeSeq = @@ -126,10 +126,10 @@ class MakePom def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) - def makeRepositories(settings: IvySettings, filterRepositories: MavenRepository => Boolean) = + def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = { class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) - val repositories = resolvers(settings.getDefaultResolver) + val repositories = if(includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => @@ -139,6 +139,7 @@ class MakePom val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) if(repositoryElements.isEmpty) repositoryElements else {repositoryElements} } + def allResolvers(settings: IvySettings): Seq[DependencyResolver] = flatten(castResolvers(settings.getResolvers)).distinct def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if(rs eq null) Nil else rs.flatMap(resolvers) def resolvers(r: DependencyResolver): Seq[DependencyResolver] = r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } From 28f76228656b94dfcbde4aa1ba005c48c70a07d8 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 12 Jun 2011 21:32:52 -0400 Subject: [PATCH 0107/1030] Define 'type' for builtin artifacts based on classifier --- ivy/IvyInterface.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 66a87d1b3..6d4ccacb9 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -389,7 +389,8 @@ object Artifact def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" val classifierTypeMap = Map("sources" -> "src", "javadoc" -> "doc") - def classified(name: String, classifier: String): Artifact = Artifact(name, classifierTypeMap.getOrElse(classifier, defaultType), defaultExtension, classifier) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, defaultType) + def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), defaultExtension, classifier) } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration From 68719cf9d79df74e595b57eb74d58eaaa86a57e7 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 14 Jun 2011 19:32:36 -0400 Subject: [PATCH 0108/1030] cleaning up artifact configurations --- ivy/IvyInterface.scala | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 6d4ccacb9..2d0a3e54f 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -290,8 +290,9 @@ object Configurations { def config(name: String) = new Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = Compile :: Runtime :: Test :: Provided :: Optional :: Nil - def defaultInternal: Seq[Configuration] = CompileInternal :: RuntimeInternal :: TestInternal :: Nil + def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) + def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) + def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) @@ -314,12 +315,13 @@ object Configurations lazy val Compile = config("compile") lazy val IntegrationTest = config("it") extend(Runtime) lazy val Provided = config("provided") intransitive ; - lazy val Javadoc = config("javadoc") + lazy val Docs = config("docs") lazy val Runtime = config("runtime") extend(Compile) lazy val Test = config("test") extend(Runtime) lazy val Sources = config("sources") lazy val System = config("system") lazy val Optional = config("optional") + lazy val Pom = config("pom") lazy val CompilerPlugin = config("plugin") hide @@ -347,6 +349,9 @@ final case class Artifact(name: String, `type`: String, extension: String, class { def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) } + + import Configurations.{config, Docs, Optional, Pom, Sources} + object Artifact { def apply(name: String): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None) @@ -357,12 +362,18 @@ object Artifact def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) + val defaultExtension = "jar" val defaultType = "jar" + def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) + def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) + val DocClassifier = "javadoc" val SourceClassifier = "sources" + val PomType = "pom" + def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = { @@ -388,9 +399,12 @@ object Artifact } def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" - val classifierTypeMap = Map("sources" -> "src", "javadoc" -> "doc") + val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) + val classifierTypeMap = Map(SourceClassifier -> "src", DocClassifier -> "doc") + def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, defaultType) - def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), defaultExtension, classifier) + def classified(name: String, classifier: String): Artifact = + Artifact(name, classifierType(classifier), defaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration From f2fbe273751389e834bf0b36d2bc9a5508c700cc Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 15 Jun 2011 19:09:31 -0400 Subject: [PATCH 0109/1030] fixes #55 updated dependency-management/sources test covers this --- ivy/IvyActions.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 5149fb3cf..0e29ba740 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -131,7 +131,7 @@ object IvyActions def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = { - val base = id.copy(name = id.name + "$" + label) + val base = restrictedCopy(id).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) transitive(ivySbt, id, report, classifiers, c, ivyScala, log) @@ -141,13 +141,14 @@ object IvyActions def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = { assert(!classifiers.isEmpty, "classifiers cannot be empty") - val baseModules = modules map { m => ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) } + val baseModules = modules map restrictedCopy val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact.classified(m.name, c) }) } - val base = id.copy(name = id.name + classifiers.mkString("$","_","")) + val base = restrictedCopy(id).copy(name = id.name + classifiers.mkString("$","_","")) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) update(module, configuration, log) } - private def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = + private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) + private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions resolveOptions.setLog(ivyLogLevel(logging)) From dbd7a3eacb3dc1ed21366940aa0c44cb9c015965 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 17 Jun 2011 21:56:52 -0400 Subject: [PATCH 0110/1030] inject internal configurations into pom ModuleDescriptor. fixes #59 --- ivy/Ivy.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index e5ab87aa9..701b8fb1d 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -142,7 +142,7 @@ final class IvySbt(val configuration: IvyConfiguration) { val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) mod.setLastModified(System.currentTimeMillis) - configurations.foreach(config => mod.addConfiguration(IvySbt.toIvyConfiguration(config))) + IvySbt.addConfigurations(mod, configurations) IvySbt.addArtifacts(mod, module.explicitArtifacts) mod } @@ -151,7 +151,9 @@ final class IvySbt(val configuration: IvyConfiguration) private def readPom(pomFile: File, validate: Boolean) = { val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), validate) - (IvySbt.toDefaultModuleDescriptor(md), "compile") + val dmd = IvySbt.toDefaultModuleDescriptor(md) + IvySbt.addConfigurations(dmd, Configurations.defaultInternal) + (dmd, "compile") } /** Parses the given Ivy file 'ivyFile'.*/ private def readIvyFile(ivyFile: File, validate: Boolean) = @@ -408,6 +410,8 @@ private object IvySbt def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) moduleID.addArtifact(c, art) + def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = + configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = { From bbf05dc770b981cbf1fcfc07af7024a0cab6e361 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 18 Jun 2011 20:17:50 -0400 Subject: [PATCH 0111/1030] fixes issue with inter-project resolution when project delegates are defined --- ivy/IvyInterface.scala | 1 + ivy/ProjectResolver.scala | 1 + 2 files changed, 2 insertions(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 2d0a3e54f..3b802fc20 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -41,6 +41,7 @@ sealed trait Resolver final class RawRepository(val resolver: DependencyResolver) extends Resolver { def name = resolver.getName + override def toString = "Raw(" + resolver.toString + ")" } sealed case class MavenRepository(name: String, root: String) extends Resolver { diff --git a/ivy/ProjectResolver.scala b/ivy/ProjectResolver.scala index aee0cb772..4c2d046db 100644 --- a/ivy/ProjectResolver.scala +++ b/ivy/ProjectResolver.scala @@ -23,6 +23,7 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] { def getName = name def setName(name: String) = error("Setting name not supported by ProjectResolver") + override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = { From 07ba2bcaa2b2505086132da5004de31fff071710 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 19 Jun 2011 21:01:29 -0400 Subject: [PATCH 0112/1030] cache failing classifiers. fixes #46 --- ivy/IvyActions.scala | 32 ++++++++++++++++++++------ ivy/UpdateReport.scala | 52 +++++++++++++++++++++++------------------- 2 files changed, 53 insertions(+), 31 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 0e29ba740..eed985a03 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -27,6 +27,8 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) + // exclude is a map on a restricted ModuleID +final case class GetClassifiersConfiguration(id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. @@ -129,24 +131,40 @@ object IvyActions } } - def transitiveScratch(ivySbt: IvySbt, id: ModuleID, label: String, deps: Seq[ModuleID], classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = + def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { + import config.{configuration => c, id, ivyScala, modules => deps} val base = restrictedCopy(id).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) - transitive(ivySbt, id, report, classifiers, c, ivyScala, log) + val newConfig = config.copy(modules = report.allModules) + updateClassifiers(ivySbt, newConfig, log) } - def transitive(ivySbt: IvySbt, module: ModuleID, report: UpdateReport, classifiers: Seq[String], c: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = - updateClassifiers(ivySbt, module, report.allModules, classifiers, new UpdateConfiguration(c.retrieve, true, c.logging), ivyScala, log) - def updateClassifiers(ivySbt: IvySbt, id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], log: Logger): UpdateReport = + def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { + import config.{configuration => c, _} assert(!classifiers.isEmpty, "classifiers cannot be empty") val baseModules = modules map restrictedCopy - val deps = baseModules.distinct map { m => m.copy(explicitArtifacts = classifiers map { c => Artifact.classified(m.name, c) }) } + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) val base = restrictedCopy(id).copy(name = id.name + classifiers.mkString("$","_","")) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) - update(module, configuration, log) + val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) + update(module, upConf, log) } + def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = + { + val excluded = exclude getOrElse(m, Set.empty) + val included = classifiers filterNot excluded + if(included.isEmpty) None else Some(m.copy(explicitArtifacts = classifiedArtifacts(m.name, included) )) + } + def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = + report.addMissing { id => classifiedArtifacts(id.name, classifiers filter exclude.getOrElse(id, Set.empty[String])) } + def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = + classifiers map { c => Artifact.classified(name, c) } + + def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = + report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } + private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 47a8dd5de..63e99f8ff 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -88,36 +88,40 @@ object UpdateReport /** Constructs a new report that only contains files matching the specified filter.*/ def filter(f: DependencyFilter): UpdateReport = - { - val newConfigurations = report.configurations.map { confReport => - import confReport._ - val newModules = - modules map { modReport => - import modReport._ - val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } - val newMissing = missingArtifacts filter { art => f(configuration, module, art) } - new ModuleReport(module, newArtifacts, newMissing) - } - new ConfigurationReport(configuration, newModules) + moduleReportMap { (configuration, modReport) => + import modReport._ + val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } + val newMissing = missingArtifacts filter { art => f(configuration, module, art) } + new ModuleReport(module, newArtifacts, newMissing) } - new UpdateReport(report.cachedDescriptor, newConfigurations) - } def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = - { - val newConfigurations = report.configurations.map { confReport => - import confReport._ - val newModules = - modules map { modReport => - val newArtifacts = f(configuration, modReport.module, modReport.artifacts) - new ModuleReport(modReport.module, newArtifacts, Nil) - } - new ConfigurationReport(configuration, newModules) + moduleReportMap { (configuration, modReport) => + val newArtifacts = f(configuration, modReport.module, modReport.artifacts) + new ModuleReport(modReport.module, newArtifacts, Nil) } - new UpdateReport(report.cachedDescriptor, newConfigurations) - } def toSeq: Seq[(String, ModuleID, Artifact, File)] = for(confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) + + def allMissing: Seq[(String, ModuleID, Artifact)] = + for(confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield + (confReport.configuration, modReport.module, artifact) + + def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = + moduleReportMap { (configuration, modReport) => + import modReport._ + new ModuleReport(module, artifacts, (missingArtifacts ++ f(module)).distinct) + } + + def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = modules map { modReport => f(configuration, modReport) } + new ConfigurationReport(configuration, newModules) + } + new UpdateReport(report.cachedDescriptor, newConfigurations) + } } } From dcd84a48ab8c778695cd40c69fc72f3a99d76aab Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 20 Jun 2011 15:25:23 -0400 Subject: [PATCH 0113/1030] add ChainedResolver(name: String, resolvers: Seq[Resolver]), closes #63 --- ivy/ConvertResolver.scala | 5 +++-- ivy/Ivy.scala | 10 +++++----- ivy/IvyInterface.scala | 1 + 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index eec6a5121..6c479a619 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -6,13 +6,13 @@ package sbt import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId import core.settings.IvySettings -import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} +import plugins.resolver.{DependencyResolver, IBiblioResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} private object ConvertResolver { /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver)(implicit settings: IvySettings) = + def apply(r: Resolver)(implicit settings: IvySettings, log: Logger) = { r match { @@ -61,6 +61,7 @@ private object ConvertResolver initializePatterns(resolver, repo.patterns) resolver } + case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) case repo: RawRepository => repo.resolver } } diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 701b8fb1d..cf15bf44a 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -68,7 +68,7 @@ final class IvySbt(val configuration: IvyConfiguration) i.paths.ivyHome foreach is.setDefaultIvyUserDir IvySbt.configureCache(is, i.localOnly) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) - IvySbt.setModuleConfigurations(is, i.moduleConfigurations) + IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) } is } @@ -205,7 +205,7 @@ private object IvySbt val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } - private def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = + def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = { val newDefault = new ChainResolver { // Technically, this should be applied to module configurations. @@ -219,7 +219,7 @@ private object IvySbt newDefault.setCheckmodified(false) for(sbtResolver <- resolvers) { log.debug("\t" + sbtResolver) - newDefault.add(ConvertResolver(sbtResolver)(settings)) + newDefault.add(ConvertResolver(sbtResolver)(settings, log)) } newDefault } @@ -231,7 +231,7 @@ private object IvySbt import collection.JavaConversions._ artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") } - private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration]) + private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger) { val existing = settings.getResolverNames for(moduleConf <- moduleConfigurations) @@ -240,7 +240,7 @@ private object IvySbt import IvyPatternHelper._ import PatternMatcher._ if(!existing.contains(resolver.name)) - settings.addResolver(ConvertResolver(resolver)(settings)) + settings.addResolver(ConvertResolver(resolver)(settings, log)) val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 3b802fc20..7998b573e 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -43,6 +43,7 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver def name = resolver.getName override def toString = "Raw(" + resolver.toString + ")" } +sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver sealed case class MavenRepository(name: String, root: String) extends Resolver { override def toString = name + ": " + root From c2ea5746a609a0a8f57d68cfb8bb31978f5d20a5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 22 Jun 2011 19:17:10 -0400 Subject: [PATCH 0114/1030] use ivyConfigurations for interDependencies instead of scope configurations --- ivy/IvyInterface.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 7998b573e..6d9958a4b 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -295,6 +295,7 @@ object Configurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) + def names(cs: Seq[Configuration]) = cs.map(_.name) lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) From f4dd9941d60caa31aa8d3088e2f7f436bc43128a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 26 Jun 2011 12:27:06 -0400 Subject: [PATCH 0115/1030] add methods for directly working with credentials --- ivy/Credentials.scala | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index a2a3c9d2b..a097596ed 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -18,6 +18,22 @@ object Credentials CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) /** Load credentials from the given file into Ivy's credentials cache.*/ def add(path: File, log: Logger): Unit = + loadCredentials(path) match + { + case Left(err) => log.warn(err) + case Right(dc) => add(dc.realm, dc.host, dc.userName, dc.passwd) + } + + def forHost(sc: Seq[Credentials], host: String) = allDirect(sc) find { _.host == host } + def allDirect(sc: Seq[Credentials]): Seq[DirectCredentials] = sc map toDirect + def toDirect(c: Credentials): DirectCredentials = c match { + case dc: DirectCredentials => dc + case fc: FileCredentials => loadCredentials(fc.path) match { + case Left(err) => error(err) + case Right(dc) => dc + } + } + def loadCredentials(path: File): Either[String, DirectCredentials] = if(path.exists) { val properties = read(path) @@ -25,12 +41,12 @@ object Credentials List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match { - case (Nil, List(realm, host, user, pass)) => add(realm, host, user, pass) - case (errors, _) => log.warn(errors.mkString("\n")) + case (Nil, List(realm, host, user, pass)) => Right( new DirectCredentials(realm, host, user, pass) ) + case (errors, _) => Left(errors.mkString("\n")) } } else - log.warn("Credentials file " + path + " does not exist") + Left("Credentials file " + path + " does not exist") def register(cs: Seq[Credentials], log: Logger): Unit = cs foreach { From f2c5c62f1d463b59ffa5fb62c497865832add502 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 3 Jul 2011 15:44:53 -0400 Subject: [PATCH 0116/1030] return Provided to be transitive, ref #42 --- ivy/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 6d9958a4b..040728568 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -317,7 +317,7 @@ object Configurations lazy val Default = config("default") lazy val Compile = config("compile") lazy val IntegrationTest = config("it") extend(Runtime) - lazy val Provided = config("provided") intransitive ; + lazy val Provided = config("provided") ; lazy val Docs = config("docs") lazy val Runtime = config("runtime") extend(Compile) lazy val Test = config("test") extend(Runtime) From 3c37eaa1610e3808aec3a7f8237195d7684d96bf Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 6 Jul 2011 07:30:47 -0400 Subject: [PATCH 0117/1030] move dependency mapping to IvySbt#Module --- ivy/Ivy.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index cf15bf44a..bd40d92d3 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -108,6 +108,11 @@ final class IvySbt(val configuration: IvyConfiguration) withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_,md,_) => md) + def dependencyMapping(log: Logger): (ModuleRevisionId, ModuleDescriptor) = + { + val md = moduleDescriptor(log) + (md.getModuleRevisionId, md) + } def defaultConfig(log: Logger): String = withModule(log)( (_,_,dc) => dc) // these should only be referenced by withModule because lazy vals synchronize on this object // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock From 98b60623af462a69dae7616a1b73492fcf5c101c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 8 Jul 2011 21:54:59 -0400 Subject: [PATCH 0118/1030] Include evicted modules and statistics in UpdateReport --- ivy/IvyRetrieve.scala | 10 +++++++--- ivy/UpdateReport.scala | 20 ++++++++++++-------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index 84947a5ae..da673db0f 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -34,6 +34,9 @@ object IvyRetrieve } new ModuleReport(mid, resolved.toSeq, missing.toSeq) } + + def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = + confReport.getEvictedNodes.map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) @@ -45,8 +48,9 @@ object IvyRetrieve } def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = - new UpdateReport(cachedDescriptor, reports(report) map configurationReport) - + new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report)) + def updateStats(report: ResolveReport): UpdateStats = + new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport)) + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) } diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 63e99f8ff..28145f7e5 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -12,15 +12,15 @@ package sbt * @param configurations a sequence containing one report for each configuration resolved. * @see sbt.RichUpdateReport */ -final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport]) +final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats) { - override def toString = "Update report:\n" + configurations.mkString + override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString /** All resolved modules in all configurations. */ def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(cachedDescriptor, configurations map { _ retrieve f} ) + new UpdateReport(cachedDescriptor, configurations map { _ retrieve f}, stats ) /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ def configuration(s: String) = configurations.find(_.configuration == s) @@ -33,9 +33,9 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con * @param configuration the configuration this report is for. * @param modules a seqeuence containing one report for each module resolved for this configuration. */ -final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport]) +final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport], val evicted: Seq[ModuleID]) { - override def toString = "\t" + configuration + ":\n" + modules.mkString + override def toString = "\t" + configuration + ":\n" + modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString /** All resolved modules for this configuration. * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. @@ -43,7 +43,7 @@ final class ConfigurationReport(val configuration: String, val modules: Seq[Modu def allModules: Seq[ModuleID] = modules.map(_.module) def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }) + new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }, evicted) } /** Provides information about the resolution of a module. @@ -119,9 +119,13 @@ object UpdateReport val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules) + new ConfigurationReport(configuration, newModules, evicted) } - new UpdateReport(report.cachedDescriptor, newConfigurations) + new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats) } } } +final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long) +{ + override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") +} \ No newline at end of file From 82f025bdeca4fc3aad24c814d881634960dcd486 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 8 Jul 2011 21:54:59 -0400 Subject: [PATCH 0119/1030] warn when there is an sbt version conflict. fixes #80 --- ivy/ConflictWarning.scala | 20 ++++++++++++++++++++ ivy/DependencyFilter.scala | 1 + ivy/IvyActions.scala | 12 ++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 ivy/ConflictWarning.scala diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala new file mode 100644 index 000000000..5d642f04f --- /dev/null +++ b/ivy/ConflictWarning.scala @@ -0,0 +1,20 @@ +package sbt + + import DependencyFilter._ + +final case class ConflictWarning(filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) +object ConflictWarning +{ + def default: ConflictWarning = ConflictWarning( moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) + + def apply(config: ConflictWarning, report: UpdateReport, log: Logger) + { + val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) + if(!conflicts.isEmpty) + log.log(config.level, "Potentially incompatible versions specified:") + for( (label, versions) <- conflicts ) + log.log(config.level, " " + label + ": " + versions.mkString(", ")) + if(config.failOnConflict && !conflicts.isEmpty) + error("Conflicts in " + conflicts.map(_._1).mkString ) + } +} diff --git a/ivy/DependencyFilter.scala b/ivy/DependencyFilter.scala index 1773525c6..e31cd4e24 100644 --- a/ivy/DependencyFilter.scala +++ b/ivy/DependencyFilter.scala @@ -32,6 +32,7 @@ object DependencyFilter extends DependencyFilterExtra implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) } implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) } + implicit def subDepFilterToFn[Arg](f: SubDepFilter[Arg, _]): Arg => Boolean = f apply _ } trait DependencyFilter { diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index eed985a03..ad0f4cdca 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -131,6 +131,18 @@ object IvyActions } } + def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = + report.configurations.flatMap { confReport => + val evicted = confReport.evicted.filter(moduleFilter) + val evictedSet = evicted.map( m => (m.organization, m.name) ).toSet + val conflicted = confReport.allModules.filter( mod => evictedSet( (mod.organization, mod.name) ) ) + grouped(grouping)(conflicted ++ evicted) + } toMap; + + def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = + mods groupBy(grouping) mapValues(_.map(_.revision).toSet) + + def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { import config.{configuration => c, id, ivyScala, modules => deps} From 92201e4ab3daaeeaf0d8296cfdda94c8602ec12e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 12 Jul 2011 07:47:31 -0400 Subject: [PATCH 0120/1030] use \n for make-pom because PrettyPrinter hard codes it. fixes #95 --- ivy/MakePom.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 9a20e11e5..432a83ba6 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -22,15 +22,15 @@ class MakePom def encoding = "UTF-8" def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = write(process(toPom(ivy, module, configurations, extra, filterRepositories, allRepositories)), output) - def write(node: XNode, output: File): Unit = write(toString(node), output) - def write(xmlString: String, output: File) + // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n + def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") + def write(xmlString: String, output: File, newline: String) { output.getParentFile.mkdirs() val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding)) try { - out.write("") - out.newLine() + out.write("" + newline) out.write(xmlString) } finally { out.close() } From 3631d6a3a94379245b073e8ccad8fc449107fb8d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 13 Jul 2011 18:08:29 -0400 Subject: [PATCH 0121/1030] cleanup --- ivy/ConflictWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index 5d642f04f..f61f0f51f 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -5,7 +5,7 @@ package sbt final case class ConflictWarning(filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) object ConflictWarning { - def default: ConflictWarning = ConflictWarning( moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) + lazy val default: ConflictWarning = ConflictWarning( moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { From eedc93c423808d8762bcf8d752201cfcf0afbc6d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 16 Jul 2011 12:53:29 -0400 Subject: [PATCH 0122/1030] provide better indication of cause of incompatible sbt versions --- ivy/ConflictWarning.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index f61f0f51f..758ebb07a 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -2,16 +2,16 @@ package sbt import DependencyFilter._ -final case class ConflictWarning(filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) +final case class ConflictWarning(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) object ConflictWarning { - lazy val default: ConflictWarning = ConflictWarning( moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) + def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) - log.log(config.level, "Potentially incompatible versions specified:") + log.log(config.level, "Potentially incompatible versions specified by " + config.label + ":") for( (label, versions) <- conflicts ) log.log(config.level, " " + label + ": " + versions.mkString(", ")) if(config.failOnConflict && !conflicts.isEmpty) From c766412885262a51e04d63779d47a91351c8de96 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 17 Jul 2011 11:26:27 -0400 Subject: [PATCH 0123/1030] use 'scalaVersion in update' for cross building, IvyScala.substituteCross for generality. fixes #86 also, 'scalaVersion in artifactName` for the version to append to artifacts --- ivy/Ivy.scala | 10 ++++------ ivy/IvyScala.scala | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index bd40d92d3..c3ece3247 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -290,11 +290,11 @@ private object IvySbt } private def substituteCross(m: ModuleSettings): ModuleSettings = - m.ivyScala match { case None => m; case Some(is) => substituteCross(m, is.scalaVersion) } - private def substituteCross(m: ModuleSettings, cross: String): ModuleSettings = + m.ivyScala match { case None => m; case Some(is) => substituteCross(m, is.substituteCross) } + private def substituteCross(m: ModuleSettings, sub: ModuleID => ModuleID): ModuleSettings = m match { - case ec: EmptyConfiguration => ec.copy(module = substituteCross(ec.module, cross)) - case ic: InlineConfiguration => ic.copy(module = substituteCross(ic.module, cross), dependencies = substituteCrossM(ic.dependencies, cross)) + case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) + case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub) case _ => m } def crossName(name: String, cross: String): String = @@ -303,8 +303,6 @@ private object IvySbt a.copy(name = crossName(a.name, cross)) def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] = as.map(art => substituteCross(art, cross)) - def substituteCrossM(ms: Seq[ModuleID], cross: String): Seq[ModuleID] = - ms.map(m => substituteCross(m, cross)) def substituteCross(m: ModuleID, cross: String): ModuleID = if(m.crossVersion) m.copy(name = crossName(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 62230a1c6..0760a7277 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -22,10 +22,10 @@ object ScalaArtifacts import ScalaArtifacts._ -final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) +final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, substituteCross: ModuleID => ModuleID) { // otherwise, Ivy produces the error: "impossible to get artifacts when data has not been loaded" - // which may be related to sbt's custom conflict manager, to IVY-987, or both + // which may be related to sbt's custom conflict manager (now removed), to IVY-987, or both assert(if(overrideScalaVersion) checkExplicit else true, "Explicit Scala version checking cannot be disabled when forcing the Scala version.") } private object IvyScala From 987dc0f3ba17b7a20e90b809c87ee9b02f976777 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 19 Jul 2011 21:29:05 -0400 Subject: [PATCH 0124/1030] use launcher repositories for update-sbt-classifiers. fixes #88 --- ivy/IvyInterface.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 040728568..fdf0cd7dd 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -274,6 +274,7 @@ object Resolver def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]" + def mavenLocal = MavenRepository("Maven2 Local", (new File(Path.userHome, ".m2/repository/")).toURI.toURL.toExternalForm) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = From b1229349366d4c7b1cb4aaec99e988acfb889d80 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 21 Jul 2011 22:03:56 -0400 Subject: [PATCH 0125/1030] support configuring checksums differently for publish, publish-local, update, and update-sbt-classifiers. fixes #115 --- ivy/IvyActions.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index ad0f4cdca..0d62ea547 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -19,10 +19,10 @@ import core.report.{ArtifactDownloadReport,ResolveReport} import core.resolve.ResolveOptions import core.retrieve.RetrieveOptions import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} -import plugins.resolver.DependencyResolver +import plugins.resolver.{BasicResolver, DependencyResolver} final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) -final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val logging: UpdateLogging.Value) +final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value) final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) @@ -94,9 +94,18 @@ object IvyActions val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } val is = crossIvyScala(module.moduleSettings) val as = mapArtifacts(md, is, artifacts) ++ ivyArtifact.toList - publish(md, as, resolver, overwrite = true) + withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = true) } } } + private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T = + resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act } + private[this] def withChecksums[T](resolver: BasicResolver, checksums: Seq[String])(act: => T): T = + { + val previous = resolver.getChecksumAlgorithms + resolver.setChecksums(checksums mkString ",") + try { act } + finally { resolver.setChecksums(previous mkString ",") } + } private def crossIvyScala(moduleSettings: ModuleSettings): Option[IvyScala] = moduleSettings match { case i: InlineConfiguration if i.module.crossVersion => i.ivyScala From 7bb3cddf3cdbf18b5cc2b1ab31109f86abe14550 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 23 Jul 2011 23:07:54 -0400 Subject: [PATCH 0126/1030] drop problem summary for update-seems entirely redundant --- ivy/IvyLogger.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/IvyLogger.scala b/ivy/IvyLogger.scala index b06d477a2..1d68e7e3a 100644 --- a/ivy/IvyLogger.scala +++ b/ivy/IvyLogger.scala @@ -35,7 +35,7 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger def getErrors = emptyList def clearProblems = () - def sumupProblems = () + def sumupProblems = clearProblems() def progress = () def endProgress = () @@ -47,6 +47,7 @@ private final class SbtMessageLoggerEngine extends MessageLoggerEngine { /** This is a hack to filter error messages about 'unknown resolver ...'. */ override def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) super.error(msg) + override def sumupProblems = clearProblems() } private object SbtIvyLogger { From 703c1e841ae5a82f6dd61ddbbbaf63bdfb1815ab Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 23 Jul 2011 23:07:54 -0400 Subject: [PATCH 0127/1030] preserve extraAttributes in a couple of places --- ivy/IvyActions.scala | 2 +- ivy/IvyRetrieve.scala | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 0d62ea547..0b2f26305 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -186,7 +186,7 @@ object IvyActions def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } - private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion) + private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index da673db0f..c36703c2f 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -39,7 +39,11 @@ object IvyRetrieve confReport.getEvictedNodes.map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = - ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) + { + import collection.JavaConverters._ + val extra = revID.getExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = extra.toMap) + } def toArtifact(art: IvyArtifact): Artifact = { From d96c5ad1b496671945da19baf9e4c638a1539ae2 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 23 Jul 2011 23:07:54 -0400 Subject: [PATCH 0128/1030] extra information when dependencies with extra attributes cannot be resolved --- ivy/IvyActions.scala | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 0b2f26305..215959116 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -128,7 +128,9 @@ object IvyActions val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { - case Some(x) if !configuration.missingOk => throw x + case Some(x) if !configuration.missingOk => + processUnresolved(x, log) + throw x case _ => val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) @@ -140,6 +142,13 @@ object IvyActions } } + def processUnresolved(err: ResolveException, log: Logger) + { + val withExtra = err.failed.filter(!_.extraAttributes.isEmpty) + log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") + withExtra foreach { id => log.warn("\t\t" + id) } + log.warn("") + } def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = report.configurations.flatMap { confReport => val evicted = confReport.evicted.filter(moduleFilter) @@ -194,7 +203,11 @@ object IvyActions val resolveReport = ivy.resolve(module, resolveOptions) val err = if(resolveReport.hasError) - Some(new ResolveException(resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct)) + { + val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct + val failed = resolveReport.getUnresolvedDependencies.map(node => IvyRetrieve.toModuleID(node.getId)) + Some(new ResolveException(messages, failed)) + } else None (resolveReport, err) } @@ -245,4 +258,4 @@ object IvyActions } } -final class ResolveException(messages: Seq[String]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file +final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file From 1dced5cc4151c9922316625bd55f141f2d94b499 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 23 Jul 2011 23:07:54 -0400 Subject: [PATCH 0129/1030] includes extra attributes in ModuleID.toString --- ivy/IvyInterface.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index fdf0cd7dd..ac653de40 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -11,7 +11,11 @@ import org.apache.ivy.util.url.CredentialsStore final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) { - override def toString = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + override def toString = + organization + ":" + name + ":" + revision + + (configurations match { case Some(s) => ":" + s; case None => "" }) + + (if(extraAttributes.isEmpty) "" else " " + extraString) + def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") def cross(v: Boolean) = copy(crossVersion = v) // () required for chaining def notTransitive() = intransitive() From efe920fff0adc0b28910efc908904fc20660eb87 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 23 Jul 2011 23:07:54 -0400 Subject: [PATCH 0130/1030] includes sbt, Scala version extra attributes in repository/cache patterns --- ivy/Ivy.scala | 4 ++++ ivy/IvyInterface.scala | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index c3ece3247..d461f1f18 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -4,6 +4,7 @@ package sbt import Artifact.{defaultExtension, defaultType} +import Resolver.PluginPattern import java.io.File import java.util.concurrent.Callable @@ -257,6 +258,9 @@ private object IvySbt override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = super.findModuleInCache(dd,revId,options,null) } + manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) + manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) + manager.setIvyPattern(PluginPattern + manager.getIvyPattern) manager.setUseOrigin(true) if(localOnly) manager.setDefaultTTL(java.lang.Long.MAX_VALUE); diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index ac653de40..3157a6b4b 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -275,8 +275,10 @@ object Resolver def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns - def mavenStyleBasePattern = "[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/[revision]/[type]s/[artifact](-[classifier]).[ext]" + def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" + def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" + def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" + final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" def mavenLocal = MavenRepository("Maven2 Local", (new File(Path.userHome, ".m2/repository/")).toURI.toURL.toExternalForm) def defaultLocal = defaultUserFileRepository("local") From b8b06a5ba756c64f3da4127b630cd2444bc4c22b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 25 Jul 2011 21:38:01 -0400 Subject: [PATCH 0131/1030] fix spurious extra attributes warning --- ivy/IvyActions.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 215959116..387fdd60b 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -145,9 +145,12 @@ object IvyActions def processUnresolved(err: ResolveException, log: Logger) { val withExtra = err.failed.filter(!_.extraAttributes.isEmpty) - log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") - withExtra foreach { id => log.warn("\t\t" + id) } - log.warn("") + if(!withExtra.isEmpty) + { + log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") + withExtra foreach { id => log.warn("\t\t" + id) } + log.warn("") + } } def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = report.configurations.flatMap { confReport => From 1cbd4a2e4771d5ec15b500b8b47ea9a0ea36addf Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Jul 2011 19:50:58 -0400 Subject: [PATCH 0132/1030] log conflict messages as one unit --- ivy/ConflictWarning.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index 758ebb07a..f26661936 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -11,9 +11,13 @@ object ConflictWarning { val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) - log.log(config.level, "Potentially incompatible versions specified by " + config.label + ":") - for( (label, versions) <- conflicts ) - log.log(config.level, " " + label + ": " + versions.mkString(", ")) + { + val msg = "Potentially incompatible versions specified by " + config.label + ":" + val conflictMsgs = + for( (label, versions) <- conflicts ) yield + label + ": " + versions.mkString(", ") + log.log(config.level, msg + conflictMsgs.mkString(msg, "\n ", "")) + } if(config.failOnConflict && !conflicts.isEmpty) error("Conflicts in " + conflicts.map(_._1).mkString ) } From 149edd6ee852aa3f7ff682cdeef7d9b38f91531a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Jul 2011 19:50:59 -0400 Subject: [PATCH 0133/1030] explicitly set pattern for Maven resolver for more control --- ivy/ConvertResolver.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 6c479a619..a05cbcf0d 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -70,6 +70,7 @@ private object ConvertResolver resolver.setName(name) resolver.setM2compatible(true) resolver.setRoot(root) + resolver.setPattern(Resolver.mavenStyleBasePattern) } private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)(implicit settings: IvySettings) { From 392754e165262d619473425c95e558e9ff60b9b0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Jul 2011 19:50:59 -0400 Subject: [PATCH 0134/1030] maven-compatible plugin dependency system --- ivy/CustomPomParser.scala | 88 +++++++++++++++++++++++++++++++++++++++ ivy/Ivy.scala | 7 ++++ ivy/IvyRetrieve.scala | 6 +-- ivy/MakePom.scala | 11 +++++ 4 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 ivy/CustomPomParser.scala diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala new file mode 100644 index 000000000..c2c928a6f --- /dev/null +++ b/ivy/CustomPomParser.scala @@ -0,0 +1,88 @@ +package sbt + + import org.apache.ivy.{core, plugins} + import core.module.id.ModuleRevisionId + import core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} + import plugins.parser.{m2, ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} + import m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} + import plugins.repository.Resource + + import java.io.{File, InputStream} + import java.net.URL + +final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser +{ + override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = + transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) + + override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, res: Resource, validate: Boolean) = + transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, res, validate)) + + override def toIvyFile(is: InputStream, res: Resource, destFile: File, md: ModuleDescriptor) = delegate.toIvyFile(is, res, destFile, md) + + override def accept(res: Resource) = delegate.accept(res) + override def getType() = delegate.getType() + override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) +} +object CustomPomParser +{ + val SbtVersionKey = "sbtVersion" + val ScalaVersionKey = "scalaVersion" + + val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) + + // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. + lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) + + def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + { + import collection.JavaConverters._ + val properties = PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap + val filtered = shouldBeUnqualified(properties) + if(filtered.isEmpty) md else addExtra(filtered, parser, md) + } + private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = + m.filter { case (k,_) => k == SbtVersionKey || k == ScalaVersionKey } + + private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = + { + import collection.JavaConverters._ + val oldExtra = id.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala + val newExtra = (oldExtra ++ properties).asJava + ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, newExtra) + } + + import collection.JavaConverters._ + def addExtra(properties: Map[String, String], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + { + val dmd = new DefaultModuleDescriptor(parser, md.getResource) + + val mrid = addExtra(properties, md.getModuleRevisionId) + val resolvedMrid = addExtra(properties, md.getResolvedModuleRevisionId) + dmd.setModuleRevisionId(mrid) + dmd.setResolvedModuleRevisionId(resolvedMrid) + + dmd.setDefault(md.isDefault) + dmd.setHomePage(md.getHomePage) + dmd.setDescription(md.getDescription) + dmd.setLastModified(md.getLastModified) + dmd.setStatus(md.getStatus()) + dmd.setPublicationDate(md.getPublicationDate()) + dmd.setResolvedPublicationDate(md.getResolvedPublicationDate()) + + for(l <- md.getLicenses) dmd.addLicense(l) + for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) + for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) + for( dd <- md.getDependencies ) dmd.addDependency(dd) + + for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( mrid, resolvedMrid, ed.getLocation, ed.getExtendsTypes) ) + for( conf <- md.getConfigurations) { + dmd.addConfiguration(conf) + for(art <- md.getArtifacts(conf.getName)) { + val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, art.getExt, art.getUrl, art.getQualifiedExtraAttributes) + dmd.addArtifact(conf.getName, nart) + } + } + dmd + } +} \ No newline at end of file diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index d461f1f18..89aa46592 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -25,6 +25,7 @@ import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser import plugins.resolver.{ChainResolver, DependencyResolver} import util.{Message, MessageLogger} +import util.extendable.ExtendableItem import scala.xml.NodeSeq @@ -61,6 +62,7 @@ final class IvySbt(val configuration: IvyConfiguration) { val is = new IvySettings is.setBaseDir(baseDirectory) + CustomPomParser.registerDefault configuration match { case e: ExternalIvyConfiguration => is.load(e.file) @@ -319,6 +321,11 @@ private object IvySbt configurations.foreach(artifact.addConfiguration) artifact } + def getExtraAttributes(revID: ExtendableItem): Map[String,String] = + { + import collection.JavaConverters._ + revID.getExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala.toMap + } private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = { val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index c36703c2f..7c96c63ff 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -39,11 +39,7 @@ object IvyRetrieve confReport.getEvictedNodes.map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = - { - import collection.JavaConverters._ - val extra = revID.getExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala - ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = extra.toMap) - } + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID)) def toArtifact(art: IvyArtifact): Artifact = { diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 432a83ba6..063b44e5b 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -42,6 +42,7 @@ class MakePom 4.0.0 { makeModuleID(module) } { extra } + { makeProperties(module) } { makeDependencies(module, configurations) } { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) @@ -60,6 +61,16 @@ class MakePom licenses(module.getLicenses)) : NodeSeq ) a ++ b } + def makeProperties(module: ModuleDescriptor): NodeSeq = + { + val extra = IvySbt.getExtraAttributes(module) + if(extra.isEmpty) NodeSeq.Empty else makeProperties(extra) + } + def makeProperties(extra: Map[String,String]): NodeSeq = + { + for( (key,value) <- extra ) yield + ({value}).copy(label = key) + } def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else {d} def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else {ls.map(license)} From 73d52dc03130eb929194969cd8b4194c3100d2be Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 29 Jul 2011 23:33:10 -0400 Subject: [PATCH 0135/1030] fix inter-project dependencies involving extra attributes --- ivy/Ivy.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 89aa46592..8f8829328 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -141,7 +141,6 @@ final class IvySbt(val configuration: IvyConfiguration) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) - IvySbt.addDependencies(moduleID, dependencies, parser) IvySbt.addMainArtifact(moduleID) (moduleID, parser.getDefaultConf) @@ -351,11 +350,11 @@ private object IvySbt private def wrapped(module: ModuleID, dependencies: NodeSeq) = { import module._ - + { if(hasInfo(module, dependencies)) NodeSeq.Empty else - + addExtraAttributes(, module.extraAttributes) } {dependencies} { @@ -364,6 +363,8 @@ private object IvySbt } } + private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = + (elem /: extra) { case (e, (key,value) ) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { val info = {x} \ "info" From d7a5dca8129391aad072a0434954baa7c8842797 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 30 Jul 2011 18:11:20 -0400 Subject: [PATCH 0136/1030] fix pom packaging autodetection --- ivy/Ivy.scala | 1 - ivy/IvyInterface.scala | 22 ++++++++++++---------- ivy/MakePom.scala | 10 +++++++--- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 8f8829328..bd1adc399 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -3,7 +3,6 @@ */ package sbt -import Artifact.{defaultExtension, defaultType} import Resolver.PluginPattern import java.io.File diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 3157a6b4b..3c80bc087 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -364,17 +364,17 @@ final case class Artifact(name: String, `type`: String, extension: String, class object Artifact { - def apply(name: String): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None) - def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, defaultType, defaultExtension, None, Nil, None, extra) - def apply(name: String, classifier: String): Artifact = Artifact(name, defaultType, defaultExtension, Some(classifier), Nil, None) + def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) + def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) + def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) - def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, defaultType), extract(url, defaultExtension), None, Nil, Some(url)) + def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) - val defaultExtension = "jar" - val defaultType = "jar" + val DefaultExtension = "jar" + val DefaultType = "jar" def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) @@ -382,6 +382,8 @@ object Artifact val DocClassifier = "javadoc" val SourceClassifier = "sources" + val DocType = "doc" + val SourceType = "src" val PomType = "pom" def extract(url: URL, default: String): String = extract(url.toString, default) @@ -398,7 +400,7 @@ object Artifact val name = file.getName val i = name.lastIndexOf('.') val base = if(i >= 0) name.substring(0, i) else name - Artifact(base, extract(name, defaultType), extract(name, defaultExtension), None, Nil, Some(file.toURI.toURL)) + Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) } def artifactName(scalaVersion: String, module: ModuleID, artifact: Artifact): String = { @@ -410,11 +412,11 @@ object Artifact def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) - val classifierTypeMap = Map(SourceClassifier -> "src", DocClassifier -> "doc") + val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, defaultType) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, DefaultType) def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), defaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 063b44e5b..64145e066 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -88,10 +88,14 @@ class MakePom case Array() => "pom" case Array(x) => x.getType case xs => - val types = xs.map(_.getType) - val notpom = types.toList - "pom" - if(notpom.isEmpty) "pom" else if(notpom contains "jar") "jar" else notpom.head + val types = xs.map(_.getType).toList.filterNot(IgnoreTypes) + types match { + case Nil => Artifact.PomType + case xs if xs.contains(Artifact.DefaultType) => Artifact.DefaultType + case x :: xs => x + } } + val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) def makeDependencies(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): NodeSeq = { From 009c34e021fd5aeeb6882938cd08d23302640aaf Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Fri, 29 Jul 2011 00:09:21 +0530 Subject: [PATCH 0137/1030] fix distribution method (see: http://maven.apache.org/pom.html#Licenses) --- ivy/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 64145e066..f8f3da374 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -78,7 +78,7 @@ class MakePom {l.getName} {l.getUrl} - jar + repo def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else {homePage} def revision(version: String) = if(version ne null) {version} else NodeSeq.Empty From a24e2d06bb4a44247009e03fa943c061996e6abd Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Fri, 29 Jul 2011 23:02:45 +0530 Subject: [PATCH 0138/1030] Add java.net M2 repo for convenience --- ivy/IvyInterface.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 3c80bc087..3631bbef0 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -159,6 +159,7 @@ import Resolver._ object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) +object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JavaNet1Repository extends JavaNet1Repository sealed trait JavaNet1Repository extends Resolver { @@ -171,6 +172,8 @@ object Resolver val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository" val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" + val JavaNet2RepositoryName = "java.net Maven2 Repository" + val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" /** Add the local, Maven Central, and Scala Tools releases repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = From 6dca8bda66fece4e9ba501f6d1abec9c8ebed56e Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sat, 30 Jul 2011 01:52:02 +0530 Subject: [PATCH 0139/1030] JavaNet1Repository should have legacy layout (see: http://maven.apache.org/pom.html#Repository) --- ivy/MakePom.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index f8f3da374..361520698 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -173,6 +173,7 @@ class MakePom {id} {name} {root} + { if(name == JavaNet1Repository.name) "legacy" else "default" } /** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. From 0c9f6d88f9ce1343bc0f927cf605c21d8a9dc561 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 31 Jul 2011 22:17:50 -0400 Subject: [PATCH 0140/1030] use configurations for modules for update-classifiers. fixes #104 --- ivy/IvyActions.scala | 15 +++++++++------ ivy/UpdateReport.scala | 5 +++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 387fdd60b..45944d5a1 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -28,7 +28,8 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) // exclude is a map on a restricted ModuleID -final case class GetClassifiersConfiguration(id: ModuleID, modules: Seq[ModuleID], classifiers: Seq[String], exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) +final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) +final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) /** Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. @@ -166,21 +167,23 @@ object IvyActions def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { - import config.{configuration => c, id, ivyScala, modules => deps} + import config.{configuration => c, ivyScala, module => mod} + import mod.{configurations => confs, id, modules => deps} val base = restrictedCopy(id).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) - val newConfig = config.copy(modules = report.allModules) + val newConfig = config.copy(module = mod.copy(modules = report.allModules)) updateClassifiers(ivySbt, newConfig, log) } def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { - import config.{configuration => c, _} + import config.{configuration => c, module => mod, _} + import mod.{configurations => confs, _} assert(!classifiers.isEmpty, "classifiers cannot be empty") val baseModules = modules map restrictedCopy val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) val base = restrictedCopy(id).copy(name = id.name + classifiers.mkString("$","_","")) - val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) + val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) update(module, upConf, log) } @@ -198,7 +201,7 @@ object IvyActions def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } - private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes) + private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = m.configurations) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 28145f7e5..241ecded5 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -40,8 +40,9 @@ final class ConfigurationReport(val configuration: String, val modules: Seq[Modu /** All resolved modules for this configuration. * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. */ - def allModules: Seq[ModuleID] = modules.map(_.module) - + def allModules: Seq[ModuleID] = modules.map(mr => addConfiguration(mr.module)) + private[this] def addConfiguration(mod: ModuleID): ModuleID = if(mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod + def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }, evicted) } From 479c088772bb74e8b7d5dfee5ea91d1facb3c489 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sun, 31 Jul 2011 23:17:35 +0530 Subject: [PATCH 0141/1030] - Extra Settings are now available to control project information, viz., name, description, homepage, organization name, organization homepage, licenses - Modified name/signature of some private types/methods to reduce confusion (all in limited scope, so nothing should change from end user's pov) - Enriched Ivy and Maven descriptors produced out of the box (see Keys.scala and Defaults.scala for more) - Projects do not need to create custom Ivy block anymore, there is more settings-specific control instead --- ivy/Ivy.scala | 50 +++++++++++++++++++------------------ ivy/IvyActions.scala | 10 ++++---- ivy/IvyConfigurations.scala | 14 ++++------- ivy/IvyInterface.scala | 8 ++++++ ivy/MakePom.scala | 15 ++++++++--- 5 files changed, 56 insertions(+), 41 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index bd1adc399..d24691df9 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -14,7 +14,7 @@ import org.apache.ivy.{core, plugins, util, Ivy} import core.IvyPatternHelper import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} +import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.IvyNode import core.settings.IvySettings @@ -26,7 +26,7 @@ import plugins.resolver.{ChainResolver, DependencyResolver} import util.{Message, MessageLogger} import util.extendable.ExtendableItem -import scala.xml.NodeSeq +import scala.xml.{NodeSeq, Text} final class IvySbt(val configuration: IvyConfiguration) { @@ -124,9 +124,9 @@ final class IvySbt(val configuration: IvyConfiguration) moduleSettings match { case ic: InlineConfiguration => configureInline(ic, configuration.log) - case ec: EmptyConfiguration => configureEmpty(ec.module) - case pc: PomConfiguration => readPom(pc.file, pc.validate) - case ifc: IvyFileConfiguration => readIvyFile(ifc.file, ifc.validate) + case ec: EmptyConfiguration => configureEmpty(ec) + case pc: PomConfiguration => configurePom(pc) + case ifc: IvyFileConfiguration => configureIvyFile(ifc) } moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra") @@ -135,7 +135,7 @@ final class IvySbt(val configuration: IvyConfiguration) private def configureInline(ic: InlineConfiguration, log: Logger) = { import ic._ - val moduleID = newConfiguredModuleID(module, configurations) + val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) @@ -144,44 +144,43 @@ final class IvySbt(val configuration: IvyConfiguration) IvySbt.addMainArtifact(moduleID) (moduleID, parser.getDefaultConf) } - private def newConfiguredModuleID(module: ModuleID, configurations: Iterable[Configuration]) = + private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = { val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) mod.setLastModified(System.currentTimeMillis) + mod.setDescription(moduleInfo.description) + moduleInfo.homepage foreach { h => mod.setHomePage(h.toString) } + moduleInfo.licenses foreach { l => mod.addLicense(new License(l._1, l._2.toString)) } IvySbt.addConfigurations(mod, configurations) IvySbt.addArtifacts(mod, module.explicitArtifacts) mod } - /** Parses the given Maven pom 'pomFile'.*/ - private def readPom(pomFile: File, validate: Boolean) = + /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ + private def configurePom(pc: PomConfiguration) = { - val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pomFile), validate) + val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) IvySbt.addConfigurations(dmd, Configurations.defaultInternal) (dmd, "compile") } - /** Parses the given Ivy file 'ivyFile'.*/ - private def readIvyFile(ivyFile: File, validate: Boolean) = + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ + private def configureIvyFile(ifc: IvyFileConfiguration) = { - val url = toURL(ivyFile) val parser = new CustomXmlParser.CustomParser(settings, None) - parser.setValidate(validate) - parser.setSource(url) + parser.setValidate(ifc.validate) + parser.setSource(toURL(ifc.file)) parser.parse() val md = parser.getModuleDescriptor() (IvySbt.toDefaultModuleDescriptor(md), parser.getDefaultConf) } private def toURL(file: File) = file.toURI.toURL - private def configureEmpty(module: ModuleID) = + private def configureEmpty(ec: EmptyConfiguration) = { val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION - val moduleID = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) - moduleID.setLastModified(System.currentTimeMillis) - moduleID.addConfiguration(IvySbt.toIvyConfiguration(Configurations.Default)) - IvySbt.addArtifacts(moduleID, module.explicitArtifacts) - IvySbt.addMainArtifact(moduleID) - (moduleID, defaultConf) + val mod = newConfiguredModuleID(ec.module, ec.moduleInfo, Seq(Configurations.Default)) + IvySbt.addMainArtifact(mod) + (mod, defaultConf) } } } @@ -348,12 +347,11 @@ private object IvySbt /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ private def wrapped(module: ModuleID, dependencies: NodeSeq) = { - import module._ { if(hasInfo(module, dependencies)) NodeSeq.Empty else - addExtraAttributes(, module.extraAttributes) + addExtraAttributes(defaultInfo(module), module.extraAttributes) } {dependencies} { @@ -362,6 +360,10 @@ private object IvySbt } } + private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { + import module._ + + } private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = (elem /: extra) { case (e, (key,value) ) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 45944d5a1..a1c26b020 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -26,7 +26,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final case class MakePomConfiguration(file: File, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) +final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) @@ -66,9 +66,9 @@ object IvyActions /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { - import configuration.{allRepositories, configurations, extra, file, filterRepositories, process} + import configuration.{allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process} module.withModule(log) { (ivy, md, default) => - (new MakePom).write(ivy, md, configurations, extra, process, filterRepositories, allRepositories, file) + (new MakePom).write(ivy, md, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, file) log.info("Wrote " + file.getAbsolutePath) } } @@ -170,7 +170,7 @@ object IvyActions import config.{configuration => c, ivyScala, module => mod} import mod.{configurations => confs, id, modules => deps} val base = restrictedCopy(id).copy(name = id.name + "$" + label) - val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala)) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) val newConfig = config.copy(module = mod.copy(modules = report.allModules)) updateClassifiers(ivySbt, newConfig, log) @@ -183,7 +183,7 @@ object IvyActions val baseModules = modules map restrictedCopy val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) val base = restrictedCopy(id).copy(name = id.name + classifiers.mkString("$","_","")) - val module = new ivySbt.Module(InlineConfiguration(base, deps).copy(ivyScala = ivyScala, configurations = confs)) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) update(module, upConf, log) } diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index b151054bd..09fa96fcb 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -62,21 +62,17 @@ final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], valida { def noScala = copy(ivyScala = None) } -final case class InlineConfiguration(module: ModuleID, dependencies: Seq[ModuleID], ivyXML: NodeSeq, - configurations: Seq[Configuration], defaultConfiguration: Option[Configuration], ivyScala: Option[IvyScala], - validate: Boolean) extends ModuleSettings +final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) } -final case class EmptyConfiguration(module: ModuleID, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings +final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { def noScala = copy(ivyScala = None) } object InlineConfiguration { - def apply(module: ModuleID, dependencies: Seq[ModuleID]) = - new InlineConfiguration(module, dependencies, NodeSeq.Empty, Nil, None, None, false) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if(explicitConfigurations.isEmpty) { @@ -92,7 +88,7 @@ object InlineConfiguration } object ModuleSettings { - def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID)(baseDirectory: File, log: Logger) = + def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger) = { log.debug("Autodetecting dependencies.") val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) @@ -106,8 +102,8 @@ object ModuleSettings else { log.warn("No dependency configuration found, using defaults.") - new EmptyConfiguration(module, ivyScala, validate) + new EmptyConfiguration(module, moduleInfo, ivyScala, validate) } } } -} \ No newline at end of file +} diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 3631bbef0..a1eadeb1c 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -38,6 +38,14 @@ object ModuleID for ( (key, value) <- attributes) yield if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } +/** Additional information about a project module */ +case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None) +{ + def formally(name: String) = copy(nameFormal = name) + def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) + def licensed(lics: (String, URL)*) = copy(licenses = lics) + def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) +} sealed trait Resolver { def name: String diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 361520698..939ee92bb 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -20,8 +20,8 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom { def encoding = "UTF-8" - def write(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(process(toPom(ivy, module, configurations, extra, filterRepositories, allRepositories)), output) + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + write(process(toPom(ivy, module, moduleInfo, configurations, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) @@ -37,10 +37,12 @@ class MakePom } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = ( 4.0.0 { makeModuleID(module) } + {moduleInfo.nameFormal} + { makeOrganization(moduleInfo) } { extra } { makeProperties(module) } { makeDependencies(module, configurations) } @@ -61,6 +63,13 @@ class MakePom licenses(module.getLicenses)) : NodeSeq ) a ++ b } + def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = + { + + {moduleInfo.organizationName} + { moduleInfo.organizationHomepage map { h => {h} } getOrElse NodeSeq.Empty } + + } def makeProperties(module: ModuleDescriptor): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) From c96aa6f9d27ff5def87e729f8763e4504563df3c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 4 Aug 2011 18:08:21 -0400 Subject: [PATCH 0142/1030] remove obsolete assertion. ref #143 --- ivy/IvyScala.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 0760a7277..e1672d9d5 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -23,11 +23,7 @@ object ScalaArtifacts import ScalaArtifacts._ final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, substituteCross: ModuleID => ModuleID) -{ - // otherwise, Ivy produces the error: "impossible to get artifacts when data has not been loaded" - // which may be related to sbt's custom conflict manager (now removed), to IVY-987, or both - assert(if(overrideScalaVersion) checkExplicit else true, "Explicit Scala version checking cannot be disabled when forcing the Scala version.") -} + private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ From 9d6fca5d2a1b0884471b8ea61935cf21c66d99c5 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Fri, 5 Aug 2011 13:16:49 +0530 Subject: [PATCH 0143/1030] Remove some deprecations and redundant code --- ivy/Credentials.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index a097596ed..4ca13d7a3 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -37,7 +37,7 @@ object Credentials if(path.exists) { val properties = read(path) - def get(keys: List[String]) = keys.flatMap(properties.get).firstOption.toRight(keys.head + " not specified in credentials file: " + path) + def get(keys: List[String]) = keys.flatMap(properties.get).headOption.toRight(keys.head + " not specified in credentials file: " + path) List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match { From 6d583f36c1efd8036c7bf2718af6f2501ae1d4d3 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 16 Aug 2011 17:28:53 -0400 Subject: [PATCH 0144/1030] move to 2.9.1 (RC3), bump to 0.11.0-SNAPSHOT --- ivy/IvyConfigurations.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 09fa96fcb..97e6eb7c2 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -88,7 +88,7 @@ object InlineConfiguration } object ModuleSettings { - def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger) = + def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = { log.debug("Autodetecting dependencies.") val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) From de91865fae625ccd566ba903347f7701dfe796f1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 19 Aug 2011 22:13:56 -0400 Subject: [PATCH 0145/1030] append sbt pattern to leave the default IBiblioResolver pattern in place. fixes #155 --- ivy/ConvertResolver.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index a05cbcf0d..731ad268b 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -20,6 +20,8 @@ private object ConvertResolver { val resolver = new IBiblioResolver initializeMavenStyle(resolver, repo.name, repo.root) + resolver.addArtifactPattern(Resolver.mavenStyleBasePattern) + resolver.addIvyPattern(Resolver.mavenStyleBasePattern) resolver } case r: JavaNet1Repository => @@ -70,7 +72,6 @@ private object ConvertResolver resolver.setName(name) resolver.setM2compatible(true) resolver.setRoot(root) - resolver.setPattern(Resolver.mavenStyleBasePattern) } private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)(implicit settings: IvySettings) { From e73e0938ebdff676f645c755e2a95fda2ef38bbe Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 22 Aug 2011 22:48:21 -0400 Subject: [PATCH 0146/1030] remove duplication in conflict warning message --- ivy/ConflictWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index f26661936..c59e4ccf5 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -16,7 +16,7 @@ object ConflictWarning val conflictMsgs = for( (label, versions) <- conflicts ) yield label + ": " + versions.mkString(", ") - log.log(config.level, msg + conflictMsgs.mkString(msg, "\n ", "")) + log.log(config.level, conflictMsgs.mkString(msg, "\n ", "")) } if(config.failOnConflict && !conflicts.isEmpty) error("Conflicts in " + conflicts.map(_._1).mkString ) From 6961dff60e6468ff775c7851d77b60bd1ef71e26 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 22 Aug 2011 22:48:21 -0400 Subject: [PATCH 0147/1030] better error when publish resolver from custom configuration doesn't exist --- ivy/IvyActions.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a1c26b020..c1eef5913 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -92,6 +92,7 @@ object IvyActions import configuration._ module.withModule(log) { case (ivy, md, default) => val resolver = ivy.getSettings.getResolver(resolverName) + if(resolver eq null) error("Undefined resolver '" + resolverName + "'") val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } val is = crossIvyScala(module.moduleSettings) val as = mapArtifacts(md, is, artifacts) ++ ivyArtifact.toList From 964f83244a91165b9ca20e384dbc46d16d5878e7 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 22 Aug 2011 22:45:05 -0400 Subject: [PATCH 0148/1030] improved fix for #155 --- ivy/ConvertResolver.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 731ad268b..f99a1fb9a 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -3,6 +3,7 @@ */ package sbt +import java.util.Collections import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId import core.settings.IvySettings @@ -18,10 +19,16 @@ private object ConvertResolver { case repo: MavenRepository => { - val resolver = new IBiblioResolver + val pattern = Collections.singletonList(repo.root + Resolver.mavenStyleBasePattern) + final class PluginCapableResolver extends IBiblioResolver { + def setPatterns() { // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + } + val resolver = new PluginCapableResolver initializeMavenStyle(resolver, repo.name, repo.root) - resolver.addArtifactPattern(Resolver.mavenStyleBasePattern) - resolver.addIvyPattern(Resolver.mavenStyleBasePattern) + resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns resolver } case r: JavaNet1Repository => From 86c0ff1c09120f7c383f8c2829e3e93c9534586c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 23 Aug 2011 19:51:50 -0400 Subject: [PATCH 0149/1030] minor improvements to conflict message. closes #132 --- ivy/ConflictWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index c59e4ccf5..92ae38cbb 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -12,7 +12,7 @@ object ConflictWarning val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) { - val msg = "Potentially incompatible versions specified by " + config.label + ":" + val msg = "Potentially incompatible versions of dependencies of " + config.label + ":" val conflictMsgs = for( (label, versions) <- conflicts ) yield label + ": " + versions.mkString(", ") From 5f674dbea4b59dbd0b66b2118090f315b6827b96 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 23 Aug 2011 19:51:50 -0400 Subject: [PATCH 0150/1030] more on #155 --- ivy/ConvertResolver.scala | 2 +- ivy/IvyInterface.scala | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index f99a1fb9a..1d6920c5c 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -19,7 +19,7 @@ private object ConvertResolver { case repo: MavenRepository => { - val pattern = Collections.singletonList(repo.root + Resolver.mavenStyleBasePattern) + val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) final class PluginCapableResolver extends IBiblioResolver { def setPatterns() { // done this way for access to protected methods. setArtifactPatterns(pattern) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index a1eadeb1c..d8c5c0ac6 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -275,12 +275,14 @@ object Resolver /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = { - val normBase = base.replace('\\', '/') - def resolve(pattern: String) = if(normBase.endsWith("/") || pattern.startsWith("/")) normBase +pattern else normBase + "/" + pattern - def resolveAll(patterns: Seq[String]) = patterns.map(resolve) + def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) } - + private[sbt] def resolvePattern(base: String, pattern: String): String = + { + val normBase = base.replace('\\', '/') + if(normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern + } def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) From a258d4f3b5e15c6d9e3f4fbcfe4f17dabee081f1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 26 Aug 2011 23:27:03 -0400 Subject: [PATCH 0151/1030] clean up optional dependency handling for make-pom. fixes #162 --- ivy/MakePom.scala | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 939ee92bb..76d891330 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -9,6 +9,7 @@ package sbt; import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter, XML} +import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} import core.settings.IvySettings @@ -123,32 +124,37 @@ class MakePom {mrid.getOrganisation} {mrid.getName} {mrid.getRevision} - { scope(dependency)} - { optional(dependency) } + { scopeAndOptional(dependency)} } - def scope(dependency: DependencyDescriptor): NodeSeq = - scope(getScope(dependency.getModuleConfigurations)) - def scope(scope: String): NodeSeq = if(scope ne null) {scope} else NodeSeq.Empty - def optional(dependency: DependencyDescriptor) = - if(isOptional(dependency.getModuleConfigurations)) true else NodeSeq.Empty + def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = + { + val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) + scopeElem(scope) ++ optionalElem(opt) + } + def scopeElem(scope: Option[String]): NodeSeq = scope match { + case Some(s) => {s} + case None => NodeSeq.Empty + } + def optionalElem(opt: Boolean) = if(opt) true else NodeSeq.Empty def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId - def getScope(confs: Array[String]) = + def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = { - Configurations.defaultMavenConfigurations.find(conf => confs.contains(conf.name)) match + val (opt, notOptional) = confs.partition(_ == Optional.name) + val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) + val scope = defaultNotOptional match { - case Some(conf) => conf.name + case Some(conf) => Some(conf.name) case None => - if(confs.isEmpty || confs(0) == Configurations.Default.name) - null + if(notOptional.isEmpty || notOptional(0) == Configurations.Default.name) + None else - confs(0) + Option(notOptional(0)) } + (scope, !opt.isEmpty) } - def isOptional(confs: Array[String]) = confs.isEmpty || (confs.length == 1 && confs(0) == Configurations.Optional.name) - def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = { From 2c0819d7c724b4a6d89a7dc4420c21efa65e70e1 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sat, 3 Sep 2011 00:16:00 +0530 Subject: [PATCH 0152/1030] Add start-year for compliance in ProjectInfo --- ivy/IvyInterface.scala | 2 +- ivy/MakePom.scala | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index d8c5c0ac6..918023f38 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -39,7 +39,7 @@ object ModuleID if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } /** Additional information about a project module */ -case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None) +case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None) { def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 76d891330..dc31760b1 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -43,6 +43,7 @@ class MakePom 4.0.0 { makeModuleID(module) } {moduleInfo.nameFormal} + { makeStartYear(moduleInfo) } { makeOrganization(moduleInfo) } { extra } { makeProperties(module) } @@ -64,6 +65,8 @@ class MakePom licenses(module.getLicenses)) : NodeSeq ) a ++ b } + + def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = moduleInfo.startYear map { y => {y} } getOrElse NodeSeq.Empty def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = { From 2585c57760a943a42b344462f1b292d72c291b4e Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Tue, 6 Sep 2011 17:29:42 +0530 Subject: [PATCH 0153/1030] Honor in when available --- ivy/IvyActions.scala | 2 +- ivy/MakePom.scala | 31 ++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index c1eef5913..3a40aadf0 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -68,7 +68,7 @@ object IvyActions { import configuration.{allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process} module.withModule(log) { (ivy, md, default) => - (new MakePom).write(ivy, md, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, file) + (new MakePom(log)).write(ivy, md, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, file) log.info("Wrote " + file.getAbsolutePath) } } diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index dc31760b1..fc0a90c16 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -14,11 +14,11 @@ import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} import core.settings.IvySettings import core.module.{descriptor, id} -import descriptor.{DependencyDescriptor, License, ModuleDescriptor} +import descriptor.{DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} import id.ModuleRevisionId import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} -class MakePom +class MakePom(val log: Logger) { def encoding = "UTF-8" def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = @@ -123,11 +123,21 @@ class MakePom def makeDependency(dependency: DependencyDescriptor): NodeSeq = { val mrid = dependency.getDependencyRevisionId + val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) {mrid.getOrganisation} {mrid.getName} {mrid.getRevision} - { scopeAndOptional(dependency)} + { scopeAndOptional(dependency) } + { + val (warns, excls) = List.separate(excl.map(makeExclusion)) + if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) + if(excls.isEmpty) NodeSeq.Empty + else + + { excls } + + } } @@ -159,6 +169,21 @@ class MakePom (scope, !opt.isEmpty) } + def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = + { + val m = exclRule.getId.getModuleId + val (g, a) = (m.getOrganisation, m.getName) + if(g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") + Left("Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.".format(m)) + else + Right( + + {g} + {a} + + ) + } + def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = { class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) From a6396f839ba4106c14c1f7d0a251e1a825b53cd1 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Tue, 6 Sep 2011 18:59:24 +0530 Subject: [PATCH 0154/1030] Support for simple exclusion rules in inline dependencies This support excluding a library from the dependency tree for a given set of `ExclusionRule`s. There are two ways to achieve this: - Using `organization` and `name` pairs: val dep = "org" % "name" % "version" exclude("commons-codec", "commons-codec") exclude("org.slf4j", "slf4j-log4j") - Using `ExclusionRule`: val dep = "org" % "name" % "version" excludeAll(ExclusionRule("commons-codec", "commons-codec"), ExclusionRule("org.slf4j", "slf4j-log4j")) --- ivy/Ivy.scala | 7 +++++++ ivy/IvyInterface.scala | 6 +++++- ivy/IvyScala.scala | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index d24691df9..c0936c1ee 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -419,6 +419,13 @@ private object IvySbt for(conf <- dependencyDescriptor.getModuleConfigurations) dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) } + for(excls <- dependency.exclusions) + { + for(conf <- dependencyDescriptor.getModuleConfigurations) + { + dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations)) + } + } moduleID.addDependency(dependencyDescriptor) } } diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 918023f38..9f5b0c630 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,7 +9,7 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) { override def toString = organization + ":" + name + ":" + revision + @@ -24,6 +24,8 @@ final case class ModuleID(organization: String, name: String, revision: String, def from(url: String) = artifacts(Artifact(name, new URL(url))) def classifier(c: String) = artifacts(Artifact(name, c)) def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) def sources() = artifacts(Artifact.sources(name)) def javadoc() = artifacts(Artifact.javadoc(name)) @@ -46,6 +48,8 @@ case class ModuleInfo(nameFormal: String, description: String = "", homepage: Op def licensed(lics: (String, URL)*) = copy(licenses = lics) def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) } +/** Rule to exclude unwanted dependencies pulled in transitively by a module. */ +case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) sealed trait Resolver { def name: String diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index e1672d9d5..9926f7141 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -86,7 +86,7 @@ private object IvyScala } /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for * the given configurations. */ - private def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = + private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = { val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "jar", "*") val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef,AnyRef]) From 31f492f4bc499b79ac050a139597c6d595d65395 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 16 Sep 2011 23:08:01 -0400 Subject: [PATCH 0155/1030] make ComponentManager honor value of Ivy home provided by the launcher --- ivy/ComponentManager.scala | 11 ++++++----- ivy/IvyCache.scala | 6 +++--- ivy/src/test/scala/ComponentManagerTest.scala | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 16ff083da..32979ab3b 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -15,8 +15,9 @@ import java.util.concurrent.Callable * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, val log: Logger) extends NotNull +class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, ivyHome: Option[File], val log: Logger) { + private[this] val ivyCache = new IvyCache(ivyHome) /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ def files(id: String)(ifMissing: IfMissing): Iterable[File] = { @@ -45,7 +46,7 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action ) /** This is used to ensure atomic access to components in the global Ivy cache.*/ - private def lockGlobalCache[T](action: => T): T = lock(IvyCache.lockFile)( action ) + private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)( action ) private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ def file(id: String)(ifMissing: IfMissing): File = @@ -58,12 +59,12 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } /** Retrieve the file for component 'id' from the local repository. */ - private def update(id: String): Unit = IvyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar)) ) + private def update(id: String): Unit = ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar)) ) private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, ComponentManager.stampedVersion) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ - def cache(id: String): Unit = IvyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) - def clearCache(id: String): Unit = lockGlobalCache { IvyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } + def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) + def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } } class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index d7c524a84..ff4b57bac 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -28,9 +28,9 @@ private object NotInCache } } /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ -object IvyCache +class IvyCache(val ivyHome: Option[File]) { - def lockFile = new File(System.getProperty("user.home"), ".sbt.cache.lock") + def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger) { @@ -85,7 +85,7 @@ object IvyCache private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal - val paths = new IvyPaths(new File("."), None) + val paths = new IvyPaths(new File("."), ivyHome) val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, log) (new IvySbt(conf), local) } diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 923304fde..1d9e77c44 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -77,5 +77,5 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), logger)) } ) + TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), None, logger)) } ) } \ No newline at end of file From fe264c4f4e96ef02b36f6f4276731c86d9753ad3 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 20 Sep 2011 20:51:47 -0400 Subject: [PATCH 0156/1030] work around for Ivy-899. fixes #194 --- ivy/CustomPomParser.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index c2c928a6f..cc1fb37d0 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -29,6 +29,8 @@ object CustomPomParser val SbtVersionKey = "sbtVersion" val ScalaVersionKey = "scalaVersion" + // packagings that should be jars, but that Ivy doesn't handle as jars + val JarPackagings = Set("eclipse-plugin") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. @@ -39,11 +41,17 @@ object CustomPomParser import collection.JavaConverters._ val properties = PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap val filtered = shouldBeUnqualified(properties) - if(filtered.isEmpty) md else addExtra(filtered, parser, md) + val convertArtifacts = artifactExtIncorrect(md) + if(filtered.isEmpty && !convertArtifacts) md else addExtra(filtered, parser, md) } + private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = + md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filter { case (k,_) => k == SbtVersionKey || k == ScalaVersionKey } + + private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = + if(properties.isEmpty) id else addExtra(properties, id) private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = { import collection.JavaConverters._ @@ -79,7 +87,9 @@ object CustomPomParser for( conf <- md.getConfigurations) { dmd.addConfiguration(conf) for(art <- md.getArtifacts(conf.getName)) { - val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, art.getExt, art.getUrl, art.getQualifiedExtraAttributes) + val ext = art.getExt + val newExt = if( JarPackagings(ext) ) "jar" else ext + val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, newExt, art.getUrl, art.getQualifiedExtraAttributes) dmd.addArtifact(conf.getName, nart) } } From a32278bfc7ecf2ec1304f996f214f3db811a7074 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 21 Sep 2011 22:49:58 -0400 Subject: [PATCH 0157/1030] require metadata by default --- ivy/ConvertResolver.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index 1d6920c5c..ff9d01259 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -7,7 +7,7 @@ import java.util.Collections import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId import core.settings.IvySettings -import plugins.resolver.{DependencyResolver, IBiblioResolver} +import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} private object ConvertResolver @@ -29,6 +29,7 @@ private object ConvertResolver val resolver = new PluginCapableResolver initializeMavenStyle(resolver, repo.name, repo.root) resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + initializeBasic(resolver) resolver } case r: JavaNet1Repository => @@ -38,6 +39,7 @@ private object ConvertResolver val resolver = new IBiblioResolver { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") + initializeBasic(resolver) resolver } case repo: SshRepository => @@ -45,12 +47,14 @@ private object ConvertResolver val resolver = new SshResolver initializeSSHResolver(resolver, repo) repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + initializeBasic(resolver) resolver } case repo: SftpRepository => { val resolver = new SFTPResolver initializeSSHResolver(resolver, repo) + initializeBasic(resolver) resolver } case repo: FileRepository => @@ -61,6 +65,7 @@ private object ConvertResolver import repo.configuration.{isLocal, isTransactional} resolver.setLocal(isLocal) isTransactional.foreach(value => resolver.setTransactional(value.toString)) + initializeBasic(resolver) resolver } case repo: URLRepository => @@ -68,12 +73,17 @@ private object ConvertResolver val resolver = new URLResolver resolver.setName(repo.name) initializePatterns(resolver, repo.patterns) + initializeBasic(resolver) resolver } case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) case repo: RawRepository => repo.resolver } } + private def initializeBasic(resolver: BasicResolver) + { + resolver.setDescriptor(BasicResolver.DESCRIPTOR_REQUIRED) + } private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) { resolver.setName(name) From d605408950221f8373eb31e5f2e1c331d8cebb26 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 1 Oct 2011 19:46:51 -0400 Subject: [PATCH 0158/1030] fixes #212. dependencies on plugins must be encoded in element. --- ivy/CustomPomParser.scala | 101 +++++++++++++++++++++++++++++++++++--- ivy/MakePom.scala | 21 ++++---- 2 files changed, 106 insertions(+), 16 deletions(-) diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index cc1fb37d0..8f64fd950 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -1,14 +1,18 @@ package sbt - import org.apache.ivy.{core, plugins} + import org.apache.ivy.{core, plugins, util} import core.module.id.ModuleRevisionId import core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} + import core.module.descriptor.{DefaultDependencyDescriptor, DependencyDescriptor} import plugins.parser.{m2, ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} import m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} import plugins.repository.Resource + import plugins.namespace.NamespaceTransformer + import util.extendable.ExtendableItem import java.io.{File, InputStream} import java.net.URL + import java.util.regex.Pattern final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { @@ -28,6 +32,7 @@ object CustomPomParser { val SbtVersionKey = "sbtVersion" val ScalaVersionKey = "scalaVersion" + val ExtraAttributesKey = "extraDependencyAttributes" // packagings that should be jars, but that Ivy doesn't handle as jars val JarPackagings = Set("eclipse-plugin") @@ -38,16 +43,37 @@ object CustomPomParser def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = { - import collection.JavaConverters._ + import collection.JavaConverters._ + // The element of the pom is used to store additional metadata for sbt plugins. + // This is done because the pom XSD does not appear to allow extra metadata anywhere else. + // The pom.xml does not need to be readable by maven because these are only enabled for sbt plugins. + // However, the pom.xml needs to be valid because other tools, like repository managers may read the pom.xml. val properties = PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap + + // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. + // These are attached to the module itself. val filtered = shouldBeUnqualified(properties) + + // Extracts extra attributes for the dependencies. + // Because the tag in pom.xml cannot include additional metadata, + // sbt includes extra attributes in a 'extraDependencyAttributes' property. + // This is read/written from/to a pure string (no element structure) because Ivy only + // parses the immediate text nodes of the property. + val extraDepAttributes = getDependencyExtra(filtered) + + // Fixes up the detected extension in some cases missed by Ivy. val convertArtifacts = artifactExtIncorrect(md) - if(filtered.isEmpty && !convertArtifacts) md else addExtra(filtered, parser, md) + + val unqualify = filtered - ExtraAttributesKey + if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts) + md + else + addExtra(unqualify, extraDepAttributes, parser, md) } private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = - m.filter { case (k,_) => k == SbtVersionKey || k == ScalaVersionKey } + m.filter { case (SbtVersionKey | ScalaVersionKey | ExtraAttributesKey,_) => true; case _ => false } private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = @@ -55,13 +81,74 @@ object CustomPomParser private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = { import collection.JavaConverters._ - val oldExtra = id.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala + val oldExtra = qualifiedExtra(id) val newExtra = (oldExtra ++ properties).asJava ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, newExtra) } + private[this] def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String,String]] = + (m get ExtraAttributesKey) match { + case None => Map.empty + case Some(str) => + def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include=true)) + readDependencyExtra(str).map(processDep).toMap + } + + def qualifiedExtra(item: ExtendableItem): Map[String,String] = + { + import collection.JavaConverters._ + item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala.toMap + } + def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String,String] = + (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) + + def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = + s.flatMap { dd => + val revId = dd.getDependencyRevisionId + if(filterCustomExtra(revId, include=true).isEmpty) + Nil + else + revId.encodeToString :: Nil + } + + // parses the sequence of dependencies with extra attribute information, with one dependency per line + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = + LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) + + private[this] val LinesP = Pattern.compile("(?m)^") + + def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) + + // Reduces the id to exclude custom extra attributes + // This makes the id suitable as a key to associate a dependency parsed from a element + // with the extra attributes from the section + def simplify(id: ModuleRevisionId): ModuleRevisionId = + { + import collection.JavaConverters._ + ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include=false).asJava) + } + + private[this] def addExtra(dep: DependencyDescriptor, extra: Map[ModuleRevisionId, Map[String, String]]): DependencyDescriptor = + { + val extras = if(extra.isEmpty) None else extra get simplify(dep.getDependencyRevisionId) + extras match { + case None => dep + case Some(extraAttrs) => transform(dep, revId => addExtra(extraAttrs, revId)) + } + } + private[this] def transform(dep: DependencyDescriptor, f: ModuleRevisionId => ModuleRevisionId): DependencyDescriptor = + DefaultDependencyDescriptor.transformInstance(dep, namespaceTransformer(dep.getDependencyRevisionId, f), false) + private[this] def extraTransformer(txId: ModuleRevisionId, extra: Map[String, String]): NamespaceTransformer = + namespaceTransformer(txId, revId => addExtra(extra, revId) ) + + private[this] def namespaceTransformer(txId: ModuleRevisionId, f: ModuleRevisionId => ModuleRevisionId): NamespaceTransformer = + new NamespaceTransformer { + def transform(revId: ModuleRevisionId): ModuleRevisionId = if(revId == txId) f(revId) else revId + def isIdentity = false + } + import collection.JavaConverters._ - def addExtra(properties: Map[String, String], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + def addExtra(properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String,String]], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = { val dmd = new DefaultModuleDescriptor(parser, md.getResource) @@ -81,7 +168,7 @@ object CustomPomParser for(l <- md.getLicenses) dmd.addLicense(l) for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) - for( dd <- md.getDependencies ) dmd.addDependency(dd) + for( dd <- md.getDependencies ) dmd.addDependency(addExtra(dd, dependencyExtra)) for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( mrid, resolvedMrid, ed.getLocation, ed.getExtendsTypes) ) for( conf <- md.getConfigurations) { diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index fc0a90c16..262a1ee35 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -46,8 +46,11 @@ class MakePom(val log: Logger) { makeStartYear(moduleInfo) } { makeOrganization(moduleInfo) } { extra } - { makeProperties(module) } - { makeDependencies(module, configurations) } + { + val deps = depsInConfs(module, configurations) + makeProperties(module, deps) ++ + makeDependencies(deps) + } { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) @@ -74,10 +77,12 @@ class MakePom(val log: Logger) { moduleInfo.organizationHomepage map { h => {h} } getOrElse NodeSeq.Empty } } - def makeProperties(module: ModuleDescriptor): NodeSeq = + def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) - if(extra.isEmpty) NodeSeq.Empty else makeProperties(extra) + val depExtra = CustomPomParser.writeDependencyExtra(dependencies).mkString("\n") + val allExtra = if(depExtra.isEmpty) extra else extra.updated(CustomPomParser.ExtraAttributesKey, depExtra) + if(allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) } def makeProperties(extra: Map[String,String]): NodeSeq = { @@ -110,15 +115,13 @@ class MakePom(val log: Logger) } val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) - def makeDependencies(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): NodeSeq = - { - val dependencies = depsInConfs(module, configurations) - if(dependencies.isEmpty) NodeSeq.Empty + def makeDependencies(dependencies: Seq[DependencyDescriptor]): NodeSeq = + if(dependencies.isEmpty) + NodeSeq.Empty else { dependencies.map(makeDependency) } - } def makeDependency(dependency: DependencyDescriptor): NodeSeq = { From 2f52a17b6b7c2f5fa3d1807a543f5e3a3844a61e Mon Sep 17 00:00:00 2001 From: Jan Berkel Date: Mon, 10 Oct 2011 18:10:47 +0200 Subject: [PATCH 0159/1030] Added support for in makePom Avoid second call to getExtraAttribute --- ivy/MakePom.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 262a1ee35..b85334e97 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -132,6 +132,7 @@ class MakePom(val log: Logger) {mrid.getName} {mrid.getRevision} { scopeAndOptional(dependency) } + { classifier(dependency) } { val (warns, excls) = List.separate(excl.map(makeExclusion)) if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) @@ -144,6 +145,13 @@ class MakePom(val log: Logger) } + def classifier(dependency: DependencyDescriptor): Seq[scala.xml.Node] = + { + for (da <- dependency.getAllDependencyArtifacts; + cl <- Option(da.getExtraAttribute("classifier"))) yield + {cl} + } + def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = { val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) @@ -238,4 +246,4 @@ class MakePom(val log: Logger) } module.getDependencies flatMap translate } -} \ No newline at end of file +} From 31e4e5682f7b94c69f1d5dc832a6df9d0bb39af1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 16 Oct 2011 17:27:36 -0400 Subject: [PATCH 0160/1030] drop configurations when storing unavailable classifiers. fixes #46 --- ivy/IvyActions.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 3a40aadf0..ff53041ef 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -170,7 +170,7 @@ object IvyActions { import config.{configuration => c, ivyScala, module => mod} import mod.{configurations => confs, id, modules => deps} - val base = restrictedCopy(id).copy(name = id.name + "$" + label) + val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) val newConfig = config.copy(module = mod.copy(modules = report.allModules)) @@ -181,28 +181,31 @@ object IvyActions import config.{configuration => c, module => mod, _} import mod.{configurations => confs, _} assert(!classifiers.isEmpty, "classifiers cannot be empty") - val baseModules = modules map restrictedCopy + val baseModules = modules map { m => restrictedCopy(m, true) } val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) - val base = restrictedCopy(id).copy(name = id.name + classifiers.mkString("$","_","")) + val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$","_","")) val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) update(module, upConf, log) } def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { - val excluded = exclude getOrElse(m, Set.empty) + val excluded = exclude getOrElse(restrictedCopy(m, false), Set.empty) val included = classifiers filterNot excluded if(included.isEmpty) None else Some(m.copy(explicitArtifacts = classifiedArtifacts(m.name, included) )) } def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = - report.addMissing { id => classifiedArtifacts(id.name, classifiers filter exclude.getOrElse(id, Set.empty[String])) } + report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = classifiers map { c => Artifact.classified(name, c) } + private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = + exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } + report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } - private[this] def restrictedCopy(m: ModuleID) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = m.configurations) + private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = + ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions From 34260c022aa035a715b55939c3751c38d532f57e Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Wed, 26 Oct 2011 21:43:42 +0530 Subject: [PATCH 0161/1030] Use IO.write instead of explicit resource management --- ivy/MakePom.scala | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index b85334e97..50b23d920 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -7,7 +7,7 @@ package sbt; -import java.io.{BufferedWriter, File, OutputStreamWriter, FileOutputStream} +import java.io.File import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter, XML} import Configurations.Optional @@ -20,21 +20,13 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) { - def encoding = "UTF-8" def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = write(process(toPom(ivy, module, moduleInfo, configurations, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) { - output.getParentFile.mkdirs() - val out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(output), encoding)) - try - { - out.write("" + newline) - out.write(xmlString) - } - finally { out.close() } + IO.write(output, "" + newline + xmlString) } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) From 8c1c2a8c1d37aecefdcd600471a12c68123ec9f1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 26 Oct 2011 19:28:26 -0400 Subject: [PATCH 0162/1030] use Charset.name instead of toString (which currently calls name) --- ivy/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 50b23d920..21099e929 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -26,7 +26,7 @@ class MakePom(val log: Logger) def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) { - IO.write(output, "" + newline + xmlString) + IO.write(output, "" + newline + xmlString) } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) From 579938b72e07dbe921560b60fb8bd1d26206c11b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 30 Oct 2011 18:38:37 -0400 Subject: [PATCH 0163/1030] track whether UpdateReport was cached or freshly generated --- ivy/IvyRetrieve.scala | 2 +- ivy/UpdateReport.scala | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index 7c96c63ff..cd619afaf 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -50,7 +50,7 @@ object IvyRetrieve def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report)) def updateStats(report: ResolveReport): UpdateStats = - new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize) + new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) } diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 241ecded5..6f8485c9d 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -10,8 +10,9 @@ package sbt * This means that for a given configuration, there should only be one revision for a given organization and module name. * @param cachedDescriptor the location of the resolved module descriptor in the cache * @param configurations a sequence containing one report for each configuration resolved. +* @param stats information about the update that produced this report * @see sbt.RichUpdateReport - */ +*/ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats) { override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString @@ -126,7 +127,7 @@ object UpdateReport } } } -final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long) +final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") } \ No newline at end of file From f478b0b907b98453d2e726a7983c42bc9866bb87 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 4 Nov 2011 12:19:45 -0400 Subject: [PATCH 0164/1030] log during resolution --- ivy/Ivy.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index c0936c1ee..3cac60e0b 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -11,12 +11,12 @@ import java.util.{Collection, Collections => CS} import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} -import core.IvyPatternHelper +import core.{IvyPatternHelper, LogOptions} import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import core.resolve.IvyNode +import core.resolve.{IvyNode, ResolveData} import core.settings.IvySettings import plugins.conflict.{ConflictManager, LatestCompatibleConflictManager, LatestConflictManager} import plugins.latest.LatestRevisionStrategy @@ -218,6 +218,12 @@ private object IvySbt // It would be better to get proper support into Ivy. override def locate(artifact: IArtifact) = if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = + { + if(data.getOptions.getLog != LogOptions.LOG_QUIET) + log.info("Resolving " + dd.getDependencyRevisionId + " ...") + super.getDependency(dd, data) + } } newDefault.setName(name) newDefault.setReturnFirst(true) From 2eab86bf25080b0651f28acba309a381f29a3d9f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 4 Nov 2011 12:36:26 -0400 Subject: [PATCH 0165/1030] add missing newline in conflict warning --- ivy/ConflictWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index 92ae38cbb..738ab50fc 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -12,7 +12,7 @@ object ConflictWarning val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) { - val msg = "Potentially incompatible versions of dependencies of " + config.label + ":" + val msg = "Potentially incompatible versions of dependencies of " + config.label + ":\n " val conflictMsgs = for( (label, versions) <- conflicts ) yield label + ": " + versions.mkString(", ") From 226db8b597db0ce32722ff0e16acace7bb940a77 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 9 Nov 2011 18:30:35 -0500 Subject: [PATCH 0166/1030] only require descriptors for dependencies without an explicit URL. fixes #263 --- ivy/ConvertResolver.scala | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/ivy/ConvertResolver.scala b/ivy/ConvertResolver.scala index ff9d01259..293963a2d 100644 --- a/ivy/ConvertResolver.scala +++ b/ivy/ConvertResolver.scala @@ -6,6 +6,8 @@ package sbt import java.util.Collections import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId +import core.module.descriptor.DependencyDescriptor +import core.resolve.ResolveData import core.settings.IvySettings import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} @@ -20,7 +22,7 @@ private object ConvertResolver case repo: MavenRepository => { val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver { + final class PluginCapableResolver extends IBiblioResolver with DescriptorRequired { def setPatterns() { // done this way for access to protected methods. setArtifactPatterns(pattern) setIvyPatterns(pattern) @@ -29,60 +31,63 @@ private object ConvertResolver val resolver = new PluginCapableResolver initializeMavenStyle(resolver, repo.name, repo.root) resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - initializeBasic(resolver) resolver } case r: JavaNet1Repository => { // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html - val resolver = new IBiblioResolver { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } + val resolver = new IBiblioResolver with DescriptorRequired { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") - initializeBasic(resolver) resolver } case repo: SshRepository => { - val resolver = new SshResolver + val resolver = new SshResolver with DescriptorRequired initializeSSHResolver(resolver, repo) repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - initializeBasic(resolver) resolver } case repo: SftpRepository => { val resolver = new SFTPResolver initializeSSHResolver(resolver, repo) - initializeBasic(resolver) resolver } case repo: FileRepository => { - val resolver = new FileSystemResolver + val resolver = new FileSystemResolver with DescriptorRequired resolver.setName(repo.name) initializePatterns(resolver, repo.patterns) import repo.configuration.{isLocal, isTransactional} resolver.setLocal(isLocal) isTransactional.foreach(value => resolver.setTransactional(value.toString)) - initializeBasic(resolver) resolver } case repo: URLRepository => { - val resolver = new URLResolver + val resolver = new URLResolver with DescriptorRequired resolver.setName(repo.name) initializePatterns(resolver, repo.patterns) - initializeBasic(resolver) resolver } case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) case repo: RawRepository => repo.resolver } } - private def initializeBasic(resolver: BasicResolver) + private sealed trait DescriptorRequired extends BasicResolver { - resolver.setDescriptor(BasicResolver.DESCRIPTOR_REQUIRED) + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = + { + val prev = descriptorString(isAllownomd) + setDescriptor(descriptorString(hasExplicitURL(dd))) + try super.getDependency(dd, data) finally setDescriptor(prev) + } + def descriptorString(optional: Boolean) = + if(optional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED + def hasExplicitURL(dd: DependencyDescriptor): Boolean = + dd.getAllDependencyArtifacts.exists(_.getUrl != null) } private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) { From c597ec1e5e5964c179ce24946f9d25e25269ea47 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Wed, 16 Nov 2011 14:04:16 +0530 Subject: [PATCH 0167/1030] Support for enhanced cross build suffix in dependencies. Closes #267 Overloading `%%` for library dependency to allow using a library built with an alternative version of Scala that is different from the Scala version used in the current build (but hopefully binary compatible). This is useful in cases, where the binary build of a dependency with the exact Scala version isn't yet available but an otherwise binary compatible build (maybe with a previous Scala release) is available. --- ivy/DependencyBuilders.scala | 15 ++++++++------- ivy/Ivy.scala | 2 +- ivy/IvyActions.scala | 4 ++-- ivy/IvyInterface.scala | 12 ++++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/ivy/DependencyBuilders.scala b/ivy/DependencyBuilders.scala index 00168d7c1..68a30b122 100644 --- a/ivy/DependencyBuilders.scala +++ b/ivy/DependencyBuilders.scala @@ -4,7 +4,7 @@ package sbt package impl - import StringUtilities.{appendable,nonEmpty} +import StringUtilities.nonEmpty trait DependencyBuilders { @@ -27,20 +27,21 @@ trait DependencyBuilders final class GroupID private[sbt] (groupID: String) { - def % (artifactID: String) = groupArtifact(artifactID, false) - def %% (artifactID: String) = groupArtifact(artifactID, true) - private def groupArtifact(artifactID: String, cross: Boolean) = + def % (artifactID: String) = groupArtifact(artifactID, None) + def %% (artifactID: String, crossVersion: String => String = identity) = groupArtifact(artifactID, Some(crossVersion)) + def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, Some(Map(alternatives: _*) orElse { case s => s })) + private def groupArtifact(artifactID: String, cross: Option[String => String]) = { nonEmpty(artifactID, "Artifact ID") new GroupArtifactID(groupID, artifactID, cross) } } -final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: Boolean) -{ +final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: Option[String => String]) +{ def % (revision: String): ModuleID = { nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(crossVersion) + ModuleID(groupID, artifactID, revision).cross(!crossVersion.isEmpty, crossVersion.getOrElse(identity)) } } final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 3cac60e0b..19252fb28 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -314,7 +314,7 @@ private object IvySbt as.map(art => substituteCross(art, cross)) def substituteCross(m: ModuleID, cross: String): ModuleID = if(m.crossVersion) - m.copy(name = crossName(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + m.copy(name = crossName(m.name, m.crossVersionRemap(cross)), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) else m diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index ff53041ef..07b2740d1 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -205,7 +205,7 @@ object IvyActions report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) + ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, crossVersionRemap = m.crossVersionRemap, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions @@ -268,4 +268,4 @@ object IvyActions } } -final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) \ No newline at end of file +final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 9f5b0c630..7bf72b0dc 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,14 +9,14 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false) +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false, crossVersionRemap: String => String = identity) { override def toString = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + (if(extraAttributes.isEmpty) "" else " " + extraString) def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") - def cross(v: Boolean) = copy(crossVersion = v) + def cross(v: Boolean, verRemap: String => String = identity) = copy(crossVersion = v, crossVersionRemap = verRemap) // () required for chaining def notTransitive() = intransitive() def intransitive() = copy(isTransitive = false) @@ -282,7 +282,7 @@ object Resolver def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) } - private[sbt] def resolvePattern(base: String, pattern: String): String = + private[sbt] def resolvePattern(base: String, pattern: String): String = { val normBase = base.replace('\\', '/') if(normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern @@ -423,14 +423,14 @@ object Artifact { import artifact._ val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - val base = if(module.crossVersion) IvySbt.crossName(artifact.name, scalaVersion) else artifact.name + val base = if(module.crossVersion) IvySbt.crossName(artifact.name, module.crossVersionRemap(scalaVersion)) else artifact.name base + "-" + module.revision + classifierStr + "." + artifact.extension } def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) + def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, DefaultType) def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) @@ -440,4 +440,4 @@ object ModuleConfiguration { def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) -} \ No newline at end of file +} From b31c510f389a639e24e5902c400158ee34f426c1 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sun, 20 Nov 2011 00:10:43 +0530 Subject: [PATCH 0168/1030] Add classifier for 'jar' artifact type only. Closes #257. --- ivy/MakePom.scala | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 21099e929..60127c603 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -49,7 +49,7 @@ class MakePom(val log: Logger) def makeModuleID(module: ModuleDescriptor): NodeSeq = { val mrid = moduleDescriptor(module) - val a: NodeSeq = + val a: NodeSeq = ({ mrid.getOrganisation } { mrid.getName } { packaging(module) }) @@ -137,11 +137,16 @@ class MakePom(val log: Logger) } - def classifier(dependency: DependencyDescriptor): Seq[scala.xml.Node] = + def classifier(dependency: DependencyDescriptor): NodeSeq = { - for (da <- dependency.getAllDependencyArtifacts; - cl <- Option(da.getExtraAttribute("classifier"))) yield - {cl} + val jarDep = dependency.getAllDependencyArtifacts.filter(_.getType == Artifact.DefaultType).headOption + jarDep match { + case Some(a) => { + val cl = a.getExtraAttribute("classifier") + if (cl != null) {cl} else NodeSeq.Empty + } + case _ => NodeSeq.Empty + } } def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = From 4e7f7092ae0e5e41756f4ace20238de902721a87 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sun, 20 Nov 2011 00:51:04 +0530 Subject: [PATCH 0169/1030] Cleanups activities - extract exclusion block to separate method - replace simple cases of mapping over function with pattern matching --- ivy/MakePom.scala | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 60127c603..180f41622 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -8,7 +8,7 @@ package sbt; import java.io.File -import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter, XML} +import scala.xml.{Node, NodeSeq, PrettyPrinter} import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} @@ -20,17 +20,17 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) { - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: Node => Node, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = write(process(toPom(ivy, module, moduleInfo, configurations, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n - def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") + def write(node: Node, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) { IO.write(output, "" + newline + xmlString) } - def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): Node = ( 4.0.0 { makeModuleID(module) } @@ -61,12 +61,19 @@ class MakePom(val log: Logger) a ++ b } - def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = moduleInfo.startYear map { y => {y} } getOrElse NodeSeq.Empty + def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = + moduleInfo.startYear match { + case Some(y) => {y} + case _ => NodeSeq.Empty + } def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = { {moduleInfo.organizationName} - { moduleInfo.organizationHomepage map { h => {h} } getOrElse NodeSeq.Empty } + { moduleInfo.organizationHomepage match { + case Some(h) => {h} + case _ => NodeSeq.Empty + }} } def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = @@ -118,22 +125,13 @@ class MakePom(val log: Logger) def makeDependency(dependency: DependencyDescriptor): NodeSeq = { val mrid = dependency.getDependencyRevisionId - val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) {mrid.getOrganisation} {mrid.getName} {mrid.getRevision} { scopeAndOptional(dependency) } { classifier(dependency) } - { - val (warns, excls) = List.separate(excl.map(makeExclusion)) - if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) - if(excls.isEmpty) NodeSeq.Empty - else - - { excls } - - } + { exclusions(dependency) } } @@ -177,6 +175,14 @@ class MakePom(val log: Logger) (scope, !opt.isEmpty) } + def exclusions(dependency: DependencyDescriptor): NodeSeq = + { + val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) + val (warns, excls) = List.separate(excl.map(makeExclusion)) + if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) + if(!excls.isEmpty) {excls} + else NodeSeq.Empty + } def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = { val m = exclRule.getId.getModuleId @@ -217,9 +223,9 @@ class MakePom(val log: Logger) def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id - def mavenRepository(repo: MavenRepository): XNode = + def mavenRepository(repo: MavenRepository): Node = mavenRepository(toID(repo.name), repo.name, repo.root) - def mavenRepository(id: String, name: String, root: String): XNode = + def mavenRepository(id: String, name: String, root: String): Node = {id} {name} From 7141000e659864339f3f6aed982f05f4f6b23770 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 19 Nov 2011 18:17:20 -0500 Subject: [PATCH 0170/1030] revert XNode/Node rename because of shadowing when running full API doc generation --- ivy/MakePom.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 180f41622..c2e70e9a4 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -8,7 +8,9 @@ package sbt; import java.io.File -import scala.xml.{Node, NodeSeq, PrettyPrinter} +// Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow +// scala.xml.Node when generating aggregated API documentation +import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter} import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} @@ -20,17 +22,17 @@ import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) { - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: Node => Node, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = write(process(toPom(ivy, module, moduleInfo, configurations, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n - def write(node: Node, output: File): Unit = write(toString(node), output, "\n") + def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) { IO.write(output, "" + newline + xmlString) } - def toString(node: Node): String = new PrettyPrinter(1000, 4).format(node) - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): Node = + def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = ( 4.0.0 { makeModuleID(module) } @@ -223,9 +225,9 @@ class MakePom(val log: Logger) def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id - def mavenRepository(repo: MavenRepository): Node = + def mavenRepository(repo: MavenRepository): XNode = mavenRepository(toID(repo.name), repo.name, repo.root) - def mavenRepository(id: String, name: String, root: String): Node = + def mavenRepository(id: String, name: String, root: String): XNode = {id} {name} From 31f5133ff634164bbe480c3a3ddcc8f6291ca68d Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Tue, 22 Nov 2011 02:08:16 +0530 Subject: [PATCH 0171/1030] Miscellaneous updates - honor includeTypes to filter dependency artifact candidates for classifier setting - prefer the more stable Seq[_] instead of Iterable[_] - import cleanups --- ivy/IvyActions.scala | 32 +++++++++++++------------------- ivy/MakePom.scala | 27 ++++++++++++++++----------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 07b2740d1..1cabd0a31 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -4,21 +4,15 @@ package sbt import java.io.File -import scala.xml.{Node => XNode,NodeSeq} +import scala.xml.{Node => XNode, NodeSeq} import org.apache.ivy.{core, plugins, Ivy} -import core.cache.DefaultRepositoryCacheManager -import core.{IvyPatternHelper,LogOptions} +import core.{IvyPatternHelper, LogOptions} import core.deliver.DeliverOptions import core.install.InstallOptions -import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import core.publish.PublishOptions -import core.report.{ArtifactDownloadReport,ResolveReport} +import core.module.descriptor.{Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor} +import core.report.ResolveReport import core.resolve.ResolveOptions -import core.retrieve.RetrieveOptions -import plugins.parser.m2.{PomModuleDescriptorParser,PomModuleDescriptorWriter} import plugins.resolver.{BasicResolver, DependencyResolver} final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) @@ -26,7 +20,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean) +final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType)) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) @@ -66,9 +60,9 @@ object IvyActions /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { - import configuration.{allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process} + import configuration.{allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes} module.withModule(log) { (ivy, md, default) => - (new MakePom(log)).write(ivy, md, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, file) + (new MakePom(log)).write(ivy, md, moduleInfo, configurations, includeTypes, extra, process, filterRepositories, allRepositories, file) log.info("Wrote " + file.getAbsolutePath) } } @@ -168,8 +162,8 @@ object IvyActions def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { - import config.{configuration => c, ivyScala, module => mod} - import mod.{configurations => confs, id, modules => deps} + import config.{configuration => c, ivyScala, module => mod} + import mod.{id, modules => deps} val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) val report = update(module, c, log) @@ -178,8 +172,8 @@ object IvyActions } def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { - import config.{configuration => c, module => mod, _} - import mod.{configurations => confs, _} + import config.{configuration => c, module => mod, _} + import mod.{configurations => confs, _} assert(!classifiers.isEmpty, "classifiers cannot be empty") val baseModules = modules map { m => restrictedCopy(m, true) } val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) @@ -223,7 +217,7 @@ object IvyActions } private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) - + private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = { val toCopy = new collection.mutable.HashSet[(File,File)] @@ -255,7 +249,7 @@ object IvyActions case Full => LOG_DEFAULT } - def publish(module: ModuleDescriptor, artifacts: Iterable[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = + def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); for( (artifact, file) <- artifacts) if(file.exists) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index c2e70e9a4..e2b5f1778 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -5,7 +5,7 @@ // based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 -package sbt; +package sbt import java.io.File // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow @@ -15,15 +15,17 @@ import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} import core.settings.IvySettings -import core.module.{descriptor, id} +import core.module.descriptor import descriptor.{DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} -import id.ModuleRevisionId import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) { + @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(process(toPom(ivy, module, moduleInfo, configurations, extra, filterRepositories, allRepositories)), output) + write(ivy, module, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], Set(Artifact.DefaultType), extra, process, filterRepositories, allRepositories, output) + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + write(process(toPom(ivy, module, moduleInfo, configurations, includeTypes, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String) @@ -32,7 +34,10 @@ class MakePom(val log: Logger) } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) + @deprecated("Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", "0.11.2") def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + toPom(ivy, module, moduleInfo, configurations, Set(Artifact.DefaultType), extra, filterRepositories, allRepositories) + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = ( 4.0.0 { makeModuleID(module) } @@ -43,7 +48,7 @@ class MakePom(val log: Logger) { val deps = depsInConfs(module, configurations) makeProperties(module, deps) ++ - makeDependencies(deps) + makeDependencies(deps, includeTypes) } { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) @@ -116,15 +121,15 @@ class MakePom(val log: Logger) } val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) - def makeDependencies(dependencies: Seq[DependencyDescriptor]): NodeSeq = + def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = if(dependencies.isEmpty) NodeSeq.Empty else - { dependencies.map(makeDependency) } + { dependencies.map(makeDependency(_, includeTypes)) } - def makeDependency(dependency: DependencyDescriptor): NodeSeq = + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { val mrid = dependency.getDependencyRevisionId @@ -132,14 +137,14 @@ class MakePom(val log: Logger) {mrid.getName} {mrid.getRevision} { scopeAndOptional(dependency) } - { classifier(dependency) } + { classifier(dependency, includeTypes) } { exclusions(dependency) } } - def classifier(dependency: DependencyDescriptor): NodeSeq = + def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { - val jarDep = dependency.getAllDependencyArtifacts.filter(_.getType == Artifact.DefaultType).headOption + val jarDep = dependency.getAllDependencyArtifacts.filter(d => includeTypes(d.getType)).headOption jarDep match { case Some(a) => { val cl = a.getExtraAttribute("classifier") From 3817c0ce480a1fb4b9f110c2e317bb71aebfb6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E5=8D=9A?= Date: Tue, 13 Dec 2011 00:08:18 +0800 Subject: [PATCH 0172/1030] Allow `ModuleID % Configuration` --- ivy/DependencyBuilders.scala | 2 ++ 1 file changed, 2 insertions(+) mode change 100644 => 100755 ivy/DependencyBuilders.scala diff --git a/ivy/DependencyBuilders.scala b/ivy/DependencyBuilders.scala old mode 100644 new mode 100755 index 68a30b122..b878f206c --- a/ivy/DependencyBuilders.scala +++ b/ivy/DependencyBuilders.scala @@ -46,6 +46,8 @@ final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, c } final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { + def % (configuration: Configuration): ModuleID = %(configuration.name) + def % (configurations: String): ModuleID = { nonEmpty(configurations, "Configurations") From bb30184470a108168bd515c3a16c90b22d5d030c Mon Sep 17 00:00:00 2001 From: "Eric J. Christeson" Date: Fri, 30 Dec 2011 11:49:43 -0600 Subject: [PATCH 0173/1030] Remove trailing whitespace from entries in credentials file --- ivy/Credentials.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index 4ca13d7a3..09e86d579 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -64,10 +64,10 @@ object Credentials { val properties = new java.util.Properties IO.load(properties, from) - properties map { case (k,v) => (k.toString, v.toString) } toMap; + properties map { case (k,v) => (k.toString, v.toString.trim) } toMap; } } sealed trait Credentials final class FileCredentials(val path: File) extends Credentials -final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials \ No newline at end of file +final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials From 45e097e28148699910afa2b0c585ab38b201553e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 22 Jan 2012 22:06:52 -0500 Subject: [PATCH 0174/1030] org.scala-tools.sbt -> org.scala-sbt and dropping scala-tools.org from defaults --- ivy/ComponentManager.scala | 2 +- ivy/ConflictWarning.scala | 2 +- ivy/IvyInterface.scala | 3 +-- ivy/IvyScala.scala | 4 ++++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/ComponentManager.scala b/ivy/ComponentManager.scala index 32979ab3b..de87a9890 100644 --- a/ivy/ComponentManager.scala +++ b/ivy/ComponentManager.scala @@ -61,7 +61,7 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr /** Retrieve the file for component 'id' from the local repository. */ private def update(id: String): Unit = ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar)) ) - private def sbtModuleID(id: String) = ModuleID("org.scala-tools.sbt", id, ComponentManager.stampedVersion) + private def sbtModuleID(id: String) = ModuleID(SbtArtifacts.Organization, id, ComponentManager.stampedVersion) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index 738ab50fc..befe4abd6 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -5,7 +5,7 @@ package sbt final case class ConflictWarning(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) object ConflictWarning { - def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter("org.scala-tools.sbt") | GlobFilter("org.scala-lang")), (_: ModuleID).organization, Level.Warn, false) + def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), (_: ModuleID).organization, Level.Warn, false) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 7bf72b0dc..8d921c2ec 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -199,8 +199,7 @@ object Resolver def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = Seq(Resolver.defaultLocal) ++ userResolvers ++ - single(DefaultMavenRepository, mavenCentral)++ - single(ScalaToolsReleases, scalaTools) + single(DefaultMavenRepository, mavenCentral) private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if(nonEmpty) Seq(value) else Nil /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 9926f7141..54f95ccf6 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -19,6 +19,10 @@ object ScalaArtifacts val CompilerID = "scala-compiler" def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) } +object SbtArtifacts +{ + val Organization = "org.scala-sbt" +} import ScalaArtifacts._ From 80589d1f5ba039a683d04df0fbe4fb0e1f8a451b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 22 Jan 2012 22:06:53 -0500 Subject: [PATCH 0175/1030] rework cross versioning to account for prerelease Scala versions --- ivy/CrossVersion.scala | 94 ++++++++++++++++++++++++++++++++++++ ivy/DependencyBuilders.scala | 19 +++++--- ivy/Ivy.scala | 21 +++----- ivy/IvyActions.scala | 18 +++---- ivy/IvyInterface.scala | 17 +++++-- ivy/IvyScala.scala | 13 ++--- 6 files changed, 142 insertions(+), 40 deletions(-) create mode 100644 ivy/CrossVersion.scala diff --git a/ivy/CrossVersion.scala b/ivy/CrossVersion.scala new file mode 100644 index 000000000..59b51c795 --- /dev/null +++ b/ivy/CrossVersion.scala @@ -0,0 +1,94 @@ +package sbt + +final case class ScalaVersion(full: String, binary: String) + +sealed trait CrossVersion +object CrossVersion +{ + val TransitionScalaVersion = "2.10" + val TransitionSbtVersion = "0.12" + + object Disabled extends CrossVersion { override def toString = "disabled" } + final class Binary(val remapVersion: String => String) extends CrossVersion { + override def toString = "Binary" + } + final class Full(val remapVersion: String => String) extends CrossVersion { + override def toString = "Full" + } + + def full: CrossVersion = new Full(idFun) + def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + + def binary: CrossVersion = new Binary(idFun) + def binaryMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + + private[this] def idFun[T]: T => T = x => x + def append(s: String): Option[String => String] = Some(x => crossName(x, s)) + + def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = + cross match + { + case Disabled => None + case b: Binary => append(b.remapVersion(binaryVersion)) + case f: Full => append(f.remapVersion(fullVersion)) + } + + def apply(module: ModuleID, is: IvyScala): Option[String => String] = + CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) + + def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = + is flatMap { i => apply(module, i) } + + def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + cross match { + case None => artifacts + case Some(is) => substituteCrossA(artifacts, cross) + } + + def applyCross(s: String, fopt: Option[String => String]): String = + fopt match { + case None => s + case Some(fopt) => fopt(s) + } + + def crossName(name: String, cross: String): String = + name + "_" + cross + def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = + a.copy(name = applyCross(a.name, cross)) + def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + as.map(art => substituteCross(art, cross)) + + def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => + { + val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) + if(cross.isDefined) + m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + else + m + } + + def isStable(v: String): Boolean = !v.contains("-") + def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full + + val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + def partialVersion(s: String): Option[(Int,Int)] = + s match { + case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) + case _ => None + } + private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = + major > minMajor || (major == minMajor && minor >= minMinor) + + def binaryScalaVersion(full: String): String = binaryVersion(full, TransitionScalaVersion) + def binarySbtVersion(full: String): String = binaryVersion(full, TransitionSbtVersion) + def binaryVersion(full: String, cutoff: String): String = + { + def sub(major: Int, minor: Int) = major + "." + minor + (partialVersion(full), partialVersion(cutoff)) match { + case (Some((major, minor)), None) => sub(major, minor) + case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) + case _ => full + } + } +} + diff --git a/ivy/DependencyBuilders.scala b/ivy/DependencyBuilders.scala index b878f206c..7d5812aaf 100755 --- a/ivy/DependencyBuilders.scala +++ b/ivy/DependencyBuilders.scala @@ -27,21 +27,28 @@ trait DependencyBuilders final class GroupID private[sbt] (groupID: String) { - def % (artifactID: String) = groupArtifact(artifactID, None) - def %% (artifactID: String, crossVersion: String => String = identity) = groupArtifact(artifactID, Some(crossVersion)) - def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, Some(Map(alternatives: _*) orElse { case s => s })) - private def groupArtifact(artifactID: String, cross: Option[String => String]) = + def % (artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) + def %% (artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) + + @deprecated(deprecationMessage, "0.12.0") + def %% (artifactID: String, crossVersion: String => String) = groupArtifact(artifactID, CrossVersion.binaryMapped(crossVersion)) + @deprecated(deprecationMessage, "0.12.0") + def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, CrossVersion.binaryMapped(Map(alternatives: _*) orElse { case s => s })) + + private def groupArtifact(artifactID: String, cross: CrossVersion) = { nonEmpty(artifactID, "Artifact ID") new GroupArtifactID(groupID, artifactID, cross) } + + private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" } -final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: Option[String => String]) +final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: CrossVersion) { def % (revision: String): ModuleID = { nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(!crossVersion.isEmpty, crossVersion.getOrElse(identity)) + ModuleID(groupID, artifactID, revision).cross(crossVersion) } } final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 19252fb28..400490086 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -299,24 +299,19 @@ private object IvySbt } private def substituteCross(m: ModuleSettings): ModuleSettings = - m.ivyScala match { case None => m; case Some(is) => substituteCross(m, is.substituteCross) } - private def substituteCross(m: ModuleSettings, sub: ModuleID => ModuleID): ModuleSettings = + m.ivyScala match { + case None => m + case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) + } + private def substituteCross(m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String): ModuleSettings = + { + val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub) case _ => m } - def crossName(name: String, cross: String): String = - name + "_" + cross - def substituteCross(a: Artifact, cross: String): Artifact = - a.copy(name = crossName(a.name, cross)) - def substituteCrossA(as: Seq[Artifact], cross: String): Seq[Artifact] = - as.map(art => substituteCross(art, cross)) - def substituteCross(m: ModuleID, cross: String): ModuleID = - if(m.crossVersion) - m.copy(name = crossName(m.name, m.crossVersionRemap(cross)), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) - else - m + } private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 1cabd0a31..059d48997 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -88,8 +88,8 @@ object IvyActions val resolver = ivy.getSettings.getResolver(resolverName) if(resolver eq null) error("Undefined resolver '" + resolverName + "'") val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } - val is = crossIvyScala(module.moduleSettings) - val as = mapArtifacts(md, is, artifacts) ++ ivyArtifact.toList + val cross = crossVersionMap(module.moduleSettings) + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = true) } } } @@ -102,18 +102,16 @@ object IvyActions try { act } finally { resolver.setChecksums(previous mkString ",") } } - private def crossIvyScala(moduleSettings: ModuleSettings): Option[IvyScala] = + private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { - case i: InlineConfiguration if i.module.crossVersion => i.ivyScala - case e: EmptyConfiguration if e.module.crossVersion => e.ivyScala + case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) + case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) case _ => None } - def substituteCross(ivyScala: Option[IvyScala], artifacts: Seq[Artifact]): Seq[Artifact] = - ivyScala match { case None => artifacts; case Some(is) => IvySbt.substituteCrossA(artifacts, is.scalaVersion) } - def mapArtifacts(module: ModuleDescriptor, ivyScala: Option[IvyScala], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = { val rawa = artifacts.keys.toSeq - val seqa = substituteCross(ivyScala, rawa) + val seqa = CrossVersion.substituteCross(rawa, cross) val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } } @@ -199,7 +197,7 @@ object IvyActions report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, crossVersionRemap = m.crossVersionRemap, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) + ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 8d921c2ec..d5ffc4d6a 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,14 +9,21 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: Boolean = false, crossVersionRemap: String => String = identity) +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + (if(extraAttributes.isEmpty) "" else " " + extraString) def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") - def cross(v: Boolean, verRemap: String => String = identity) = copy(crossVersion = v, crossVersionRemap = verRemap) + + @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) + @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) + + def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) + // () required for chaining def notTransitive() = intransitive() def intransitive() = copy(isTransitive = false) @@ -418,14 +425,14 @@ object Artifact val base = if(i >= 0) name.substring(0, i) else name Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) } - def artifactName(scalaVersion: String, module: ModuleID, artifact: Artifact): String = + def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { import artifact._ val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - val base = if(module.crossVersion) IvySbt.crossName(artifact.name, module.crossVersionRemap(scalaVersion)) else artifact.name + val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) + val base = CrossVersion.applyCross(artifact.name, cross) base + "-" + module.revision + classifierStr + "." + artifact.extension } - def cross(enable: Boolean, scalaVersion: String): String = if(enable) "_" + scalaVersion else "" val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 54f95ccf6..647df693f 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -26,7 +26,7 @@ object SbtArtifacts import ScalaArtifacts._ -final case class IvyScala(scalaVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, substituteCross: ModuleID => ModuleID) +final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) private object IvyScala { @@ -34,11 +34,11 @@ private object IvyScala def checkModule(module: DefaultModuleDescriptor, conf: String)(check: IvyScala) { if(check.checkExplicit) - checkDependencies(module, check.scalaVersion, check.configurations) + checkDependencies(module, check.scalaBinaryVersion, check.configurations) if(check.filterImplicit) excludeScalaJars(module, check.configurations) if(check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaVersion) + overrideScalaVersion(module, check.scalaFullVersion) } def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) { @@ -54,14 +54,15 @@ private object IvyScala /** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaVersion: String, configurations: Iterable[Configuration]) + private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration]) { val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) for(dep <- module.getDependencies.toList) { val id = dep.getDependencyRevisionId - if(id.getOrganisation == Organization && id.getRevision != scalaVersion && dep.getModuleConfigurations.exists(configSet)) - error("Version specified for dependency " + id + " differs from Scala version in project (" + scalaVersion + ").") + val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) + if(id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet)) + error("Binary version for dependency " + id + " (" + depBinaryVersion + ") differs from Scala binary version in project (" + scalaBinaryVersion + ").") } } private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet From 851864f9f6e84364dd4c50098bd0cf6bd79aaf9f Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Tue, 7 Feb 2012 20:14:45 +0400 Subject: [PATCH 0176/1030] Mirror ivy \'force\' attribute in sbt. --- ivy/Ivy.scala | 2 +- ivy/IvyInterface.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 400490086..a9a5cf8f8 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -404,7 +404,7 @@ private object IvySbt { for(dependency <- dependencies) { - val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), false, dependency.isChanging, dependency.isTransitive) + val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) dependency.configurations match { case None => // The configuration for this dependency was not explicitly specified, so use the default diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index d5ffc4d6a..e7d5115d3 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -9,7 +9,7 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString = organization + ":" + name + ":" + revision + @@ -28,6 +28,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def notTransitive() = intransitive() def intransitive() = copy(isTransitive = false) def changing() = copy(isChanging = true) + def force() = copy(isForce = true) def from(url: String) = artifacts(Artifact(name, new URL(url))) def classifier(c: String) = artifacts(Artifact(name, c)) def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) From 1b168c37e49a033499943bd1b77fe16e0f29fd38 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 14 Feb 2012 21:59:12 -0500 Subject: [PATCH 0177/1030] support for dependency overrides --- ivy/Ivy.scala | 13 ++++++++++++- ivy/IvyConfigurations.scala | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index a9a5cf8f8..03b434ac4 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -15,6 +15,7 @@ import core.{IvyPatternHelper, LogOptions} import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} +import core.module.descriptor.{OverrideDependencyDescriptorMediator} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.{IvyNode, ResolveData} import core.settings.IvySettings @@ -142,6 +143,7 @@ final class IvySbt(val configuration: IvyConfiguration) val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) IvySbt.addDependencies(moduleID, dependencies, parser) IvySbt.addMainArtifact(moduleID) + IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT_OR_REGEXP)) (moduleID, parser.getDefaultConf) } private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = @@ -308,7 +310,7 @@ private object IvySbt val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) - case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub) + case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) case _ => m } } @@ -430,6 +432,15 @@ private object IvySbt moduleID.addDependency(dependencyDescriptor) } } + def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = + overrides foreach addOverride(moduleID, matcher) + def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = + { + val overrideID = new ModuleId(overrideDef.organization, overrideDef.name) + val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) + moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) + } + /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 97e6eb7c2..317d20c67 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -62,7 +62,7 @@ final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], valida { def noScala = copy(ivyScala = None) } -final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false) extends ModuleSettings +final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) From c74b03513f163b407b6908f240bfefc4d846c63b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 14 Feb 2012 21:59:13 -0500 Subject: [PATCH 0178/1030] work around 'data has not been loaded' exception when direct dependency overridden by newer version --- ivy/Ivy.scala | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 03b434ac4..0c378c899 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -141,9 +141,9 @@ final class IvySbt(val configuration: IvyConfiguration) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) - IvySbt.addDependencies(moduleID, dependencies, parser) IvySbt.addMainArtifact(moduleID) - IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT_OR_REGEXP)) + IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) + IvySbt.addDependencies(moduleID, IvySbt.overrideDirect(dependencies, overrides), parser) (moduleID, parser.getDefaultConf) } private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = @@ -440,6 +440,20 @@ private object IvySbt val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) } + /** It is necessary to explicitly modify direct dependencies because Ivy gives + * "IllegalStateException: impossible to get artifacts when data has not been loaded." + * when a direct dependency is overridden with a newer version."*/ + def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = + { + def key(id: ModuleID) = (id.organization, id.name) + val overridden = overrides.map(id => (key(id), id.revision)).toMap + dependencies map { dep => + overridden get key(dep) match { + case Some(rev) => dep.copy(revision = rev) + case None => dep + } + } + } /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = From 2b3db35d840a7ae778c64904d86c5277851892b3 Mon Sep 17 00:00:00 2001 From: Eugene Vigdorchik Date: Tue, 21 Feb 2012 18:52:50 +0400 Subject: [PATCH 0179/1030] test- preffix should be stripped to obtain classifier. --- ivy/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index e7d5115d3..5b90fd141 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -438,7 +438,7 @@ object Artifact val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier, DefaultType) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix("test-"), DefaultType) def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) } From ebc0e90690770df43fc4937dad1104d19141b24c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 21 Feb 2012 22:47:07 -0500 Subject: [PATCH 0180/1030] add ConflictWarning.disable convenience method --- ivy/ConflictWarning.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index befe4abd6..1aa421388 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -5,7 +5,11 @@ package sbt final case class ConflictWarning(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) object ConflictWarning { - def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), (_: ModuleID).organization, Level.Warn, false) + def disable: ConflictWarning = ConflictWarning("", (_: ModuleID) => false, org, Level.Warn, false) + + private[this] def org = (_: ModuleID).organization + + def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), org, Level.Warn, false) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { From ec955474c42829f6fc11398262b63f7eb399f46d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 27 Feb 2012 18:37:49 -0500 Subject: [PATCH 0181/1030] Declare extra namespace in ModuleDescriptor for parsed plugin poms. Fixes #368. --- ivy/CustomPomParser.scala | 3 ++- ivy/Ivy.scala | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index 8f64fd950..9135cab41 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -64,7 +64,7 @@ object CustomPomParser // Fixes up the detected extension in some cases missed by Ivy. val convertArtifacts = artifactExtIncorrect(md) - val unqualify = filtered - ExtraAttributesKey + val unqualify = (filtered - ExtraAttributesKey) map { case (k,v) => ("e:" + k, v) } if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts) md else @@ -168,6 +168,7 @@ object CustomPomParser for(l <- md.getLicenses) dmd.addLicense(l) for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) + IvySbt.addExtraNamespace(dmd) for( dd <- md.getDependencies ) dmd.addDependency(addExtra(dd, dependencyExtra)) for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( mrid, resolvedMrid, ed.getLocation, ed.getExtendsTypes) ) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 0c378c899..b59f639a8 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -130,7 +130,7 @@ final class IvySbt(val configuration: IvyConfiguration) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) - baseModule.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].put("e", "http://ant.apache.org/ivy/extra") + IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } private def configureInline(ic: InlineConfiguration, log: Logger) = @@ -286,6 +286,9 @@ private object IvySbt import configuration._ new IvyConfig(name, if(isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) } + def addExtraNamespace(dmd: DefaultModuleDescriptor): Unit = + dmd.addExtraAttributeNamespace("e", "http://ant.apache.org/ivy/extra") + /** Adds the ivy.xml main artifact. */ private def addMainArtifact(moduleID: DefaultModuleDescriptor) { From 403383d7cfb9da66278248b9a98b94ea27427d20 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Tue, 28 Feb 2012 15:18:46 +0530 Subject: [PATCH 0182/1030] Added support for providing basic SCM info Sonatype OSS repo (where many libraries are expected to migrate) requires populating SCM info in additional to what is already provisioned for populating in SBT. We now support populating the basic SCM info as thus: ``` // Usual scmInfo := Some(ScmInfo(url("https://github.com/foo/project"), "scm:git:https://github.com/foo/project.git")) // Also add scmInfo := Some(ScmInfo(url("https://github.com/foo/project"), "scm:git:https://github.com/foo/project.git", Some("dev_connection"))) ``` For anything more esoteric than the basic info, there is always `pomPostProcess` :) --- ivy/IvyInterface.scala | 10 ++++++---- ivy/MakePom.scala | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 5b90fd141..be3d2cd3d 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -17,9 +17,9 @@ final case class ModuleID(organization: String, name: String, revision: String, (if(extraAttributes.isEmpty) "" else " " + extraString) def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") - @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) - @deprecated("Use the variant accepting a CrossVersion value constructed by a member of the CrossVersion object.", "0.12.0") + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) @@ -49,13 +49,15 @@ object ModuleID if(key.startsWith("e:")) (key, value) else ("e:" + key, value) } /** Additional information about a project module */ -case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None) +case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) } +/** Basic SCM information for a project module */ +case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) sealed trait Resolver @@ -428,7 +430,7 @@ object Artifact } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { - import artifact._ + import artifact._ val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) val base = CrossVersion.applyCross(artifact.name, cross) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index e2b5f1778..31a83a705 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -44,6 +44,7 @@ class MakePom(val log: Logger) {moduleInfo.nameFormal} { makeStartYear(moduleInfo) } { makeOrganization(moduleInfo) } + { makeScmInfo(moduleInfo) } { extra } { val deps = depsInConfs(module, configurations) @@ -83,6 +84,21 @@ class MakePom(val log: Logger) }} } + def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = + { + moduleInfo.scmInfo match { + case Some(s) => + + {s.browseUrl} + {s.connection} + {s.devConnection match { + case Some(d) => {d} + case _ => NodeSeq.Empty + }} + + case _ => NodeSeq.Empty + } + } def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) From 89122005cb1e28d50f0273f2933ca8193af1dc07 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Tue, 28 Feb 2012 22:52:14 +0530 Subject: [PATCH 0183/1030] Have convenient toString for `FileCredentials` --- ivy/Credentials.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index 09e86d579..dc09adbcc 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -69,5 +69,7 @@ object Credentials } sealed trait Credentials -final class FileCredentials(val path: File) extends Credentials +final class FileCredentials(val path: File) extends Credentials { + override def toString = "FileCredentials('" + path + "')" +} final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials From 2999cf8df908e68066a7485c5da808a78da02fb9 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Mon, 12 Mar 2012 04:34:45 +0530 Subject: [PATCH 0184/1030] Update Resolver configuration - deprecate scala-tools resolvers - rename `typesafeResolver` to `typesafeReleases` for consistency - add reference for other wel known resolvers, viz., oss.sonatype.org and scalasbt.artifactoryonline.com - rearrange locations for helper methods --- ivy/IvyInterface.scala | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index be3d2cd3d..76c910cbb 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -178,7 +178,9 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern } import Resolver._ +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) @@ -190,13 +192,25 @@ sealed trait JavaNet1Repository extends Resolver object Resolver { + val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" + val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" + val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") val ScalaToolsReleasesName = "Scala-Tools Maven2 Repository" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" + def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) + def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) + def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) + def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + /** Add the local, Maven Central, and Scala Tools releases repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = withDefaultResolvers(userResolvers, true) From 38289ad08ad9440ae0640b57d70cf4c73d3b4e22 Mon Sep 17 00:00:00 2001 From: Michael Allman Date: Sun, 8 Apr 2012 20:22:15 -0700 Subject: [PATCH 0185/1030] Add support for loading Ivy settings from a URL --- ivy/Ivy.scala | 2 +- ivy/IvyConfigurations.scala | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index b59f639a8..002618fad 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -65,7 +65,7 @@ final class IvySbt(val configuration: IvyConfiguration) CustomPomParser.registerDefault configuration match { - case e: ExternalIvyConfiguration => is.load(e.file) + case e: ExternalIvyConfiguration => is.load(e.url) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 317d20c67..c3999ea6f 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -4,6 +4,7 @@ package sbt import java.io.File +import java.net.URL import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) @@ -27,10 +28,14 @@ final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resol def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) } -final class ExternalIvyConfiguration(val baseDirectory: File, val file: File, val lock: Option[xsbti.GlobalLock], val log: Logger) extends IvyConfiguration +final class ExternalIvyConfiguration(val baseDirectory: File, val url: URL, val lock: Option[xsbti.GlobalLock], val log: Logger) extends IvyConfiguration { type This = ExternalIvyConfiguration - def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, file, lock, log) + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, url, lock, log) +} +object ExternalIvyConfiguration +{ + def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI.toURL, lock, log) } object IvyConfiguration @@ -42,7 +47,7 @@ object IvyConfiguration log.debug("Autodetecting configuration.") val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) if(defaultIvyConfigFile.canRead) - new ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) + ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, log) } From c111fc1ae24a34a2e5dd09d3b01e54e18b9d02f4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 11 Apr 2012 22:40:45 -0400 Subject: [PATCH 0186/1030] configuration via ivysettings.xml: use URI instead of URL and make 'inter-project' resolver available for multi-project builds. ref #416 --- ivy/Ivy.scala | 20 +++++++++++++++++++- ivy/IvyConfigurations.scala | 9 +++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 002618fad..dba07c443 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -6,6 +6,7 @@ package sbt import Resolver.PluginPattern import java.io.File +import java.net.URI import java.util.concurrent.Callable import java.util.{Collection, Collections => CS} import CS.singleton @@ -65,7 +66,9 @@ final class IvySbt(val configuration: IvyConfiguration) CustomPomParser.registerDefault configuration match { - case e: ExternalIvyConfiguration => is.load(e.url) + case e: ExternalIvyConfiguration => + IvySbt.addResolvers(e.extraResolvers, is, configuration.log) + IvySbt.loadURI(is, e.uri) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir @@ -198,6 +201,14 @@ private object IvySbt def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) def defaultPOM(project: File) = new File(project, DefaultMavenFilename) + def loadURI(is: IvySettings, uri: URI) + { + if(uri.getScheme == "file") + is.load(new File(uri)) // IVY-1114 + else + is.load(uri.toURL) + } + /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: Logger) @@ -236,6 +247,13 @@ private object IvySbt } newDefault } + def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger) + { + for(r <- resolvers) { + log.debug("\t" + r) + settings.addResolver(ConvertResolver(r)(settings, log)) + } + } /** A hack to detect if the given artifact is an automatically generated request for a classifier, * as opposed to a user-initiated declaration. It relies on Ivy prefixing classifier with m:, while sbt uses e:. * Clearly, it would be better to have an explicit option in Ivy to control this.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index c3999ea6f..d2a5c958c 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -4,7 +4,7 @@ package sbt import java.io.File -import java.net.URL +import java.net.{URI,URL} import scala.xml.NodeSeq final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) @@ -28,20 +28,21 @@ final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resol def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) } -final class ExternalIvyConfiguration(val baseDirectory: File, val url: URL, val lock: Option[xsbti.GlobalLock], val log: Logger) extends IvyConfiguration +final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration { type This = ExternalIvyConfiguration - def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, url, lock, log) + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, log) } object ExternalIvyConfiguration { - def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI.toURL, lock, log) + def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, log) } object IvyConfiguration { /** Called to configure Ivy when inline resolvers are not specified. * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ + @deprecated("Explicitly use either external or inline configuration.", "0.12.0") def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration = { log.debug("Autodetecting configuration.") From ce8f7b677d4b72432dba8b5f06dc1e0aa2274fd1 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 18 Apr 2012 08:07:53 -0400 Subject: [PATCH 0187/1030] reorganize compilation modules --- ivy/IvyScala.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 647df693f..a4654eb51 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -14,14 +14,16 @@ import plugins.matcher.ExactPatternMatcher object ScalaArtifacts { - val Organization = "org.scala-lang" - val LibraryID = "scala-library" - val CompilerID = "scala-compiler" + import xsbti.ArtifactInfo._ + val Organization = ScalaOrganization + val LibraryID = ScalaLibraryID + val CompilerID = ScalaCompilerID def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) } object SbtArtifacts { - val Organization = "org.scala-sbt" + import xsbti.ArtifactInfo._ + val Organization = SbtOrganization } import ScalaArtifacts._ From 9fe72a546e2e4b930dc1573abf45019e541a357b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 28 Apr 2012 18:58:38 -0400 Subject: [PATCH 0188/1030] exclude should apply to any artifact type, not just jars. fixes #436 --- ivy/IvyScala.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index a4654eb51..171f5488e 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -95,7 +95,7 @@ private object IvyScala * the given configurations. */ private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "jar", "*") + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "*", "*") val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef,AnyRef]) configurationNames.foreach(rule.addConfiguration) rule From 9fe6049352865b111c2a5d64e4af3b6ff289ccef Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 2 May 2012 19:56:35 -0400 Subject: [PATCH 0189/1030] update-classifiers fixes: mark modules intransitive and don't exclude sources/docs for scala jars --- ivy/Ivy.scala | 2 +- ivy/IvyActions.scala | 2 +- ivy/IvyScala.scala | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index dba07c443..6afd2c963 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -447,7 +447,7 @@ private object IvySbt { for(conf <- dependencyDescriptor.getModuleConfigurations) { - dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations)) + dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, "*")) } } moduleID.addDependency(dependencyDescriptor) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 059d48997..902b84d95 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -184,7 +184,7 @@ object IvyActions { val excluded = exclude getOrElse(restrictedCopy(m, false), Set.empty) val included = classifiers filterNot excluded - if(included.isEmpty) None else Some(m.copy(explicitArtifacts = classifiedArtifacts(m.name, included) )) + if(included.isEmpty) None else Some(m.copy(isTransitive = false, explicitArtifacts = classifiedArtifacts(m.name, included) )) } def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 171f5488e..0310a62ba 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -87,15 +87,15 @@ private object IvyScala } } def excludeScalaJar(name: String): Unit = - module.addExcludeRule(excludeRule(Organization, name, configurationNames)) + module.addExcludeRule(excludeRule(Organization, name, configurationNames, "jar")) excludeScalaJar(LibraryID) excludeScalaJar(CompilerID) } /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for * the given configurations. */ - private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String]): ExcludeRule = + private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String], excludeTypePattern: String): ExcludeRule = { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", "*", "*") + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", excludeTypePattern, "*") val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef,AnyRef]) configurationNames.foreach(rule.addConfiguration) rule From 3d1766a96e3e9b40930ab426496dab4c2c12f817 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 2 May 2012 19:56:35 -0400 Subject: [PATCH 0190/1030] bump to Ivy 2.3.0-RC1 --- ivy/CustomXmlParser.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ivy/CustomXmlParser.scala b/ivy/CustomXmlParser.scala index f773b1ce9..da44743f6 100644 --- a/ivy/CustomXmlParser.scala +++ b/ivy/CustomXmlParser.scala @@ -19,8 +19,6 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) { - if(defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") - def setSource(url: URL) = { super.setResource(new URLResource(url)) @@ -29,7 +27,11 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser def setInput(bytes: Array[Byte]) { setInput(new ByteArrayInputStream(bytes)) } /** Overridden because the super implementation overwrites the module descriptor.*/ override def setResource(res: Resource) {} - override def setMd(md: DefaultModuleDescriptor) = super.setMd(md) + override def setMd(md: DefaultModuleDescriptor) = + { + super.setMd(md) + if(defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") + } override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) } From 52af295b42de7411c42e558ccaf1053f70cbdf6a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 5 May 2012 20:35:04 -0400 Subject: [PATCH 0191/1030] deprecations backported to 0.11.3 --- ivy/IvyInterface.scala | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 76c910cbb..851aa271b 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -178,9 +178,9 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern } import Resolver._ -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) @@ -195,13 +195,13 @@ object Resolver val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") val ScalaToolsReleasesName = "Scala-Tools Maven2 Repository" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.12.0") + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" @@ -211,16 +211,12 @@ object Resolver def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) - /** Add the local, Maven Central, and Scala Tools releases repositories to the user repositories. */ + /** Add the local and Maven Central repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = withDefaultResolvers(userResolvers, true) - /** Add the local Ivy and Maven Central repositories to the user repositories. If `scalaTools` is true, add the Scala Tools releases repository as well. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], scalaTools: Boolean): Seq[Resolver] = - withDefaultResolvers(userResolvers, true, scalaTools) /** Add the local Ivy repository to the user repositories. - * If `scalaTools` is true, add the Scala Tools releases repository. * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean, scalaTools: Boolean): Seq[Resolver] = + def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = Seq(Resolver.defaultLocal) ++ userResolvers ++ single(DefaultMavenRepository, mavenCentral) From db3fd8223642d252e7bbc9d70ecf040bfb8186a5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 5 May 2012 20:35:04 -0400 Subject: [PATCH 0192/1030] more scala-tools replacements --- ivy/IvyInterface.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 851aa271b..9a1708059 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -196,13 +196,13 @@ object Resolver val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesName = "Scala-Tools Maven2 Repository" + val ScalaToolsReleasesName = "Sonatype OSS Releases" @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsName = "Scala-Tools Maven2 Snapshots Repository" + val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesRoot = "http://scala-tools.org/repo-releases" + val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsRoot = "http://scala-tools.org/repo-snapshots" + val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" From 914161874464f860519677662f192cace37d23c0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 6 May 2012 14:15:03 -0400 Subject: [PATCH 0193/1030] change Scala binary version check to a warning --- ivy/Ivy.scala | 2 +- ivy/IvyScala.scala | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 6afd2c963..6d23c9810 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -132,7 +132,7 @@ final class IvySbt(val configuration: IvyConfiguration) case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } - moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration)) + moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 0310a62ba..0554c3471 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -33,10 +33,10 @@ final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String)(check: IvyScala) + def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala) { if(check.checkExplicit) - checkDependencies(module, check.scalaBinaryVersion, check.configurations) + checkDependencies(module, check.scalaBinaryVersion, check.configurations, log) if(check.filterImplicit) excludeScalaJars(module, check.configurations) if(check.overrideScalaVersion) @@ -56,7 +56,7 @@ private object IvyScala /** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration]) + private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger) { val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) for(dep <- module.getDependencies.toList) @@ -64,7 +64,9 @@ private object IvyScala val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) if(id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet)) - error("Binary version for dependency " + id + " (" + depBinaryVersion + ") differs from Scala binary version in project (" + scalaBinaryVersion + ").") + log.warn("Binary version " + " (" + depBinaryVersion + ") for dependency " + id + + "\n\tin " + module.getModuleRevisionId + + " differs from Scala binary version in project (" + scalaBinaryVersion + ").") } } private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet From 9983f6f19a402a6caf932669266f848c9c6af3b8 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 6 May 2012 15:11:46 -0400 Subject: [PATCH 0194/1030] remove duplicate conflict warnings --- ivy/IvyScala.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index 0554c3471..e21d3d01a 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -8,7 +8,7 @@ import scala.collection.mutable.HashSet import org.apache.ivy.{core, plugins} import core.module.descriptor.{DefaultExcludeRule, ExcludeRule} -import core.module.descriptor.{DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} +import core.module.descriptor.{DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import plugins.matcher.ExactPatternMatcher @@ -59,15 +59,19 @@ private object IvyScala private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger) { val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) - for(dep <- module.getDependencies.toList) + def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) - if(id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet)) - log.warn("Binary version " + " (" + depBinaryVersion + ") for dependency " + id + + val mismatched = id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet) + if(mismatched) + Some("Binary version (" + depBinaryVersion + ") for dependency " + id + "\n\tin " + module.getModuleRevisionId + " differs from Scala binary version in project (" + scalaBinaryVersion + ").") + else + None } + module.getDependencies.toList.flatMap(binaryScalaWarning).toSet foreach { (s: String) => log.warn(s) } } private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet From e54e41145167b136cbe6cbc8a0f6da4860f24dd9 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 May 2012 07:34:15 -0400 Subject: [PATCH 0195/1030] hk2-jar packaging should be handled like a standard jar. fixes #463 --- ivy/CustomPomParser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index 9135cab41..98e22b462 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -35,7 +35,7 @@ object CustomPomParser val ExtraAttributesKey = "extraDependencyAttributes" // packagings that should be jars, but that Ivy doesn't handle as jars - val JarPackagings = Set("eclipse-plugin") + val JarPackagings = Set("eclipse-plugin", "hk2-jar") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. From af6e99acc266df4e65d42678efdca109e912549d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 6 Jul 2012 10:28:51 -0400 Subject: [PATCH 0196/1030] 'orbit' packaging should be handled like a standard jar. fixes #499. ref #463 --- ivy/CustomPomParser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index 98e22b462..aced1d48a 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -35,7 +35,7 @@ object CustomPomParser val ExtraAttributesKey = "extraDependencyAttributes" // packagings that should be jars, but that Ivy doesn't handle as jars - val JarPackagings = Set("eclipse-plugin", "hk2-jar") + val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. From f0bdadc437907799bfc55db39c441e508642a2fb Mon Sep 17 00:00:00 2001 From: Thomas Lockney Date: Sun, 15 Jul 2012 21:03:19 -0700 Subject: [PATCH 0197/1030] Actually pass in the artifact, rather than just a global match --- ivy/Ivy.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 6d23c9810..2866c8484 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -335,7 +335,7 @@ private object IvySbt case _ => m } } - + private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) @@ -447,7 +447,7 @@ private object IvySbt { for(conf <- dependencyDescriptor.getModuleConfigurations) { - dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, "*")) + dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) } } moduleID.addDependency(dependencyDescriptor) @@ -462,7 +462,7 @@ private object IvySbt moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) } /** It is necessary to explicitly modify direct dependencies because Ivy gives - * "IllegalStateException: impossible to get artifacts when data has not been loaded." + * "IllegalStateException: impossible to get artifacts when data has not been loaded." * when a direct dependency is overridden with a newer version."*/ def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = { From 152d51465d50bc8f90880a54f8b40de7a6cf627d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 20 Aug 2012 15:55:50 -0400 Subject: [PATCH 0198/1030] Merge multiple dependency definitions for the same ID. Fixes #468, #285, #419, #480. This is only a workaround. Multiple dependency definitions should be avoided in general. --- ivy/CustomPomParser.scala | 11 +++- ivy/Ivy.scala | 97 +++++++++++++++++++-------- ivy/IvyActions.scala | 2 +- ivy/IvyInterface.scala | 1 + ivy/MakePom.scala | 58 ++++++++++++---- ivy/MergeDescriptors.scala | 132 +++++++++++++++++++++++++++++++++++++ 6 files changed, 257 insertions(+), 44 deletions(-) create mode 100644 ivy/MergeDescriptors.scala diff --git a/ivy/CustomPomParser.scala b/ivy/CustomPomParser.scala index aced1d48a..668aa5cff 100644 --- a/ivy/CustomPomParser.scala +++ b/ivy/CustomPomParser.scala @@ -64,8 +64,11 @@ object CustomPomParser // Fixes up the detected extension in some cases missed by Ivy. val convertArtifacts = artifactExtIncorrect(md) + // Merges artifact sections for duplicate dependency definitions + val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) + val unqualify = (filtered - ExtraAttributesKey) map { case (k,v) => ("e:" + k, v) } - if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts) + if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts && !mergeDuplicates) md else addExtra(unqualify, extraDepAttributes, parser, md) @@ -74,7 +77,6 @@ object CustomPomParser md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filter { case (SbtVersionKey | ScalaVersionKey | ExtraAttributesKey,_) => true; case _ => false } - private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = if(properties.isEmpty) id else addExtra(properties, id) @@ -169,7 +171,10 @@ object CustomPomParser for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) - for( dd <- md.getDependencies ) dmd.addDependency(addExtra(dd, dependencyExtra)) + + val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } + val unique = IvySbt.mergeDuplicateDefinitions(withExtra) + unique foreach dmd.addDependency for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( mrid, resolvedMrid, ed.getLocation, ed.getExtendsTypes) ) for( conf <- md.getConfigurations) { diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 2866c8484..93ab5e94b 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -146,7 +146,8 @@ final class IvySbt(val configuration: IvyConfiguration) val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) IvySbt.addMainArtifact(moduleID) IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) - IvySbt.addDependencies(moduleID, IvySbt.overrideDirect(dependencies, overrides), parser) + val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) + IvySbt.addDependencies(moduleID, transformedDeps, parser) (moduleID, parser.getDefaultConf) } private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = @@ -423,36 +424,73 @@ private object IvySbt } /** This method is used to add inline dependencies to the provided module. */ - def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Iterable[ModuleID], parser: CustomXmlParser.CustomParser) + def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) { - for(dependency <- dependencies) - { - val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) - dependency.configurations match - { - case None => // The configuration for this dependency was not explicitly specified, so use the default - parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency - parser.parseDepsConfs(confs, dependencyDescriptor) - } - for(artifact <- dependency.explicitArtifacts) - { - import artifact.{name, classifier, `type`, extension, url} - val extraMap = extra(artifact) - val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) - for(conf <- dependencyDescriptor.getModuleConfigurations) - dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) - } - for(excls <- dependency.exclusions) - { - for(conf <- dependencyDescriptor.getModuleConfigurations) - { - dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) - } - } - moduleID.addDependency(dependencyDescriptor) - } + val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } + val unique = if(hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted + unique foreach moduleID.addDependency } + /** Determines if there are multiple dependency definitions for the same dependency ID. */ + def hasDuplicateDependencies(dependencies: Seq[DependencyDescriptor]): Boolean = + { + val ids = dependencies.map(_.getDependencyRevisionId) + ids.toSet.size != ids.size + } + + /** Combines the artifacts, includes, and excludes of duplicate dependency definitions. + * This is somewhat fragile and is only intended to workaround Ivy (or sbt's use of Ivy) not handling this case properly. + * In particular, Ivy will create multiple dependency entries when converting a pom with a dependency on a classified artifact and a non-classified artifact: + * https://github.com/harrah/xsbt/issues/468 + * It will also allow users to declare dependencies on classified modules in different configurations: + * https://groups.google.com/d/topic/simple-build-tool/H2MdAARz6e0/discussion + * as well as basic multi-classifier handling: #285, #419, #480. + * Multiple dependency definitions should otherwise be avoided as much as possible. + */ + def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = + { + val deps = new java.util.LinkedHashMap[ModuleRevisionId, DependencyDescriptor] + for( dd <- dependencies ) + { + val id = dd.getDependencyRevisionId + val updated = deps get id match { + case null => dd + case v => ivyint.MergeDescriptors(v, dd) + } + deps.put(id, updated) + } + import collection.JavaConverters._ + deps.values.asScala.toSeq + } + + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ + def convertDependency(moduleID: DefaultModuleDescriptor, dependency: ModuleID, parser: CustomXmlParser.CustomParser): DefaultDependencyDescriptor = + { + val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) + dependency.configurations match + { + case None => // The configuration for this dependency was not explicitly specified, so use the default + parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) + case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + parser.parseDepsConfs(confs, dependencyDescriptor) + } + for(artifact <- dependency.explicitArtifacts) + { + import artifact.{name, classifier, `type`, extension, url} + val extraMap = extra(artifact) + val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) + for(conf <- dependencyDescriptor.getModuleConfigurations) + dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) + } + for(excls <- dependency.exclusions) + { + for(conf <- dependencyDescriptor.getModuleConfigurations) + { + dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) + } + } + dependencyDescriptor + } + def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = overrides foreach addOverride(moduleID, matcher) def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = @@ -500,6 +538,7 @@ private object IvySbt } } + /** This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. * Ivy 2.0.0 always produces a DefaultModuleDescriptor. */ private def toDefaultModuleDescriptor(md: ModuleDescriptor) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 902b84d95..a2d040a97 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -20,7 +20,7 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) -final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType)) +final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 9a1708059..0f37aa241 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -37,6 +37,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) def sources() = artifacts(Artifact.sources(name)) def javadoc() = artifacts(Artifact.javadoc(name)) + def pomOnly() = artifacts(Artifact.pom(name)) def withSources() = jarIfEmpty.sources() def withJavadoc() = jarIfEmpty.javadoc() private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 31a83a705..5dc39f069 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -10,13 +10,12 @@ package sbt import java.io.File // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation -import scala.xml.{Node => XNode, NodeSeq, PrettyPrinter} +import scala.xml.{Elem, Node => XNode, NodeSeq, PrettyPrinter} import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} import core.settings.IvySettings -import core.module.descriptor -import descriptor.{DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} +import core.module.descriptor.{DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) @@ -146,38 +145,75 @@ class MakePom(val log: Logger) def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = + { + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if(artifacts.isEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None) + } + else if(includeArtifacts.isEmpty) + NodeSeq.Empty + else + NodeSeq.fromSeq(artifacts.map( a => makeDependencyElem(dependency, a) )) + } + + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Elem = + { + val artifactConfigs = artifact.getConfigurations + val configs = if(artifactConfigs.isEmpty) dependency.getModuleConfigurations else artifactConfigs + val (scope, optional) = getScopeAndOptional(configs) + makeDependencyElem(dependency, scope, optional, artifactClassifier(artifact), artifactType(artifact)) + } + def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = { val mrid = dependency.getDependencyRevisionId {mrid.getOrganisation} {mrid.getName} {mrid.getRevision} - { scopeAndOptional(dependency) } - { classifier(dependency, includeTypes) } + { scopeElem(scope) } + { optionalElem(optional) } + { classifierElem(classifier) } + { typeElem(tpe) } { exclusions(dependency) } } + @deprecated("No longer used and will be removed.", "0.12.1") def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { val jarDep = dependency.getAllDependencyArtifacts.filter(d => includeTypes(d.getType)).headOption jarDep match { - case Some(a) => { - val cl = a.getExtraAttribute("classifier") - if (cl != null) {cl} else NodeSeq.Empty - } - case _ => NodeSeq.Empty + case Some(a) => classifierElem(artifactClassifier(a)) + case None => NodeSeq.Empty } } + def artifactType(artifact: DependencyArtifactDescriptor): Option[String] = + Option(artifact.getType).flatMap { tpe => if(tpe == "jar") None else Some(tpe) } + def typeElem(tpe: Option[String]): NodeSeq = + tpe match { + case Some(t) => {t} + case None => NodeSeq.Empty + } + + def artifactClassifier(artifact: DependencyArtifactDescriptor): Option[String] = + Option(artifact.getExtraAttribute("classifier")) + def classifierElem(classifier: Option[String]): NodeSeq = + classifier match { + case Some(c) => {c} + case None => NodeSeq.Empty + } + @deprecated("No longer used and will be removed.", "0.12.1") def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = { val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) scopeElem(scope) ++ optionalElem(opt) } def scopeElem(scope: Option[String]): NodeSeq = scope match { - case Some(s) => {s} case None => NodeSeq.Empty + case Some(s) => {s} } def optionalElem(opt: Boolean) = if(opt) true else NodeSeq.Empty def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId diff --git a/ivy/MergeDescriptors.scala b/ivy/MergeDescriptors.scala new file mode 100644 index 000000000..f46f90501 --- /dev/null +++ b/ivy/MergeDescriptors.scala @@ -0,0 +1,132 @@ +package sbt +package ivyint + +import java.io.File +import java.net.URI +import java.util.{Collection, Collections => CS} +import CS.singleton + +import org.apache.ivy.{core, plugins, util, Ivy} +import core.module.descriptor.{DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor} +import core.module.descriptor.{DefaultDependencyDescriptor => DDD, DependencyDescriptor} +import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import plugins.namespace.Namespace +import util.extendable.ExtendableItem + +private[sbt] object MergeDescriptors +{ + def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = + { + assert(a.isForce == b.isForce) + assert(a.isChanging == b.isChanging) + assert(a.isTransitive == b.isTransitive) + assert(a.getParentRevisionId == b.getParentRevisionId) + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + assert(amrid == bmrid) + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + assert(adyn == bdyn) + assert(a.getNamespace == b.getNamespace) + + new MergedDescriptors(a,b) + } +} + +// combines the artifacts, configurations, includes, and excludes for DependencyDescriptors `a` and `b` +// that otherwise have equal IDs +private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor +{ + def getDependencyId = a.getDependencyId + def isForce = a.isForce + def isChanging = a.isChanging + def isTransitive = a.isTransitive + def getNamespace = a.getNamespace + def getParentRevisionId = a.getParentRevisionId + def getDependencyRevisionId = a.getDependencyRevisionId + def getDynamicConstraintDependencyRevisionId = a.getDynamicConstraintDependencyRevisionId + + def getModuleConfigurations = concat(a.getModuleConfigurations, b.getModuleConfigurations) + + def getDependencyConfigurations(moduleConfiguration: String, requestedConfiguration: String) = + concat(a.getDependencyConfigurations(moduleConfiguration, requestedConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + + def getDependencyConfigurations(moduleConfiguration: String) = + concat(a.getDependencyConfigurations(moduleConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + + def getDependencyConfigurations(moduleConfigurations: Array[String]) = + concat(a.getDependencyConfigurations(moduleConfigurations), b.getDependencyConfigurations(moduleConfigurations)) + + def getAllDependencyArtifacts = concatArtifacts(a, a.getAllDependencyArtifacts, b, b.getAllDependencyArtifacts) + + def getDependencyArtifacts(moduleConfigurations: String) = + concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + + def getDependencyArtifacts(moduleConfigurations: Array[String]) = + concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + + def getAllIncludeRules = concat(a.getAllIncludeRules, b.getAllIncludeRules) + + def getIncludeRules(moduleConfigurations: String) = + concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) + + def getIncludeRules(moduleConfigurations: Array[String]) = + concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) + + private[this] def concatArtifacts(a: DependencyDescriptor, as: Array[DependencyArtifactDescriptor], b: DependencyDescriptor, bs: Array[DependencyArtifactDescriptor]) = + { + if(as.isEmpty) + if(bs.isEmpty) as + else defaultArtifact(a) +: explicitConfigurations(b, bs) + else if(bs.isEmpty) explicitConfigurations(a, as) :+ defaultArtifact(b) + else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) + } + private[this] def explicitConfigurations(base: DependencyDescriptor, arts: Array[DependencyArtifactDescriptor]): Array[DependencyArtifactDescriptor] = + arts map { art => explicitConfigurations(base, art) } + private[this] def explicitConfigurations(base: DependencyDescriptor, art: DependencyArtifactDescriptor): DependencyArtifactDescriptor = + { + val aConfs = art.getConfigurations + if(aConfs == null || aConfs.isEmpty) + copyWithConfigurations(art, base.getModuleConfigurations) + else + art + } + private[this] def defaultArtifact(a: DependencyDescriptor): DependencyArtifactDescriptor = + { + val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) + addConfigurations(dd, a.getModuleConfigurations) + dd + } + private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = + { + val dextra = dd.getQualifiedExtraAttributes + val newd = new DefaultDependencyArtifactDescriptor(dd.getDependencyDescriptor, dd.getName, dd.getType, dd.getExt, dd.getUrl, dextra) + addConfigurations(newd, confs) + newd + } + private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = + confs foreach dd.addConfiguration + + private[this] def concat[T: ClassManifest](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray + + def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) + + def getExcludeRules(moduleConfigurations: String) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + + def getExcludeRules(moduleConfigurations: Array[String]) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + + def doesExclude(moduleConfigurations: Array[String], artifactId: ArtifactId) = a.doesExclude(moduleConfigurations, artifactId) || b.doesExclude(moduleConfigurations, artifactId) + + def canExclude = a.canExclude || b.canExclude + + def asSystem = this + + def clone(revision: ModuleRevisionId) = new MergedDescriptors(a.clone(revision), b.clone(revision)) + + def getAttribute(name: String): String = a.getAttribute(name) + def getAttributes = a.getAttributes + def getExtraAttribute(name: String) = a.getExtraAttribute(name) + def getExtraAttributes = a.getExtraAttributes + def getQualifiedExtraAttributes = a.getQualifiedExtraAttributes + def getSourceModule = a.getSourceModule +} From d641c72a453808d7caca3259617542f6bf630d27 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 28 Aug 2012 11:55:24 -0400 Subject: [PATCH 0199/1030] per-project resolution cache that deletes cached files before each update These are the ivy files, properties, and resolve reports for the project, not dependencies and their artifacts. --- ivy/Ivy.scala | 15 ++++++++++++--- ivy/IvyActions.scala | 3 +++ ivy/IvyCache.scala | 2 +- ivy/IvyConfigurations.scala | 14 ++++++++++---- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 93ab5e94b..20d3fd5e5 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -13,7 +13,7 @@ import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ResolutionCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.descriptor.{OverrideDependencyDescriptorMediator} @@ -72,7 +72,7 @@ final class IvySbt(val configuration: IvyConfiguration) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir - IvySbt.configureCache(is, i.localOnly) + IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) } @@ -277,8 +277,17 @@ private object IvySbt settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private def configureCache(settings: IvySettings, localOnly: Boolean) + private[sbt] def cleanResolutionCache(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) { + val files = + Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: + Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: + Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten + IO.delete(files) + } + private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) + { + resCacheDir foreach { dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath) } val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index a2d040a97..8bb952d06 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -201,7 +201,10 @@ object IvyActions private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(module) + resolveOptions.setResolveId(resolveId) resolveOptions.setLog(ivyLogLevel(logging)) + IvySbt.cleanResolutionCache(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) val resolveReport = ivy.resolve(module, resolveOptions) val err = if(resolveReport.hasError) diff --git a/ivy/IvyCache.scala b/ivy/IvyCache.scala index ff4b57bac..1a22a9977 100644 --- a/ivy/IvyCache.scala +++ b/ivy/IvyCache.scala @@ -86,7 +86,7 @@ class IvyCache(val ivyHome: Option[File]) { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index d2a5c958c..4d93d8722 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -21,12 +21,18 @@ sealed trait IvyConfiguration } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val log: Logger) extends IvyConfiguration + val checksums: Seq[String], val resolutionCacheDir: Option[File], val log: Logger) extends IvyConfiguration { + @deprecated("Use the variant that accepts the resolution cache location.", "0.13.0") + def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], + moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], + checksums: Seq[String], log: Logger) = + this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, log) + type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) } final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration { @@ -50,7 +56,7 @@ object IvyConfiguration if(defaultIvyConfigFile.canRead) ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, log) + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log) } } From 69724c4f8744078c90623610271072fdbe55bf6a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 28 Aug 2012 11:55:24 -0400 Subject: [PATCH 0200/1030] don't write section of pom if scope is 'compile' --- ivy/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 5dc39f069..9d57bbace 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -212,7 +212,7 @@ class MakePom(val log: Logger) scopeElem(scope) ++ optionalElem(opt) } def scopeElem(scope: Option[String]): NodeSeq = scope match { - case None => NodeSeq.Empty + case None | Some(Configurations.Compile.name) => NodeSeq.Empty case Some(s) => {s} } def optionalElem(opt: Boolean) = if(opt) true else NodeSeq.Empty From 7ed0c85097d941e4b3513b9185c1923bccb669e3 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 29 Aug 2012 11:13:48 -0400 Subject: [PATCH 0201/1030] Second part of resolution cache work. Fixes #532. Replaces the standard Ivy resolution cache: 1. Separate the cached resolved Ivy files from resolution reports, making resolution reports easier to find (target/resolution-cache/reports/) 2. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. --- ivy/Ivy.scala | 21 +++++++------ ivy/IvyActions.scala | 2 +- ivy/ResolutionCache.scala | 64 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 ivy/ResolutionCache.scala diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 20d3fd5e5..f512efef0 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -13,7 +13,7 @@ import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ResolutionCacheManager} +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.descriptor.{OverrideDependencyDescriptorMediator} @@ -277,17 +277,18 @@ private object IvySbt settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private[sbt] def cleanResolutionCache(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) - { - val files = - Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: - Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: - Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten - IO.delete(files) - } private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { - resCacheDir foreach { dir => settings.setDefaultResolutionCacheBasedir(dir.getAbsolutePath) } + configureResolutionCache(settings, localOnly, resCacheDir) + configureRepositoryCache(settings, localOnly) + } + private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) + { + val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir + settings.setResolutionCacheManager(new ResolutionCache(base)) + } + private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) + { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index 8bb952d06..e01cfba90 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -204,7 +204,7 @@ object IvyActions val resolveId = ResolveOptions.getDefaultResolveId(module) resolveOptions.setResolveId(resolveId) resolveOptions.setLog(ivyLogLevel(logging)) - IvySbt.cleanResolutionCache(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) + ResolutionCache.cleanModule(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) val resolveReport = ivy.resolve(module, resolveOptions) val err = if(resolveReport.hasError) diff --git a/ivy/ResolutionCache.scala b/ivy/ResolutionCache.scala new file mode 100644 index 000000000..c8846e251 --- /dev/null +++ b/ivy/ResolutionCache.scala @@ -0,0 +1,64 @@ +package sbt + +import java.io.File +import org.apache.ivy.core +import core.IvyPatternHelper +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, DefaultResolutionCacheManager, ResolutionCacheManager} +import core.module.id.ModuleRevisionId +import ResolutionCache.{Name, ReportDirectory, ResolvedName, ResolvedPattern} + +/** Replaces the standard Ivy resolution cache in order to: +* 1. Separate cached resolved Ivy files from resolution reports, making the resolution reports easier to find. +* 2. Have them per-project for easier cleaning (possible with standard cache, but central to this custom one). +* 3. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. +*/ +private[sbt] final class ResolutionCache(base: File) extends ResolutionCacheManager +{ + private[this] def resolvedFileInCache(m: ModuleRevisionId, name: String, ext: String): File = { + val p = ResolvedPattern + val f = IvyPatternHelper.substitute(p, m.getOrganisation, m.getName, m.getBranch, m.getRevision, name, name, ext, null, null, m.getAttributes, null) + new File(base, f) + } + private[this] def reportBase(resolveId: String): File = + new File(new File(base, ReportDirectory), resolveId) + + def getResolutionCacheRoot: File = base + def clean() { IO.delete(base) } + override def toString = Name + + def getResolvedIvyFileInCache(mrid: ModuleRevisionId): File = + resolvedFileInCache(mrid, ResolvedName, "xml") + def getResolvedIvyPropertiesInCache(mrid: ModuleRevisionId): File = + resolvedFileInCache(mrid, ResolvedName, "properties") + def getConfigurationResolveReportInCache(resolveId: String, conf: String): File = + new File(reportBase(resolveId), "/" + conf + "-" + ResolvedName) + def getConfigurationResolveReportsInCache(resolveId: String): Array[File] = + IO.listFiles(reportBase(resolveId)).flatMap(d => IO.listFiles(d)) +} +private[sbt] object ResolutionCache +{ + /** Removes cached files from the resolution cache for the module with ID `mrid` + * and the resolveId (as set on `ResolveOptions`). */ + private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) + { + val files = + Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: + Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: + Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten + IO.delete(files) + } + + private val ReportDirectory = "reports" + + // name of the file providing a dependency resolution report for a configuration + private val ReportFileName = "report.xml" + + // base name (name except for extension) of resolution report file + private val ResolvedName = "resolved" + + // Cache name + private val Name = "sbt-resolution-cache" + + // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions + private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]" +} \ No newline at end of file From 9a0b59b5979993f7770a6cdb33bd96ecd2ad9d68 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 29 Aug 2012 11:13:48 -0400 Subject: [PATCH 0202/1030] Force update on change to last modified time of artifacts or cached descriptor. This is part 2 of the fix for #532. It may also fix issues when working with multiple local projects via 'publish-local' and binary dependencies. --- ivy/IvyRetrieve.scala | 2 +- ivy/ResolutionCache.scala | 2 +- ivy/UpdateReport.scala | 17 ++++++++++++++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/ivy/IvyRetrieve.scala b/ivy/IvyRetrieve.scala index cd619afaf..dd0ffe910 100644 --- a/ivy/IvyRetrieve.scala +++ b/ivy/IvyRetrieve.scala @@ -48,7 +48,7 @@ object IvyRetrieve } def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = - new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report)) + new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps() def updateStats(report: ResolveReport): UpdateStats = new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = diff --git a/ivy/ResolutionCache.scala b/ivy/ResolutionCache.scala index c8846e251..a5026882b 100644 --- a/ivy/ResolutionCache.scala +++ b/ivy/ResolutionCache.scala @@ -54,7 +54,7 @@ private[sbt] object ResolutionCache private val ReportFileName = "report.xml" // base name (name except for extension) of resolution report file - private val ResolvedName = "resolved" + private val ResolvedName = "resolved.xml" // Cache name private val Name = "sbt-resolution-cache" diff --git a/ivy/UpdateReport.scala b/ivy/UpdateReport.scala index 6f8485c9d..071643eb2 100644 --- a/ivy/UpdateReport.scala +++ b/ivy/UpdateReport.scala @@ -13,15 +13,19 @@ package sbt * @param stats information about the update that produced this report * @see sbt.RichUpdateReport */ -final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats) +final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File,Long]) { + @deprecated("Use the variant that provides timestamps of files.", "0.13.0") + def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = + this(cachedDescriptor, configurations, stats, Map.empty) + override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString /** All resolved modules in all configurations. */ def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(cachedDescriptor, configurations map { _ retrieve f}, stats ) + new UpdateReport(cachedDescriptor, configurations map { _ retrieve f}, stats, stamps ) /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ def configuration(s: String) = configurations.find(_.configuration == s) @@ -71,6 +75,13 @@ object UpdateReport /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ final class RichUpdateReport(report: UpdateReport) { + def recomputeStamps(): UpdateReport = + { + val files = report.cachedDescriptor +: allFiles + val stamps = files.map(f => (f, f.lastModified)).toMap + new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) + } + import DependencyFilter._ /** Obtains all successfully retrieved files in all configurations and modules. */ def allFiles: Seq[File] = matching(DependencyFilter.allPass) @@ -123,7 +134,7 @@ object UpdateReport val newModules = modules map { modReport => f(configuration, modReport) } new ConfigurationReport(configuration, newModules, evicted) } - new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats) + new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } } } From 66ac1dbc9ad681289f5c4c52884cf30ffac80efb Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 1 Sep 2012 09:56:09 -0400 Subject: [PATCH 0203/1030] use context logger instead of initial logger for Resolving messages --- ivy/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index f512efef0..c6fd24422 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -235,7 +235,7 @@ private object IvySbt override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { if(data.getOptions.getLog != LogOptions.LOG_QUIET) - log.info("Resolving " + dd.getDependencyRevisionId + " ...") + Message.info("Resolving " + dd.getDependencyRevisionId + " ...") super.getDependency(dd, data) } } From a0b5b0e7ac2b6ed95149af59e836bf273b855a4e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 11 Sep 2012 11:37:41 -0400 Subject: [PATCH 0204/1030] Fail publishing when artifacts to publish do not exist. --- ivy/IvyActions.scala | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/ivy/IvyActions.scala b/ivy/IvyActions.scala index e01cfba90..ca493963e 100644 --- a/ivy/IvyActions.scala +++ b/ivy/IvyActions.scala @@ -251,9 +251,11 @@ object IvyActions } def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = + { + checkFilesPresent(artifacts) try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - for( (artifact, file) <- artifacts) if(file.exists) + for( (artifact, file) <- artifacts) resolver.publish(artifact, file, overwrite) resolver.commitPublishTransaction() } catch { @@ -261,6 +263,12 @@ object IvyActions try { resolver.abortPublishTransaction() } finally { throw e } } - + } + private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) + { + val missing = artifacts filter { case (a, file) => !file.exists } + if(missing.nonEmpty) + error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) + } } final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) From 614d9976d648d8903cfc5a1ae7f28f3b0e922d2b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 23 Sep 2012 15:46:26 -0400 Subject: [PATCH 0205/1030] invalidate cache when metadata deleted from local repository --- ivy/Ivy.scala | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index c6fd24422..0a7e07882 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -18,7 +18,7 @@ import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDe import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.descriptor.{OverrideDependencyDescriptorMediator} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import core.resolve.{IvyNode, ResolveData} +import core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} import core.settings.IvySettings import plugins.conflict.{ConflictManager, LatestCompatibleConflictManager, LatestConflictManager} import plugins.latest.LatestRevisionStrategy @@ -291,8 +291,24 @@ private object IvySbt { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { - override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = - super.findModuleInCache(dd,revId,options,null) + override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { + // ignore the resolver- not ideal, but avoids thrashing. + val resolved = super.findModuleInCache(dd,revId,options,null) + // invalidate the cache if the artifact was removed from the local repository + if(resolved == null) null + else { + val origin = resolved.getReport.getArtifactOrigin + if(!origin.isLocal) resolved + else { + val file = new File(origin.getLocation) + if(file == null || file.exists) resolved + else { + resolved.getReport.getLocalFile.delete() + null + } + } + } + } } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) From bc6770bec38cd7ebc03e26585647e0ca25ee9458 Mon Sep 17 00:00:00 2001 From: Eric Bowman Date: Thu, 25 Oct 2012 14:28:13 +0100 Subject: [PATCH 0206/1030] XSBT-5: maven-style ivy repo support in the launcher config Change-Id: I22c1ff126961d61d92e2e45a5b7eff329d3def90 Reviewed-on: https://gerrit.gilt.com/10950 Reviewed-by: Eric Bowman Tested-by: Eric Bowman --- ivy/IvyInterface.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index 0f37aa241..b1b9b9fcd 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -81,6 +81,15 @@ final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[Str private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) + override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible) + override def equals(obj: Any): Boolean = { + obj match { + case other: Patterns => + ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible + case _ => false + } + } + override def hashCode: Int = 617 * ivyPatterns.## + 37 * artifactPatterns.## + isMavenCompatible.hashCode } object Patterns { From 14057fb211210b9bb42c5041736b9f633a6cb51f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 29 Oct 2012 09:52:10 -0400 Subject: [PATCH 0207/1030] cleanup of #585: compatible with earlier launchers --- ivy/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index b1b9b9fcd..fb85ae0db 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -89,7 +89,7 @@ final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[Str case _ => false } } - override def hashCode: Int = 617 * ivyPatterns.## + 37 * artifactPatterns.## + isMavenCompatible.hashCode + override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible).hashCode } object Patterns { From f95c45f76e472c9b49057c1459556287da46fe75 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 12 Nov 2012 14:45:23 -0500 Subject: [PATCH 0208/1030] Fixes #582. Don't merge dependencies with mismatched transitive/force/changing values. This avoids the assertion, but note that Ivy is unlikely to work properly in this situation. --- ivy/Ivy.scala | 13 +++++++++---- ivy/MergeDescriptors.scala | 28 ++++++++++++++++------------ 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 0a7e07882..937648cc0 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -474,18 +474,23 @@ private object IvySbt */ def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = { - val deps = new java.util.LinkedHashMap[ModuleRevisionId, DependencyDescriptor] + // need to preserve basic order of dependencies: can't use dependencies.groupBy + val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] for( dd <- dependencies ) { val id = dd.getDependencyRevisionId val updated = deps get id match { - case null => dd - case v => ivyint.MergeDescriptors(v, dd) + case null => dd :: Nil + case v => dd :: v } deps.put(id, updated) } + import collection.JavaConverters._ - deps.values.asScala.toSeq + deps.values.asScala.toSeq.flatMap { dds => + val mergeable = (dds, dds.tail).zipped.forall( ivyint.MergeDescriptors.mergeable _) + if(mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds + } } /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ diff --git a/ivy/MergeDescriptors.scala b/ivy/MergeDescriptors.scala index f46f90501..e1c07c780 100644 --- a/ivy/MergeDescriptors.scala +++ b/ivy/MergeDescriptors.scala @@ -15,20 +15,24 @@ import util.extendable.ExtendableItem private[sbt] object MergeDescriptors { + def mergeable(a: DependencyDescriptor, b: DependencyDescriptor): Boolean = + a.isForce == b.isForce && + a.isChanging == b.isChanging && + a.isTransitive == b.isTransitive && + a.getParentRevisionId == b.getParentRevisionId && + a.getNamespace == b.getNamespace && { + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } + def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { - assert(a.isForce == b.isForce) - assert(a.isChanging == b.isChanging) - assert(a.isTransitive == b.isTransitive) - assert(a.getParentRevisionId == b.getParentRevisionId) - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - assert(amrid == bmrid) - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - assert(adyn == bdyn) - assert(a.getNamespace == b.getNamespace) - + assert(mergeable(a,b)) new MergedDescriptors(a,b) } } From c6a3b352c483181545d4d9349547536de21b564b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 14 Nov 2012 09:04:29 -0500 Subject: [PATCH 0209/1030] taking care of deprecations removed in Scala master --- ivy/Credentials.scala | 3 ++- ivy/Ivy.scala | 2 +- ivy/IvyUtil.scala | 7 +++++++ ivy/MakePom.scala | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) create mode 100644 ivy/IvyUtil.scala diff --git a/ivy/Credentials.scala b/ivy/Credentials.scala index dc09adbcc..882e1c22b 100644 --- a/ivy/Credentials.scala +++ b/ivy/Credentials.scala @@ -33,13 +33,14 @@ object Credentials case Right(dc) => dc } } + def loadCredentials(path: File): Either[String, DirectCredentials] = if(path.exists) { val properties = read(path) def get(keys: List[String]) = keys.flatMap(properties.get).headOption.toRight(keys.head + " not specified in credentials file: " + path) - List.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match + IvyUtil.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match { case (Nil, List(realm, host, user, pass)) => Right( new DirectCredentials(realm, host, user, pass) ) case (errors, _) => Left(errors.mkString("\n")) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 937648cc0..030d0c192 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -382,7 +382,7 @@ private object IvySbt private[sbt] def javaMap(m: Map[String,String], unqualify: Boolean = false) = { val map = if(unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m - if(map.isEmpty) null else scala.collection.JavaConversions.asJavaMap(map) + if(map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map) } private object javaMap diff --git a/ivy/IvyUtil.scala b/ivy/IvyUtil.scala new file mode 100644 index 000000000..1c99bb5d3 --- /dev/null +++ b/ivy/IvyUtil.scala @@ -0,0 +1,7 @@ +package sbt + +private[sbt] object IvyUtil +{ + def separate[A,B](l: Seq[Either[A,B]]): (Seq[A], Seq[B]) = + (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) +} \ No newline at end of file diff --git a/ivy/MakePom.scala b/ivy/MakePom.scala index 9d57bbace..c92de2aa0 100644 --- a/ivy/MakePom.scala +++ b/ivy/MakePom.scala @@ -237,7 +237,7 @@ class MakePom(val log: Logger) def exclusions(dependency: DependencyDescriptor): NodeSeq = { val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) - val (warns, excls) = List.separate(excl.map(makeExclusion)) + val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) if(!excls.isEmpty) {excls} else NodeSeq.Empty From 3f091e5f86b6dd643c0fd7aeeb92357fab698bf4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 20 Aug 2012 15:55:51 -0400 Subject: [PATCH 0210/1030] Resolve Scala version for projects in the normal `update` task. 1. Scala jars won't be copied to the boot directory, except for those needed to run sbt. 2. Scala SNAPSHOTs behave like normal SNAPSHOTs. In particular, running `update` will properly re-resolve the dynamic revision. 3. Scala jars are resolved using the same repositories and configuration as other dependencies. 4. Classloaders (currently, Scala classloaders) are cached by the timestamps of entries instead of Scala class loaders being cached by version. TODO: Support external dependency configuration --- ivy/IvyInterface.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/IvyInterface.scala b/ivy/IvyInterface.scala index fb85ae0db..4496f3cae 100644 --- a/ivy/IvyInterface.scala +++ b/ivy/IvyInterface.scala @@ -347,7 +347,7 @@ object Configurations def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) + def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom, ScalaTool) def names(cs: Seq[Configuration]) = cs.map(_.name) lazy val RuntimeInternal = optionalInternal(Runtime) @@ -379,6 +379,7 @@ object Configurations lazy val Optional = config("optional") lazy val Pom = config("pom") + lazy val ScalaTool = config("scala-tool") hide lazy val CompilerPlugin = config("plugin") hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) From ae67f6f85d7aedaa076c2f1fdff391fdbd39e183 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 2 Dec 2012 03:17:19 -0500 Subject: [PATCH 0211/1030] ConflictWarning cleanup, added strict convenience method for failing on any conflicts --- ivy/ConflictWarning.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ivy/ConflictWarning.scala b/ivy/ConflictWarning.scala index 1aa421388..f918990e1 100644 --- a/ivy/ConflictWarning.scala +++ b/ivy/ConflictWarning.scala @@ -11,18 +11,21 @@ object ConflictWarning def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), org, Level.Warn, false) + def strict(label: String): ConflictWarning = ConflictWarning(label, (id: ModuleID) => true, (id: ModuleID) => id.organization + ":" + id.name, Level.Error, true) + def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) { - val msg = "Potentially incompatible versions of dependencies of " + config.label + ":\n " + val prefix = if(config.failOnConflict) "Incompatible" else "Potentially incompatible" + val msg = prefix + " versions of dependencies of " + config.label + ":\n " val conflictMsgs = for( (label, versions) <- conflicts ) yield label + ": " + versions.mkString(", ") log.log(config.level, conflictMsgs.mkString(msg, "\n ", "")) } if(config.failOnConflict && !conflicts.isEmpty) - error("Conflicts in " + conflicts.map(_._1).mkString ) + error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) } } From 7f5f936db494195e68bd2051c125e79e11d3c75b Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 4 Dec 2012 12:19:14 -0500 Subject: [PATCH 0212/1030] Bumped the Scalatest/Specs versions for 2.10.0-RC3 * Modified tests to use mutable Specs API * Fixed a few minor specs issues. --- ivy/src/test/scala/ComponentManagerTest.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 1d9e77c44..a9bbe051f 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -1,7 +1,8 @@ package sbt import java.io.File -import org.specs._ +import org.specs2._ +import mutable.Specification import IO.{createDirectory, delete, touch, withTemporaryDirectory} import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail @@ -78,4 +79,4 @@ object ComponentManagerTest extends Specification private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), None, logger)) } ) -} \ No newline at end of file +} From 91553875a4df9446f15c6b4b293d467ad35f8c76 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 6 Dec 2012 07:25:41 -0500 Subject: [PATCH 0213/1030] add scala-tool configuration and dependencies when configuring via pom.xml/ivy.xml --- ivy/Ivy.scala | 15 +++++++++++++-- ivy/IvyConfigurations.scala | 2 ++ ivy/IvyScala.scala | 9 ++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/ivy/Ivy.scala b/ivy/Ivy.scala index 030d0c192..6f8ce9a64 100644 --- a/ivy/Ivy.scala +++ b/ivy/Ivy.scala @@ -168,6 +168,11 @@ final class IvySbt(val configuration: IvyConfiguration) val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) IvySbt.addConfigurations(dmd, Configurations.defaultInternal) + for( is <- pc.ivyScala) { + val confParser = new CustomXmlParser.CustomParser(settings, Some(Configurations.DefaultMavenConfiguration.name)) + confParser.setMd(dmd) + addScalaToolDependencies(dmd, confParser, is) + } (dmd, "compile") } /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ @@ -177,8 +182,14 @@ final class IvySbt(val configuration: IvyConfiguration) parser.setValidate(ifc.validate) parser.setSource(toURL(ifc.file)) parser.parse() - val md = parser.getModuleDescriptor() - (IvySbt.toDefaultModuleDescriptor(md), parser.getDefaultConf) + val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) + for( is <- ifc.ivyScala ) + addScalaToolDependencies(dmd, parser, is) + (dmd, parser.getDefaultConf) + } + private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala) { + IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) + IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) } private def toURL(file: File) = file.toURI.toURL private def configureEmpty(ec: EmptyConfiguration) = diff --git a/ivy/IvyConfigurations.scala b/ivy/IvyConfigurations.scala index 4d93d8722..734c56b91 100644 --- a/ivy/IvyConfigurations.scala +++ b/ivy/IvyConfigurations.scala @@ -79,6 +79,7 @@ final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, d def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) } +@deprecated("Define a module using inline Scala (InlineConfiguration), a pom.xml (PomConfiguration), or an ivy.xml (IvyFileConfiguration).", "0.13.0") final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { def noScala = copy(ivyScala = None) @@ -100,6 +101,7 @@ object InlineConfiguration } object ModuleSettings { + @deprecated("Explicitly select configuration from pom.xml, ivy.xml, or inline Scala.", "0.13.0") def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = { log.debug("Autodetecting dependencies.") diff --git a/ivy/IvyScala.scala b/ivy/IvyScala.scala index e21d3d01a..23b7597ff 100644 --- a/ivy/IvyScala.scala +++ b/ivy/IvyScala.scala @@ -19,6 +19,13 @@ object ScalaArtifacts val LibraryID = ScalaLibraryID val CompilerID = ScalaCompilerID def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) + + private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( + scalaToolDependency(org, ScalaArtifacts.CompilerID, version), + scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + ) + private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = + ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)") ) } object SbtArtifacts { @@ -28,7 +35,7 @@ object SbtArtifacts import ScalaArtifacts._ -final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) +final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization) private object IvyScala { From 3f8a09a6c7ebceee12822d551280f14f672d2038 Mon Sep 17 00:00:00 2001 From: Grzegorz Kossakowski Date: Fri, 7 Dec 2012 10:27:08 -0800 Subject: [PATCH 0214/1030] Follow source layout convention supported by Eclipse. Moved source files so directory structure follow package structure. That makes it possible to use Scala Eclipse plugin with sbt's source code. --- ivy/src/main/java/{ => sbt}/ResolverAdapter.java | 0 ivy/{ => src/main/scala/sbt}/ComponentManager.scala | 0 ivy/{ => src/main/scala/sbt}/ConflictWarning.scala | 0 ivy/{ => src/main/scala/sbt}/ConvertResolver.scala | 0 ivy/{ => src/main/scala/sbt}/Credentials.scala | 0 ivy/{ => src/main/scala/sbt}/CrossVersion.scala | 0 ivy/{ => src/main/scala/sbt}/CustomPomParser.scala | 0 ivy/{ => src/main/scala/sbt}/CustomXmlParser.scala | 0 ivy/{ => src/main/scala/sbt}/DependencyFilter.scala | 0 ivy/{ => src/main/scala/sbt}/Ivy.scala | 0 ivy/{ => src/main/scala/sbt}/IvyActions.scala | 0 ivy/{ => src/main/scala/sbt}/IvyCache.scala | 0 ivy/{ => src/main/scala/sbt}/IvyConfigurations.scala | 0 ivy/{ => src/main/scala/sbt}/IvyInterface.scala | 0 ivy/{ => src/main/scala/sbt}/IvyLogger.scala | 0 ivy/{ => src/main/scala/sbt}/IvyRetrieve.scala | 0 ivy/{ => src/main/scala/sbt}/IvyScala.scala | 0 ivy/{ => src/main/scala/sbt}/IvyUtil.scala | 0 ivy/{ => src/main/scala/sbt}/MakePom.scala | 0 ivy/{ => src/main/scala/sbt}/ProjectResolver.scala | 0 ivy/{ => src/main/scala/sbt}/ResolutionCache.scala | 0 ivy/{ => src/main/scala/sbt}/StringUtilities.scala | 0 ivy/{ => src/main/scala/sbt}/UpdateReport.scala | 0 ivy/{ => src/main/scala/sbt/impl}/DependencyBuilders.scala | 0 ivy/{ => src/main/scala/sbt/ivyint}/MergeDescriptors.scala | 0 25 files changed, 0 insertions(+), 0 deletions(-) rename ivy/src/main/java/{ => sbt}/ResolverAdapter.java (100%) rename ivy/{ => src/main/scala/sbt}/ComponentManager.scala (100%) rename ivy/{ => src/main/scala/sbt}/ConflictWarning.scala (100%) rename ivy/{ => src/main/scala/sbt}/ConvertResolver.scala (100%) rename ivy/{ => src/main/scala/sbt}/Credentials.scala (100%) rename ivy/{ => src/main/scala/sbt}/CrossVersion.scala (100%) rename ivy/{ => src/main/scala/sbt}/CustomPomParser.scala (100%) rename ivy/{ => src/main/scala/sbt}/CustomXmlParser.scala (100%) rename ivy/{ => src/main/scala/sbt}/DependencyFilter.scala (100%) rename ivy/{ => src/main/scala/sbt}/Ivy.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyActions.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyCache.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyConfigurations.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyInterface.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyLogger.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyRetrieve.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyScala.scala (100%) rename ivy/{ => src/main/scala/sbt}/IvyUtil.scala (100%) rename ivy/{ => src/main/scala/sbt}/MakePom.scala (100%) rename ivy/{ => src/main/scala/sbt}/ProjectResolver.scala (100%) rename ivy/{ => src/main/scala/sbt}/ResolutionCache.scala (100%) rename ivy/{ => src/main/scala/sbt}/StringUtilities.scala (100%) rename ivy/{ => src/main/scala/sbt}/UpdateReport.scala (100%) rename ivy/{ => src/main/scala/sbt/impl}/DependencyBuilders.scala (100%) rename ivy/{ => src/main/scala/sbt/ivyint}/MergeDescriptors.scala (100%) diff --git a/ivy/src/main/java/ResolverAdapter.java b/ivy/src/main/java/sbt/ResolverAdapter.java similarity index 100% rename from ivy/src/main/java/ResolverAdapter.java rename to ivy/src/main/java/sbt/ResolverAdapter.java diff --git a/ivy/ComponentManager.scala b/ivy/src/main/scala/sbt/ComponentManager.scala similarity index 100% rename from ivy/ComponentManager.scala rename to ivy/src/main/scala/sbt/ComponentManager.scala diff --git a/ivy/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala similarity index 100% rename from ivy/ConflictWarning.scala rename to ivy/src/main/scala/sbt/ConflictWarning.scala diff --git a/ivy/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala similarity index 100% rename from ivy/ConvertResolver.scala rename to ivy/src/main/scala/sbt/ConvertResolver.scala diff --git a/ivy/Credentials.scala b/ivy/src/main/scala/sbt/Credentials.scala similarity index 100% rename from ivy/Credentials.scala rename to ivy/src/main/scala/sbt/Credentials.scala diff --git a/ivy/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala similarity index 100% rename from ivy/CrossVersion.scala rename to ivy/src/main/scala/sbt/CrossVersion.scala diff --git a/ivy/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala similarity index 100% rename from ivy/CustomPomParser.scala rename to ivy/src/main/scala/sbt/CustomPomParser.scala diff --git a/ivy/CustomXmlParser.scala b/ivy/src/main/scala/sbt/CustomXmlParser.scala similarity index 100% rename from ivy/CustomXmlParser.scala rename to ivy/src/main/scala/sbt/CustomXmlParser.scala diff --git a/ivy/DependencyFilter.scala b/ivy/src/main/scala/sbt/DependencyFilter.scala similarity index 100% rename from ivy/DependencyFilter.scala rename to ivy/src/main/scala/sbt/DependencyFilter.scala diff --git a/ivy/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala similarity index 100% rename from ivy/Ivy.scala rename to ivy/src/main/scala/sbt/Ivy.scala diff --git a/ivy/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala similarity index 100% rename from ivy/IvyActions.scala rename to ivy/src/main/scala/sbt/IvyActions.scala diff --git a/ivy/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala similarity index 100% rename from ivy/IvyCache.scala rename to ivy/src/main/scala/sbt/IvyCache.scala diff --git a/ivy/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala similarity index 100% rename from ivy/IvyConfigurations.scala rename to ivy/src/main/scala/sbt/IvyConfigurations.scala diff --git a/ivy/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala similarity index 100% rename from ivy/IvyInterface.scala rename to ivy/src/main/scala/sbt/IvyInterface.scala diff --git a/ivy/IvyLogger.scala b/ivy/src/main/scala/sbt/IvyLogger.scala similarity index 100% rename from ivy/IvyLogger.scala rename to ivy/src/main/scala/sbt/IvyLogger.scala diff --git a/ivy/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala similarity index 100% rename from ivy/IvyRetrieve.scala rename to ivy/src/main/scala/sbt/IvyRetrieve.scala diff --git a/ivy/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala similarity index 100% rename from ivy/IvyScala.scala rename to ivy/src/main/scala/sbt/IvyScala.scala diff --git a/ivy/IvyUtil.scala b/ivy/src/main/scala/sbt/IvyUtil.scala similarity index 100% rename from ivy/IvyUtil.scala rename to ivy/src/main/scala/sbt/IvyUtil.scala diff --git a/ivy/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala similarity index 100% rename from ivy/MakePom.scala rename to ivy/src/main/scala/sbt/MakePom.scala diff --git a/ivy/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala similarity index 100% rename from ivy/ProjectResolver.scala rename to ivy/src/main/scala/sbt/ProjectResolver.scala diff --git a/ivy/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala similarity index 100% rename from ivy/ResolutionCache.scala rename to ivy/src/main/scala/sbt/ResolutionCache.scala diff --git a/ivy/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala similarity index 100% rename from ivy/StringUtilities.scala rename to ivy/src/main/scala/sbt/StringUtilities.scala diff --git a/ivy/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala similarity index 100% rename from ivy/UpdateReport.scala rename to ivy/src/main/scala/sbt/UpdateReport.scala diff --git a/ivy/DependencyBuilders.scala b/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala similarity index 100% rename from ivy/DependencyBuilders.scala rename to ivy/src/main/scala/sbt/impl/DependencyBuilders.scala diff --git a/ivy/MergeDescriptors.scala b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala similarity index 100% rename from ivy/MergeDescriptors.scala rename to ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala From 469202aeeca5af3f838072da77f8fec7ec2d8338 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 9 Dec 2012 20:40:41 -0500 Subject: [PATCH 0215/1030] More cleanup of Scala version handling, including managedScalaInstance to control automatic 'scala-tool' configuration and dependencies. --- ivy/src/main/scala/sbt/Ivy.scala | 9 +++++---- ivy/src/main/scala/sbt/IvyConfigurations.scala | 8 ++++---- ivy/src/main/scala/sbt/IvyInterface.scala | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 6f8ce9a64..ce985c95c 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -168,12 +168,13 @@ final class IvySbt(val configuration: IvyConfiguration) val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) IvySbt.addConfigurations(dmd, Configurations.defaultInternal) - for( is <- pc.ivyScala) { - val confParser = new CustomXmlParser.CustomParser(settings, Some(Configurations.DefaultMavenConfiguration.name)) + val defaultConf = Configurations.DefaultMavenConfiguration.name + for( is <- pc.ivyScala) if(pc.autoScalaTools) { + val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) confParser.setMd(dmd) addScalaToolDependencies(dmd, confParser, is) } - (dmd, "compile") + (dmd, defaultConf) } /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ private def configureIvyFile(ifc: IvyFileConfiguration) = @@ -183,7 +184,7 @@ final class IvySbt(val configuration: IvyConfiguration) parser.setSource(toURL(ifc.file)) parser.parse() val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) - for( is <- ifc.ivyScala ) + for( is <- ifc.ivyScala ) if(ifc.autoScalaTools) addScalaToolDependencies(dmd, parser, is) (dmd, parser.getDefaultConf) } diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index 734c56b91..f46d24dbd 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -66,11 +66,11 @@ sealed trait ModuleSettings def ivyScala: Option[IvyScala] def noScala: ModuleSettings } -final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings +final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { def noScala = copy(ivyScala = None) } -final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings +final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { def noScala = copy(ivyScala = None) } @@ -107,12 +107,12 @@ object ModuleSettings log.debug("Autodetecting dependencies.") val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) if(defaultPOMFile.canRead) - new PomConfiguration(defaultPOMFile, ivyScala, validate) + new PomConfiguration(defaultPOMFile, ivyScala, validate, true) else { val defaultIvy = IvySbt.defaultIvyFile(baseDirectory) if(defaultIvy.canRead) - new IvyFileConfiguration(defaultIvy, ivyScala, validate) + new IvyFileConfiguration(defaultIvy, ivyScala, validate, true) else { log.warn("No dependency configuration found, using defaults.") diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 4496f3cae..6a7381831 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -347,7 +347,7 @@ object Configurations def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom, ScalaTool) + def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) def names(cs: Seq[Configuration]) = cs.map(_.name) lazy val RuntimeInternal = optionalInternal(Runtime) From 16c719764e8a1d92da5e3f4e6f968398f1aceb28 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 4 Jan 2013 17:22:40 -0500 Subject: [PATCH 0216/1030] Convert references to harrah/xsbt to sbt/sbt --- ivy/src/main/scala/sbt/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index ce985c95c..30b19368f 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -478,7 +478,7 @@ private object IvySbt /** Combines the artifacts, includes, and excludes of duplicate dependency definitions. * This is somewhat fragile and is only intended to workaround Ivy (or sbt's use of Ivy) not handling this case properly. * In particular, Ivy will create multiple dependency entries when converting a pom with a dependency on a classified artifact and a non-classified artifact: - * https://github.com/harrah/xsbt/issues/468 + * https://github.com/sbt/sbt/issues/468 * It will also allow users to declare dependencies on classified modules in different configurations: * https://groups.google.com/d/topic/simple-build-tool/H2MdAARz6e0/discussion * as well as basic multi-classifier handling: #285, #419, #480. From ff7889289563a5f6449303f3a7f2e8112be4cf7d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Jan 2013 16:06:12 -0500 Subject: [PATCH 0217/1030] Disable Ivy debug-level logging (see elaboration below). Fixes #635. The verbose-level logging is what usually contains relevant information for the user. Persisting the debug logging slows down update noticeably and clutters the more useful debug logging output from verbose. --- ivy/src/main/scala/sbt/IvyLogger.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyLogger.scala b/ivy/src/main/scala/sbt/IvyLogger.scala index 1d68e7e3a..acd07781b 100644 --- a/ivy/src/main/scala/sbt/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/IvyLogger.scala @@ -21,7 +21,9 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger case MSG_ERR => error(msg) } } - def debug(msg: String) = logger.debug(msg) + //DEBUG level messages are very verbose and rarely useful to users. + // TODO: provide access to this information some other way + def debug(msg: String) {} def verbose(msg: String) = logger.verbose(msg) def deprecated(msg: String) = warn(msg) def info(msg: String) = logger.info(msg) From 8e34e15f69488b196b441be74569ffc2510d55c0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Jan 2013 16:06:12 -0500 Subject: [PATCH 0218/1030] Option to automatically manage API documentation mappings Set autoAPIMappings := true to enable. Then, set apiURL to the base URL of the API documentation for a project. This will get stored in an extra attribute in the ivy.xml or as a property a pom.xml. When using managed dependencies that have set their apiURL, the -doc-external-doc setting for scaladoc will be automatically configured. Note that this option will only be available in Scala 2.10.1 and so enabling autoAPIMappings for earlier versions will result in an error from scaladoc. For unmanaged dependencies or dependencies without an automatic apiURL, add the (File,URL) mapping to apiMappings. The File is the classpath entry and the URL is the location of the API documentation. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 8 ++++++-- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- ivy/src/main/scala/sbt/IvyInterface.scala | 9 +++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 668aa5cff..277b50900 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -30,9 +30,14 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module } object CustomPomParser { + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ + val InfoKeyPrefix = "info." + val ApiURLKey = "info.apiURL" + val SbtVersionKey = "sbtVersion" val ScalaVersionKey = "scalaVersion" val ExtraAttributesKey = "extraDependencyAttributes" + private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) // packagings that should be jars, but that Ivy doesn't handle as jars val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") @@ -75,8 +80,7 @@ object CustomPomParser } private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) - private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = - m.filter { case (SbtVersionKey | ScalaVersionKey | ExtraAttributesKey,_) => true; case _ => false } + private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = if(properties.isEmpty) id else addExtra(properties, id) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index ca493963e..66a00f615 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -138,7 +138,7 @@ object IvyActions def processUnresolved(err: ResolveException, log: Logger) { - val withExtra = err.failed.filter(!_.extraAttributes.isEmpty) + val withExtra = err.failed.filter(!_.extraDependencyAttributes.isEmpty) if(!withExtra.isEmpty) { log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 6a7381831..159c53b7a 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -11,11 +11,16 @@ import org.apache.ivy.util.url.CredentialsStore final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { - override def toString = + override def toString: String = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + (if(extraAttributes.isEmpty) "" else " " + extraString) - def extraString = extraAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") + + /** String representation of the extra attributes, excluding any information only attributes. */ + def extraString: String = extraDependencyAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") + + /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ + def extraDependencyAttributes: Map[String,String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) From bad48a6f0d9c30b385ab7a5036675b7134a10606 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Jan 2013 16:06:12 -0500 Subject: [PATCH 0219/1030] API documentation for ModuleID methods --- ivy/src/main/scala/sbt/IvyInterface.scala | 50 +++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 159c53b7a..bd05f56c9 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -24,28 +24,78 @@ final case class ModuleID(organization: String, name: String, revision: String, @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) + /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) // () required for chaining + /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ def notTransitive() = intransitive() + + /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ def intransitive() = copy(isTransitive = false) + + /** Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, + * redownload it. sbt configures all -SNAPSHOT dependencies to be changing. + * + * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. + * */ def changing() = copy(isChanging = true) + + /** Indicates that conflict resolution should only select this module's revision. + * This prevents a newer revision from being pulled in by a transitive dependency, for example.*/ def force() = copy(isForce = true) + + /** Specifies a URL from which the main artifact for this dependency can be downloaded. + * This value is only consulted if the module is not found in a repository. + * It is not included in published metadata.*/ def from(url: String) = artifacts(Artifact(name, new URL(url))) + + /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String) = artifacts(Artifact(name, c)) + + /** Declares the explicit artifacts for this module. If this ModuleID represents a dependency, + * these artifact definitions override the information in the dependency's published metadata. */ def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + + /** Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify + * both the exact organization and name and nothing else will be included in a pom.xml.*/ def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + + /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) + def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead.*/ def sources() = artifacts(Artifact.sources(name)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead.*/ def javadoc() = artifacts(Artifact.javadoc(name)) + def pomOnly() = artifacts(Artifact.pom(name)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ def withSources() = jarIfEmpty.sources() + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ def withJavadoc() = jarIfEmpty.javadoc() + private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this + + /** Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such + * as when adding a dependency on an artifact with a classifier.*/ def jar() = artifacts(Artifact(name)) } object ModuleID From d0815e88ae1455937204ea9119f93bb719bfc7d9 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Jan 2013 16:06:13 -0500 Subject: [PATCH 0220/1030] Split IvyInterface into Artifact, Configuration, ModuleID, and Resolver source files --- ivy/src/main/scala/sbt/Artifact.scala | 71 +++ ivy/src/main/scala/sbt/Configuration.scala | 65 +++ ivy/src/main/scala/sbt/IvyInterface.scala | 500 +-------------------- ivy/src/main/scala/sbt/ModuleID.scala | 102 +++++ ivy/src/main/scala/sbt/Resolver.scala | 289 ++++++++++++ 5 files changed, 529 insertions(+), 498 deletions(-) create mode 100644 ivy/src/main/scala/sbt/Artifact.scala create mode 100644 ivy/src/main/scala/sbt/Configuration.scala create mode 100644 ivy/src/main/scala/sbt/ModuleID.scala create mode 100644 ivy/src/main/scala/sbt/Resolver.scala diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/ivy/src/main/scala/sbt/Artifact.scala new file mode 100644 index 000000000..987a1f8ca --- /dev/null +++ b/ivy/src/main/scala/sbt/Artifact.scala @@ -0,0 +1,71 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ +package sbt + +import java.io.File +import java.net.URL + +final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) +{ + def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) +} + + import Configurations.{config, Docs, Optional, Pom, Sources} + +object Artifact +{ + def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) + def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) + def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) + def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) + def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) + def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = + Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) + + val DefaultExtension = "jar" + val DefaultType = "jar" + + def sources(name: String) = classified(name, SourceClassifier) + def javadoc(name: String) = classified(name, DocClassifier) + def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) + + val DocClassifier = "javadoc" + val SourceClassifier = "sources" + val DocType = "doc" + val SourceType = "src" + val PomType = "pom" + + def extract(url: URL, default: String): String = extract(url.toString, default) + def extract(name: String, default: String): String = + { + val i = name.lastIndexOf('.') + if(i >= 0) + name.substring(i+1) + else + default + } + def defaultArtifact(file: File) = + { + val name = file.getName + val i = name.lastIndexOf('.') + val base = if(i >= 0) name.substring(0, i) else name + Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) + } + def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = + { + import artifact._ + val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } + val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) + val base = CrossVersion.applyCross(artifact.name, cross) + base + "-" + module.revision + classifierStr + "." + artifact.extension + } + + val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) + val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) + def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix("test-"), DefaultType) + def classified(name: String, classifier: String): Artifact = + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) +} diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala new file mode 100644 index 000000000..a259f99d7 --- /dev/null +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -0,0 +1,65 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ +package sbt + +object Configurations +{ + def config(name: String) = new Configuration(name) + def default: Seq[Configuration] = defaultMavenConfigurations + def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) + def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) + def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) + def names(cs: Seq[Configuration]) = cs.map(_.name) + + lazy val RuntimeInternal = optionalInternal(Runtime) + lazy val TestInternal = fullInternal(Test) + lazy val IntegrationTestInternal = fullInternal(IntegrationTest) + lazy val CompileInternal = fullInternal(Compile) + + def internalMap(c: Configuration) = c match { + case Compile => CompileInternal + case Test => TestInternal + case Runtime => RuntimeInternal + case IntegrationTest => IntegrationTestInternal + case _ => c + } + + def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend(ext : _*) hide; + def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) + def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) + + lazy val Default = config("default") + lazy val Compile = config("compile") + lazy val IntegrationTest = config("it") extend(Runtime) + lazy val Provided = config("provided") ; + lazy val Docs = config("docs") + lazy val Runtime = config("runtime") extend(Compile) + lazy val Test = config("test") extend(Runtime) + lazy val Sources = config("sources") + lazy val System = config("system") + lazy val Optional = config("optional") + lazy val Pom = config("pom") + + lazy val ScalaTool = config("scala-tool") hide + lazy val CompilerPlugin = config("plugin") hide + + private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) + private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) + private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration + private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default + private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) +} +/** Represents an Ivy configuration. */ +final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) +{ + require(name != null && !name.isEmpty) + require(description != null) + def this(name: String) = this(name, "", true, Nil, true) + def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) + def notTransitive = intransitive + def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) + def hide = Configuration(name, description, false, extendsConfigs, transitive) + override def toString = name +} diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index bd05f56c9..a1a651e55 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -9,101 +9,6 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) -{ - override def toString: String = - organization + ":" + name + ":" + revision + - (configurations match { case Some(s) => ":" + s; case None => "" }) + - (if(extraAttributes.isEmpty) "" else " " + extraString) - - /** String representation of the extra attributes, excluding any information only attributes. */ - def extraString: String = extraDependencyAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") - - /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ - def extraDependencyAttributes: Map[String,String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) - - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) - - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) - - /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ - def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) - - // () required for chaining - /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ - def notTransitive() = intransitive() - - /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ - def intransitive() = copy(isTransitive = false) - - /** Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, - * redownload it. sbt configures all -SNAPSHOT dependencies to be changing. - * - * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. - * */ - def changing() = copy(isChanging = true) - - /** Indicates that conflict resolution should only select this module's revision. - * This prevents a newer revision from being pulled in by a transitive dependency, for example.*/ - def force() = copy(isForce = true) - - /** Specifies a URL from which the main artifact for this dependency can be downloaded. - * This value is only consulted if the module is not found in a repository. - * It is not included in published metadata.*/ - def from(url: String) = artifacts(Artifact(name, new URL(url))) - - /** Adds a dependency on the artifact for this module with classifier `c`. */ - def classifier(c: String) = artifacts(Artifact(name, c)) - - /** Declares the explicit artifacts for this module. If this ModuleID represents a dependency, - * these artifact definitions override the information in the dependency's published metadata. */ - def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) - - /** Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify - * both the exact organization and name and nothing else will be included in a pom.xml.*/ - def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) - - /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) - - def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) - - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" - * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead.*/ - def sources() = artifacts(Artifact.sources(name)) - - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" - * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead.*/ - def javadoc() = artifacts(Artifact.javadoc(name)) - - def pomOnly() = artifacts(Artifact.pom(name)) - - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" - * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ - def withSources() = jarIfEmpty.sources() - - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" - * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ - def withJavadoc() = jarIfEmpty.javadoc() - - private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this - - /** Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such - * as when adding a dependency on an artifact with a classifier.*/ - def jar() = artifacts(Artifact(name)) -} -object ModuleID -{ - def checkE(attributes: Seq[(String, String)]) = - for ( (key, value) <- attributes) yield - if(key.startsWith("e:")) (key, value) else ("e:" + key, value) -} /** Additional information about a project module */ case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { @@ -112,414 +17,13 @@ case class ModuleInfo(nameFormal: String, description: String = "", homepage: Op def licensed(lics: (String, URL)*) = copy(licenses = lics) def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) } + /** Basic SCM information for a project module */ case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) + /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) -sealed trait Resolver -{ - def name: String -} -final class RawRepository(val resolver: DependencyResolver) extends Resolver -{ - def name = resolver.getName - override def toString = "Raw(" + resolver.toString + ")" -} -sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver -sealed case class MavenRepository(name: String, root: String) extends Resolver -{ - override def toString = name + ": " + root -} -final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) -{ - private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) - private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) - private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) - override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible) - override def equals(obj: Any): Boolean = { - obj match { - case other: Patterns => - ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible - case _ => false - } - } - override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible).hashCode -} -object Patterns -{ - implicit def defaultPatterns: Patterns = Resolver.defaultPatterns - - def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) - def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) -} -object RepositoryHelpers -{ - final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) - { - def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) - } - /** Configuration specific to an Ivy filesystem resolver. */ - final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) - { - def transactional() = FileConfiguration(isLocal, Some(true)) - def nontransactional() = FileConfiguration(isLocal, Some(false)) - def nonlocal() = FileConfiguration(false, isTransactional) - } - sealed trait SshAuthentication extends NotNull - final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication - final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication -} -import RepositoryHelpers.{SshConnection, FileConfiguration} -import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} - -/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ -sealed abstract class PatternsBasedRepository extends Resolver -{ - type RepositoryType <: PatternsBasedRepository - /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ - protected def copy(patterns: Patterns): RepositoryType - - /** The object representing the configured patterns for this repository. */ - def patterns: Patterns - - /** Enables maven 2 compatibility for this repository. */ - def mavenStyle() = copy(patterns.mavenStyle()) - /** Adds the given patterns for resolving/publishing Ivy files.*/ - def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) - /** Adds the given patterns for resolving/publishing artifacts.*/ - def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) -} -/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ -final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository -{ - type RepositoryType = FileRepository - protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) - private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) - def transactional() = copy(configuration.transactional()) - def nonlocal() = copy(configuration.nonlocal()) -} -final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository -{ - type RepositoryType = URLRepository - protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) -} -/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ -sealed abstract class SshBasedRepository extends PatternsBasedRepository -{ - type RepositoryType <: SshBasedRepository - protected def copy(connection: SshConnection): RepositoryType - private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) - - /** The object representing the configured ssh connection for this repository. */ - def connection: SshConnection - - /** Configures this to use the specified user name and password when connecting to the remote repository. */ - def as(user: String, password: String): RepositoryType = as(user, Some(password)) - def as(user: String): RepositoryType = as(user, None) - def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) - /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ - def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) - def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) - def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) -} -/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ -final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository -{ - type RepositoryType = SshRepository - protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - /** Defines the permissions to set when publishing to this repository. */ - def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) - def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) -} -/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ -final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository -{ - type RepositoryType = SftpRepository - protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) - protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) -} - -import Resolver._ -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") -object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") -object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) -object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) -object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) -object JavaNet1Repository extends JavaNet1Repository -sealed trait JavaNet1Repository extends Resolver -{ - def name = "java.net Maven1 Repository" -} - -object Resolver -{ - val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" - val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" - val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesName = "Sonatype OSS Releases" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" - val JavaNet2RepositoryName = "java.net Maven2 Repository" - val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" - - def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) - def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) - def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) - def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) - - /** Add the local and Maven Central repositories to the user repositories. */ - def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = - withDefaultResolvers(userResolvers, true) - /** Add the local Ivy repository to the user repositories. - * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = - Seq(Resolver.defaultLocal) ++ - userResolvers ++ - single(DefaultMavenRepository, mavenCentral) - private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if(nonEmpty) Seq(value) else Nil - - /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ - sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull - { - /** Subclasses should implement this method to */ - protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType - /** Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject - * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, None, None, None) - /** Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), None, None) - /** Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), None, Some(basePath)) - /** Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), Some(port), None) - /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), Some(port), Some(basePath)) - /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = - construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) - } - /** A factory to construct an interface to an Ivy SSH resolver.*/ - object ssh extends Define[SshRepository] - { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) - } - /** A factory to construct an interface to an Ivy SFTP resolver.*/ - object sftp extends Define[SftpRepository] - { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) - } - /** A factory to construct an interface to an Ivy filesytem resolver. */ - object file - { - /** Constructs a file resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) - /** Constructs a file resolver with the given name and base directory. */ - def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) - } - object url - { - /** Constructs a URL resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) - /** Constructs a file resolver with the given name and base directory. */ - def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = - baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) - } - private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = - construct(resolvePatterns(base, basePatterns)) - - /** If `base` is None, `patterns` is returned unchanged. - * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ - private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = - base match - { - case Some(path) => resolvePatterns(path, patterns) - case None => patterns - } - /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ - private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = - { - def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) - Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) - } - private[sbt] def resolvePattern(base: String, pattern: String): String = - { - val normBase = base.replace('\\', '/') - if(normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern - } - def defaultFileConfiguration = FileConfiguration(true, None) - def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) - def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) - - def defaultPatterns = mavenStylePatterns - def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" - def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" - final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - - def mavenLocal = MavenRepository("Maven2 Local", (new File(Path.userHome, ".m2/repository/")).toURI.toURL.toExternalForm) - def defaultLocal = defaultUserFileRepository("local") - def defaultShared = defaultUserFileRepository("shared") - def defaultUserFileRepository(id: String) = - { - val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil - FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) - } - def defaultIvyPatterns = - { - val pList = List(localBasePattern) - Patterns(pList, pList, false) - } -} - -object Configurations -{ - def config(name: String) = new Configuration(name) - def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) - def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) - def names(cs: Seq[Configuration]) = cs.map(_.name) - - lazy val RuntimeInternal = optionalInternal(Runtime) - lazy val TestInternal = fullInternal(Test) - lazy val IntegrationTestInternal = fullInternal(IntegrationTest) - lazy val CompileInternal = fullInternal(Compile) - - def internalMap(c: Configuration) = c match { - case Compile => CompileInternal - case Test => TestInternal - case Runtime => RuntimeInternal - case IntegrationTest => IntegrationTestInternal - case _ => c - } - - def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend(ext : _*) hide; - def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) - def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) - - lazy val Default = config("default") - lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend(Runtime) - lazy val Provided = config("provided") ; - lazy val Docs = config("docs") - lazy val Runtime = config("runtime") extend(Compile) - lazy val Test = config("test") extend(Runtime) - lazy val Sources = config("sources") - lazy val System = config("system") - lazy val Optional = config("optional") - lazy val Pom = config("pom") - - lazy val ScalaTool = config("scala-tool") hide - lazy val CompilerPlugin = config("plugin") hide - - private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) - private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) - private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration - private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default - private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) -} -/** Represents an Ivy configuration. */ -final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) -{ - require(name != null && !name.isEmpty) - require(description != null) - def this(name: String) = this(name, "", true, Nil, true) - def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) - def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) - def notTransitive = intransitive - def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) - def hide = Configuration(name, description, false, extendsConfigs, transitive) - override def toString = name -} - -final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) -{ - def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) -} - - import Configurations.{config, Docs, Optional, Pom, Sources} - -object Artifact -{ - def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) - def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) - def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) - def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) - def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) - def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = - Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) - - val DefaultExtension = "jar" - val DefaultType = "jar" - - def sources(name: String) = classified(name, SourceClassifier) - def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) - - val DocClassifier = "javadoc" - val SourceClassifier = "sources" - val DocType = "doc" - val SourceType = "src" - val PomType = "pom" - - def extract(url: URL, default: String): String = extract(url.toString, default) - def extract(name: String, default: String): String = - { - val i = name.lastIndexOf('.') - if(i >= 0) - name.substring(i+1) - else - default - } - def defaultArtifact(file: File) = - { - val name = file.getName - val i = name.lastIndexOf('.') - val base = if(i >= 0) name.substring(0, i) else name - Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) - } - def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = - { - import artifact._ - val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) - val base = CrossVersion.applyCross(artifact.name, cross) - base + "-" + module.revision + classifierStr + "." + artifact.extension - } - - val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) - val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix("test-"), DefaultType) - def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) -} final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration { diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala new file mode 100644 index 000000000..df69274d4 --- /dev/null +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -0,0 +1,102 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ +package sbt + + import java.net.URL + +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) +{ + override def toString: String = + organization + ":" + name + ":" + revision + + (configurations match { case Some(s) => ":" + s; case None => "" }) + + (if(extraAttributes.isEmpty) "" else " " + extraString) + + /** String representation of the extra attributes, excluding any information only attributes. */ + def extraString: String = extraDependencyAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") + + /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ + def extraDependencyAttributes: Map[String,String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) + + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") + def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) + + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") + def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) + + /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ + def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) + + // () required for chaining + /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ + def notTransitive() = intransitive() + + /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ + def intransitive() = copy(isTransitive = false) + + /** Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, + * redownload it. sbt configures all -SNAPSHOT dependencies to be changing. + * + * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. + * */ + def changing() = copy(isChanging = true) + + /** Indicates that conflict resolution should only select this module's revision. + * This prevents a newer revision from being pulled in by a transitive dependency, for example.*/ + def force() = copy(isForce = true) + + /** Specifies a URL from which the main artifact for this dependency can be downloaded. + * This value is only consulted if the module is not found in a repository. + * It is not included in published metadata.*/ + def from(url: String) = artifacts(Artifact(name, new URL(url))) + + /** Adds a dependency on the artifact for this module with classifier `c`. */ + def classifier(c: String) = artifacts(Artifact(name, c)) + + /** Declares the explicit artifacts for this module. If this ModuleID represents a dependency, + * these artifact definitions override the information in the dependency's published metadata. */ + def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + + /** Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify + * both the exact organization and name and nothing else will be included in a pom.xml.*/ + def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + + /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ + def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) + + def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead.*/ + def sources() = artifacts(Artifact.sources(name)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead.*/ + def javadoc() = artifacts(Artifact.javadoc(name)) + + def pomOnly() = artifacts(Artifact.pom(name)) + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ + def withSources() = jarIfEmpty.sources() + + /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ + def withJavadoc() = jarIfEmpty.javadoc() + + private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this + + /** Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such + * as when adding a dependency on an artifact with a classifier.*/ + def jar() = artifacts(Artifact(name)) +} +object ModuleID +{ + def checkE(attributes: Seq[(String, String)]) = + for ( (key, value) <- attributes) yield + if(key.startsWith("e:")) (key, value) else ("e:" + key, value) +} diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala new file mode 100644 index 000000000..e315944da --- /dev/null +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -0,0 +1,289 @@ +/* sbt -- Simple Build Tool + * Copyright 2008, 2009, 2010 Mark Harrah + */ +package sbt + +import java.io.File +import java.net.URL +import scala.xml.NodeSeq +import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} + +sealed trait Resolver +{ + def name: String +} +final class RawRepository(val resolver: DependencyResolver) extends Resolver +{ + def name = resolver.getName + override def toString = "Raw(" + resolver.toString + ")" +} +sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver +sealed case class MavenRepository(name: String, root: String) extends Resolver +{ + override def toString = name + ": " + root +} + +final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) +{ + private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) + private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) + override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible) + override def equals(obj: Any): Boolean = { + obj match { + case other: Patterns => + ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible + case _ => false + } + } + override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible).hashCode +} +object Patterns +{ + implicit def defaultPatterns: Patterns = Resolver.defaultPatterns + + def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) + def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) +} +object RepositoryHelpers +{ + final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) + { + def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) + } + /** Configuration specific to an Ivy filesystem resolver. */ + final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) + { + def transactional() = FileConfiguration(isLocal, Some(true)) + def nontransactional() = FileConfiguration(isLocal, Some(false)) + def nonlocal() = FileConfiguration(false, isTransactional) + } + sealed trait SshAuthentication extends NotNull + final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication + final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication +} +import RepositoryHelpers.{SshConnection, FileConfiguration} +import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} + +/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ +sealed abstract class PatternsBasedRepository extends Resolver +{ + type RepositoryType <: PatternsBasedRepository + /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ + protected def copy(patterns: Patterns): RepositoryType + + /** The object representing the configured patterns for this repository. */ + def patterns: Patterns + + /** Enables maven 2 compatibility for this repository. */ + def mavenStyle() = copy(patterns.mavenStyle()) + /** Adds the given patterns for resolving/publishing Ivy files.*/ + def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) + /** Adds the given patterns for resolving/publishing artifacts.*/ + def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) +} +/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ +final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository +{ + type RepositoryType = FileRepository + protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) + private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) + def transactional() = copy(configuration.transactional()) + def nonlocal() = copy(configuration.nonlocal()) +} +final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository +{ + type RepositoryType = URLRepository + protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) +} +/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ +sealed abstract class SshBasedRepository extends PatternsBasedRepository +{ + type RepositoryType <: SshBasedRepository + protected def copy(connection: SshConnection): RepositoryType + private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) + + /** The object representing the configured ssh connection for this repository. */ + def connection: SshConnection + + /** Configures this to use the specified user name and password when connecting to the remote repository. */ + def as(user: String, password: String): RepositoryType = as(user, Some(password)) + def as(user: String): RepositoryType = as(user, None) + def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) + /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ + def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) + def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) + def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) +} +/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ +final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository +{ + type RepositoryType = SshRepository + protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + /** Defines the permissions to set when publishing to this repository. */ + def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) + def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) +} +/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ +final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository +{ + type RepositoryType = SftpRepository + protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) + protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) +} + +import Resolver._ +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") +object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) +@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") +object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) +object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) +object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) +object JavaNet1Repository extends JavaNet1Repository +sealed trait JavaNet1Repository extends Resolver +{ + def name = "java.net Maven1 Repository" +} + +object Resolver +{ + val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" + val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" + val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") + val ScalaToolsReleasesName = "Sonatype OSS Releases" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") + val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") + val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" + @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") + val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" + val JavaNet2RepositoryName = "java.net Maven2 Repository" + val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" + + def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) + def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) + def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) + def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + + /** Add the local and Maven Central repositories to the user repositories. */ + def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = + withDefaultResolvers(userResolvers, true) + /** Add the local Ivy repository to the user repositories. + * If `mavenCentral` is true, add the Maven Central repository. */ + def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = + Seq(Resolver.defaultLocal) ++ + userResolvers ++ + single(DefaultMavenRepository, mavenCentral) + private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if(nonEmpty) Seq(value) else Nil + + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull + { + /** Subclasses should implement this method to */ + protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType + /** Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject + * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, None, None, None) + /** Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, None) + /** Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, Some(basePath)) + /** Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), None) + /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), Some(basePath)) + /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ + def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = + construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) + } + /** A factory to construct an interface to an Ivy SSH resolver.*/ + object ssh extends Define[SshRepository] + { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) + } + /** A factory to construct an interface to an Ivy SFTP resolver.*/ + object sftp extends Define[SftpRepository] + { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) + } + /** A factory to construct an interface to an Ivy filesytem resolver. */ + object file + { + /** Constructs a file resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ + def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = + baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) + } + object url + { + /** Constructs a URL resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ + def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = + baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) + } + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = + construct(resolvePatterns(base, basePatterns)) + + /** If `base` is None, `patterns` is returned unchanged. + * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ + private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = + base match + { + case Some(path) => resolvePatterns(path, patterns) + case None => patterns + } + /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ + private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = + { + def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) + Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) + } + private[sbt] def resolvePattern(base: String, pattern: String): String = + { + val normBase = base.replace('\\', '/') + if(normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern + } + def defaultFileConfiguration = FileConfiguration(true, None) + def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) + def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) + + def defaultPatterns = mavenStylePatterns + def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" + def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" + def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" + final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" + + def mavenLocal = MavenRepository("Maven2 Local", (new File(Path.userHome, ".m2/repository/")).toURI.toURL.toExternalForm) + def defaultLocal = defaultUserFileRepository("local") + def defaultShared = defaultUserFileRepository("shared") + def defaultUserFileRepository(id: String) = + { + val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil + FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) + } + def defaultIvyPatterns = + { + val pList = List(localBasePattern) + Patterns(pList, pList, false) + } +} From 1d70775d7b1ad7b56bad13da7bd72582229a7fd5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 11 Jan 2013 16:01:30 -0500 Subject: [PATCH 0221/1030] Don't try to automatically detect a main artifact when packaging=pom. Fixes #636. For the rare case where a main artifact is expected, add an explicit jar() to the dependency declaration. --- ivy/src/main/scala/sbt/Ivy.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 30b19368f..3ffb8121d 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -242,8 +242,14 @@ private object IvySbt // Technically, this should be applied to module configurations. // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). // It would be better to get proper support into Ivy. - override def locate(artifact: IArtifact) = - if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + // + // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. + // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" + // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly + // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive, so + // sbt now requires this artifact to be explicitly declared. + override def locate(artifact: IArtifact) = null +// if(hasImplicitClassifier(artifact)) null else super.locate(artifact) override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { if(data.getOptions.getLog != LogOptions.LOG_QUIET) From 5523d16a77d15c9d1d1d6134a9d103dd49a5380b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 11 Jan 2013 16:01:31 -0500 Subject: [PATCH 0222/1030] Configurable conflict manager and corresponding documentation on conflictManager, dependencyOverrides, and force(). Fixes #603. --- ivy/src/main/scala/sbt/Ivy.scala | 10 +++++++++- ivy/src/main/scala/sbt/IvyConfigurations.scala | 2 +- ivy/src/main/scala/sbt/IvyInterface.scala | 18 +++++++++++++++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 3ffb8121d..0414cb0c5 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -20,7 +20,6 @@ import core.module.descriptor.{OverrideDependencyDescriptorMediator} import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} import core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} import core.settings.IvySettings -import plugins.conflict.{ConflictManager, LatestCompatibleConflictManager, LatestConflictManager} import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser @@ -140,6 +139,7 @@ final class IvySbt(val configuration: IvyConfiguration) { import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) + IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) @@ -359,6 +359,14 @@ private object IvySbt moduleID.setModuleArtifact(artifact) moduleID.check() } + private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings) + { + val mid = ModuleId.newInstance(conflict.organization, conflict.module) + val matcher = is.getMatcher(PatternMatcher.EXACT_OR_REGEXP) + val manager = is.getConflictManager(conflict.name) + moduleID.addConflictManager(mid, matcher, manager) + } + /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ def toID(m: ModuleID) = { diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index f46d24dbd..256af5f2e 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -74,7 +74,7 @@ final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], valida { def noScala = copy(ivyScala = None) } -final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false) extends ModuleSettings +final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index a1a651e55..2772b98c3 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -10,7 +10,7 @@ import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ -case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) +final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) @@ -19,10 +19,10 @@ case class ModuleInfo(nameFormal: String, description: String = "", homepage: Op } /** Basic SCM information for a project module */ -case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) +final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ -case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) +final case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration @@ -30,3 +30,15 @@ object ModuleConfiguration def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) } + +final case class ConflictManager(name: String, organization: String = "*", module: String = "*") + +/** See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.*/ +object ConflictManager { + val all = ConflictManager("all") + val latestTime = ConflictManager("latest-time") + val latestRevision = ConflictManager("latest-revision") + val latestCompatible = ConflictManager("latest-compatible") + val strict = ConflictManager("strict") + val default = latestRevision +} \ No newline at end of file From 5070104cce87edb427770ccf2985bbd8f58ecc5d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 15 Jan 2013 08:21:53 -0500 Subject: [PATCH 0223/1030] Warn and optionally error when multiple cross version suffixes for a module are detected. Fixes #639. --- ivy/src/main/scala/sbt/ConflictWarning.scala | 64 ++++++++++++++++++-- ivy/src/main/scala/sbt/IvyActions.scala | 1 - 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index f918990e1..8e0b07f7d 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -8,24 +8,80 @@ object ConflictWarning def disable: ConflictWarning = ConflictWarning("", (_: ModuleID) => false, org, Level.Warn, false) private[this] def org = (_: ModuleID).organization + private[this] def idString(org: String, name: String) = s"$org:$name" def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), org, Level.Warn, false) - def strict(label: String): ConflictWarning = ConflictWarning(label, (id: ModuleID) => true, (id: ModuleID) => id.organization + ":" + id.name, Level.Error, true) + def strict(label: String): ConflictWarning = ConflictWarning(label, (id: ModuleID) => true, (id: ModuleID) => idString(id.organization, id.name), Level.Error, true) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) + { + processEvicted(config, report, log) + processCrossVersioned(config, report, log) + } + private[this] def processEvicted(config: ConflictWarning, report: UpdateReport, log: Logger) { val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) if(!conflicts.isEmpty) { val prefix = if(config.failOnConflict) "Incompatible" else "Potentially incompatible" - val msg = prefix + " versions of dependencies of " + config.label + ":\n " + val msg = s"$prefix versions of dependencies of ${config.label}:\n " val conflictMsgs = for( (label, versions) <- conflicts ) yield label + ": " + versions.mkString(", ") log.log(config.level, conflictMsgs.mkString(msg, "\n ", "")) + + if(config.failOnConflict) + error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) } - if(config.failOnConflict && !conflicts.isEmpty) - error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) } + + private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) + { + val crossMismatches = crossVersionMismatches(report) + if(!crossMismatches.isEmpty) + { + val pre = "Modules were resolved with conflicting cross-version suffixes:\n " + val conflictMsgs = + for( ((org,rawName), fullNames) <- crossMismatches ) yield + { + val suffixes = fullNames.map(n => "_" + getCrossSuffix(n)).mkString(", ") + s"${idString(org,rawName)} $suffixes" + } + log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) + if(config.failOnConflict) { + val summary = crossMismatches.map{ case ((org,raw),_) => idString(org,raw)}.mkString(", ") + error("Conflicting cross-version suffixes in: " + summary) + } + } + } + + /** Map from (organization, rawName) to set of multiple full names. */ + def crossVersionMismatches(report: UpdateReport): Map[(String,String), Set[String]] = + { + val mismatches = report.configurations.flatMap { confReport => + groupByRawName(confReport.allModules).mapValues { modules => + val differentFullNames = modules.map(_.name).toSet + if(differentFullNames.size > 1) differentFullNames else Set.empty[String] + } + } + (Map.empty[(String,String),Set[String]] /: mismatches)(merge) + } + private[this] def merge[A,B](m: Map[A, Set[B]], b: (A, Set[B])): Map[A, Set[B]] = + if(b._2.isEmpty) m else + m.updated(b._1, m.getOrElse(b._1, Set.empty) ++ b._2) + + private[this] def groupByRawName(ms: Seq[ModuleID]): Map[(String,String), Seq[ModuleID]] = + ms.groupBy(m => (m.organization, dropCrossSuffix(m.name))) + + private[this] val CrossSuffixPattern = """(.+)_(\d+\.\d+(?:\.\d+)?(?:-.+)?)""".r + private[this] def dropCrossSuffix(s: String): String = s match { + case CrossSuffixPattern(raw, _) => raw + case _ => s + } + private[this] def getCrossSuffix(s: String): String = s match { + case CrossSuffixPattern(_, v) => v + case _ => "" + } + } diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 66a00f615..b139d7989 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -157,7 +157,6 @@ object IvyActions def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = mods groupBy(grouping) mapValues(_.map(_.revision).toSet) - def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = { import config.{configuration => c, ivyScala, module => mod} From 9be353e247eea0c0eb5f079e0ce7431d5b01dc5b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 15 Jan 2013 08:21:53 -0500 Subject: [PATCH 0224/1030] Invalidate artifacts not recorded in the original metadata when a module marked as changing changes. Fixes #637, #641. --- ivy/src/main/scala/sbt/Ivy.scala | 34 +++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 0414cb0c5..9260f3ed1 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -7,6 +7,7 @@ import Resolver.PluginPattern import java.io.File import java.net.URI +import java.text.ParseException import java.util.concurrent.Callable import java.util.{Collection, Collections => CS} import CS.singleton @@ -23,7 +24,9 @@ import core.settings.IvySettings import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser +import plugins.repository.ResourceDownloader import plugins.resolver.{ChainResolver, DependencyResolver} +import plugins.resolver.util.ResolvedResource import util.{Message, MessageLogger} import util.extendable.ExtendableItem @@ -327,17 +330,42 @@ private object IvySbt } } } + /** This is overridden to delete outofdate artifacts of changing modules that are not listed in the metadata. + * This occurs for artifacts with classifiers, for example. */ + @throws(classOf[ParseException]) + override def cacheModuleDescriptor(resolver: DependencyResolver, mdRef: ResolvedResource, dd: DependencyDescriptor, moduleArtifact: IArtifact, downloader: ResourceDownloader, options: CacheMetadataOptions): ResolvedModuleRevision = + { + val rmr = super.cacheModuleDescriptor(resolver, mdRef, dd, moduleArtifact, downloader, options) + val mrid = moduleArtifact.getModuleRevisionId + // only handle changing modules whose metadata actually changed. + // Typically, the publication date in the metadata has to change to get here. + if(rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) { + // this is the locally cached metadata as originally retrieved (e.g. the pom) + val original = rmr.getReport.getOriginalLocalFile + if(original != null) { + // delete all files in subdirectories that are older than the original metadata file + val lm = original.lastModified + val indirectFiles = PathFinder(original.getParentFile).*(DirectoryFilter).**(-DirectoryFilter).get.toList + val older = indirectFiles.filter(f => f.lastModified < lm).toList + Message.verbose("Deleting additional old artifacts from cache for changed module " + mrid + older.mkString(":\n\t", "\n\t", "")) + IO.delete(older) + } + } + rmr + } + def isChanging(dd: DependencyDescriptor, requestedRevisionId: ModuleRevisionId): Boolean = + dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT") } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) manager.setIvyPattern(PluginPattern + manager.getIvyPattern) manager.setUseOrigin(true) if(localOnly) - manager.setDefaultTTL(java.lang.Long.MAX_VALUE); + manager.setDefaultTTL(java.lang.Long.MAX_VALUE) else { - manager.setChangingMatcher(PatternMatcher.REGEXP); - manager.setChangingPattern(".*-SNAPSHOT"); + manager.setChangingMatcher(PatternMatcher.REGEXP) + manager.setChangingPattern(".*-SNAPSHOT") } settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) From b212d80ac67a55a2b0d4b3e1ac742576ccd8a95a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 Jan 2013 10:26:33 -0500 Subject: [PATCH 0225/1030] Ivy Artifact needs wildcard configuration added if no explicit ones are defined. Fixes #439. --- ivy/src/main/scala/sbt/Ivy.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 9260f3ed1..e4e3f26c5 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -420,7 +420,7 @@ private object IvySbt private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - configurations.foreach(artifact.addConfiguration) + copyConfigurations(a, artifact.addConfiguration) artifact } def getExtraAttributes(revID: ExtendableItem): Map[String,String] = @@ -563,6 +563,7 @@ private object IvySbt import artifact.{name, classifier, `type`, extension, url} val extraMap = extra(artifact) val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) + copyConfigurations(artifact, ivyArtifact.addConfiguration) for(conf <- dependencyDescriptor.getModuleConfigurations) dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) } @@ -575,6 +576,11 @@ private object IvySbt } dependencyDescriptor } + def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = + if(artifact.configurations.isEmpty) + addConfiguration("*") + else + artifact.configurations.foreach(c => addConfiguration(c.name)) def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = overrides foreach addOverride(moduleID, matcher) @@ -601,8 +607,9 @@ private object IvySbt /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = - for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) + for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations if c != "*") moduleID.addArtifact(c, art) + def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) From 95ded675b174fbc06d22029343659c60fdf05c87 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 Jan 2013 10:26:33 -0500 Subject: [PATCH 0226/1030] follow-up to invalidating changing artifacts: super.cacheModuleDescriptor can be null --- ivy/src/main/scala/sbt/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index e4e3f26c5..fee28808e 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -339,7 +339,7 @@ private object IvySbt val mrid = moduleArtifact.getModuleRevisionId // only handle changing modules whose metadata actually changed. // Typically, the publication date in the metadata has to change to get here. - if(rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) { + if(rmr != null && rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) { // this is the locally cached metadata as originally retrieved (e.g. the pom) val original = rmr.getReport.getOriginalLocalFile if(original != null) { From 6f1bdc9aa65f28831b070980cdfd2d9f8503c4de Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 16 Jan 2013 10:26:33 -0500 Subject: [PATCH 0227/1030] Only include standard scopes in pom.xml. --- ivy/src/main/scala/sbt/MakePom.scala | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index c92de2aa0..2421c68c4 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -160,8 +160,10 @@ class MakePom(val log: Logger) def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Elem = { - val artifactConfigs = artifact.getConfigurations - val configs = if(artifactConfigs.isEmpty) dependency.getModuleConfigurations else artifactConfigs + val configs = artifact.getConfigurations.toList match { + case Nil | "*" :: Nil => dependency.getModuleConfigurations + case x => x.toArray + } val (scope, optional) = getScopeAndOptional(configs) makeDependencyElem(dependency, scope, optional, artifactClassifier(artifact), artifactType(artifact)) } @@ -222,15 +224,7 @@ class MakePom(val log: Logger) { val (opt, notOptional) = confs.partition(_ == Optional.name) val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) - val scope = defaultNotOptional match - { - case Some(conf) => Some(conf.name) - case None => - if(notOptional.isEmpty || notOptional(0) == Configurations.Default.name) - None - else - Option(notOptional(0)) - } + val scope = defaultNotOptional.map(_.name) (scope, !opt.isEmpty) } From 5d696e5428710a0afef7d885524bec68e656cea2 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Sun, 16 Dec 2012 23:11:41 +0100 Subject: [PATCH 0228/1030] Silence boring Eclipse warnings: @SuppressWarnings("rawtypes") Add @SuppressWarnings("rawtypes") to ResolverAdapter, since it has a comment making pretty clear that using raw types is intended. --- ivy/src/main/java/sbt/ResolverAdapter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/src/main/java/sbt/ResolverAdapter.java b/ivy/src/main/java/sbt/ResolverAdapter.java index 40b1b6268..4247c97e7 100644 --- a/ivy/src/main/java/sbt/ResolverAdapter.java +++ b/ivy/src/main/java/sbt/ResolverAdapter.java @@ -4,6 +4,7 @@ package sbt; import org.apache.ivy.plugins.resolver.DependencyResolver; // implements the methods with raw types +@SuppressWarnings("rawtypes") public abstract class ResolverAdapter implements DependencyResolver { public String[] listTokenValues(String token, Map otherTokenValues) { return new String[0]; } From a2224ba0ff1cbcdd498bc50bcc0e04b0c5879361 Mon Sep 17 00:00:00 2001 From: "Paolo G. Giarrusso" Date: Tue, 8 Jan 2013 00:39:40 +0100 Subject: [PATCH 0229/1030] Silence boring Eclipse warnings: catching all exceptions, part 2 These warning fixes are new since my last pull request, please verify. --- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index b139d7989..f3ac22c82 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -258,7 +258,7 @@ object IvyActions resolver.publish(artifact, file, overwrite) resolver.commitPublishTransaction() } catch { - case e => + case e: Throwable => try { resolver.abortPublishTransaction() } finally { throw e } } From 7f44e0070de6c09a8e9f84b9f620ad13d51e68b4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 23 Jan 2013 22:16:12 -0500 Subject: [PATCH 0230/1030] adds sbtApiVersion and scalaApiVersion sbtApiVersion and scalaApiVersion each calculates the API version of release builds as well as milestones and RCs. scalaBinaryVersion and sbtBinaryVersion are now aware of scalaApiVersion and sbtApiVersion respectively. For example, sbtBinaryVersion for "0.13.0-SNAPSHOT" now evaluates to "0.13.0-SNAPSHOT" instead of "0.13". --- ivy/src/main/scala/sbt/CrossVersion.scala | 45 ++++++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 59b51c795..917f5318f 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -67,9 +67,41 @@ object CrossVersion m } - def isStable(v: String): Boolean = !v.contains("-") + // @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") + def isStable(v: String): Boolean = isScalaApiCompatible(v) + // @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full - + def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + /** Returns sbt binary interface x.y API compatible with the given version string v. + * RCs for x.y.0 are considered API compatible. + * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + */ + def sbtApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + /** Returns Scala binary interface x.y API compatible with the given version string v. + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + */ + def scalaApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r def partialVersion(s: String): Option[(Int,Int)] = s match { @@ -79,12 +111,13 @@ object CrossVersion private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) - def binaryScalaVersion(full: String): String = binaryVersion(full, TransitionScalaVersion) - def binarySbtVersion(full: String): String = binaryVersion(full, TransitionSbtVersion) - def binaryVersion(full: String, cutoff: String): String = + def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = { def sub(major: Int, minor: Int) = major + "." + minor - (partialVersion(full), partialVersion(cutoff)) match { + (apiVersion(full), partialVersion(cutoff)) match { case (Some((major, minor)), None) => sub(major, minor) case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) case _ => full From b677915016f297d776a86094f2ba118c184c7f68 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Jan 2013 10:56:10 -0500 Subject: [PATCH 0231/1030] deprecate binaryVersion --- ivy/src/main/scala/sbt/CrossVersion.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 917f5318f..ed5533a44 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -67,9 +67,9 @@ object CrossVersion m } - // @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") + @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") def isStable(v: String): Boolean = isScalaApiCompatible(v) - // @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined /** Returns sbt binary interface x.y API compatible with the given version string v. @@ -113,6 +113,7 @@ object CrossVersion def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = { From a6e7f4dc8f0fb486996bea60436de187434d09cf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Jan 2013 10:57:17 -0500 Subject: [PATCH 0232/1030] add CrossVersionTest --- ivy/src/test/scala/CrossVersionTest.scala | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 ivy/src/test/scala/CrossVersionTest.scala diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala new file mode 100644 index 000000000..7d0afa1fb --- /dev/null +++ b/ivy/src/test/scala/CrossVersionTest.scala @@ -0,0 +1,93 @@ +package sbt + +import java.io.File +import org.specs2._ +import mutable.Specification + +object CrossVersionTest extends Specification +{ + "Cross version" should { + "return sbt API for xyz as None" in { + CrossVersion.sbtApiVersion("xyz") must_== None + } + "return sbt API for 0.12 as None" in { + CrossVersion.sbtApiVersion("0.12") must_== None + } + "return sbt API for 0.12.0-SNAPSHOT as None" in { + CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") must_== None + } + "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0-RC1") must_== Some((0, 12)) + } + "return sbt API for 0.12.0 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0") must_== Some((0, 12)) + } + "return sbt API for 0.12.1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1") must_== Some((0, 12)) + } + "return sbt API compatibility for 0.12.0-M1 as false" in { + CrossVersion.isSbtApiCompatible("0.12.0-M1") must_== false + } + "return sbt API compatibility for 0.12.0-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.0-RC1") must_== true + } + "return binary sbt version for 0.11.3 as 0.11.3" in { + CrossVersion.binarySbtVersion("0.11.3") must_== "0.11.3" + } + "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { + CrossVersion.binarySbtVersion("0.12.0-M1") must_== "0.12.0-M1" + } + "return binary sbt version for 0.12.0-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0-RC1") must_== "0.12" + } + "return binary sbt version for 0.12.0 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0") must_== "0.12" + } + "return binary sbt version for 0.12.1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1") must_== "0.12" + } + + "return Scala API for xyz as None" in { + CrossVersion.scalaApiVersion("xyz") must_== None + } + "return Scala API for 2.10 as None" in { + CrossVersion.scalaApiVersion("2.10") must_== None + } + "return Scala API for 2.10.0-SNAPSHOT as None" in { + CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") must_== None + } + "return Scala API for 2.10.0-RC1 as None" in { + CrossVersion.scalaApiVersion("2.10.0-RC1") must_== None + } + "return Scala API for 2.10.0 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0") must_== Some((2, 10)) + } + "return Scala API for 2.10.0-1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0-1") must_== Some((2, 10)) + } + "return Scala API for 2.10.1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1") must_== Some((2, 10)) + } + "return Scala API compatibility for 2.10.0-M1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-M1") must_== false + } + "return Scala API compatibility for 2.10.0-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-RC1") must_== false + } + "return binary Scala version for 2.9.2 as 2.9.2" in { + CrossVersion.binaryScalaVersion("2.9.2") must_== "2.9.2" + } + "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { + CrossVersion.binaryScalaVersion("2.10.0-M1") must_== "2.10.0-M1" + } + "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { + CrossVersion.binaryScalaVersion("2.10.0-RC1") must_== "2.10.0-RC1" + } + "return binary Scala version for 2.10.0 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.0") must_== "2.10" + } + "return binary Scala version for 2.10.1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1") must_== "2.10" + } + } +} From 71473e99f2c34cca3e55e75fa574732ff50d2a40 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Jan 2013 11:15:02 -0500 Subject: [PATCH 0233/1030] add more CrossVersionTest --- ivy/src/test/scala/CrossVersionTest.scala | 30 +++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala index 7d0afa1fb..cd89b1358 100644 --- a/ivy/src/test/scala/CrossVersionTest.scala +++ b/ivy/src/test/scala/CrossVersionTest.scala @@ -22,6 +22,12 @@ object CrossVersionTest extends Specification "return sbt API for 0.12.0 as Some((0, 12))" in { CrossVersion.sbtApiVersion("0.12.0") must_== Some((0, 12)) } + "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") must_== Some((0, 12)) + } + "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-RC1") must_== Some((0, 12)) + } "return sbt API for 0.12.1 as Some((0, 12))" in { CrossVersion.sbtApiVersion("0.12.1") must_== Some((0, 12)) } @@ -31,6 +37,9 @@ object CrossVersionTest extends Specification "return sbt API compatibility for 0.12.0-RC1 as true" in { CrossVersion.isSbtApiCompatible("0.12.0-RC1") must_== true } + "return sbt API compatibility for 0.12.1-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.1-RC1") must_== true + } "return binary sbt version for 0.11.3 as 0.11.3" in { CrossVersion.binarySbtVersion("0.11.3") must_== "0.11.3" } @@ -43,6 +52,12 @@ object CrossVersionTest extends Specification "return binary sbt version for 0.12.0 as 0.12" in { CrossVersion.binarySbtVersion("0.12.0") must_== "0.12" } + "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") must_== "0.12" + } + "return binary sbt version for 0.12.1-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-RC1") must_== "0.12" + } "return binary sbt version for 0.12.1 as 0.12" in { CrossVersion.binarySbtVersion("0.12.1") must_== "0.12" } @@ -65,6 +80,12 @@ object CrossVersionTest extends Specification "return Scala API for 2.10.0-1 as Some((2, 10))" in { CrossVersion.scalaApiVersion("2.10.0-1") must_== Some((2, 10)) } + "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") must_== Some((2, 10)) + } + "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-RC1") must_== Some((2, 10)) + } "return Scala API for 2.10.1 as Some((2, 10))" in { CrossVersion.scalaApiVersion("2.10.1") must_== Some((2, 10)) } @@ -74,6 +95,9 @@ object CrossVersionTest extends Specification "return Scala API compatibility for 2.10.0-RC1 as false" in { CrossVersion.isScalaApiCompatible("2.10.0-RC1") must_== false } + "return Scala API compatibility for 2.10.1-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.1-RC1") must_== true + } "return binary Scala version for 2.9.2 as 2.9.2" in { CrossVersion.binaryScalaVersion("2.9.2") must_== "2.9.2" } @@ -86,6 +110,12 @@ object CrossVersionTest extends Specification "return binary Scala version for 2.10.0 as 2.10" in { CrossVersion.binaryScalaVersion("2.10.0") must_== "2.10" } + "return binary Scala version for 2.10.1-M1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-M1") must_== "2.10" + } + "return binary Scala version for 2.10.1-RC1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-RC1") must_== "2.10" + } "return binary Scala version for 2.10.1 as 2.10" in { CrossVersion.binaryScalaVersion("2.10.1") must_== "2.10" } From c763b3c757f328360d099011a47a3956e7277dbd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 26 Jan 2013 20:13:25 -0500 Subject: [PATCH 0234/1030] support binary version in launcher --- ivy/src/main/scala/sbt/CrossVersion.scala | 62 ++++------------- .../main/input_sources/CrossVersionUtil.scala | 69 +++++++++++++++++++ 2 files changed, 83 insertions(+), 48 deletions(-) create mode 100644 util/cross/src/main/input_sources/CrossVersionUtil.scala diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index ed5533a44..6e5df8197 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -1,12 +1,14 @@ package sbt +import cross.CrossVersionUtil + final case class ScalaVersion(full: String, binary: String) sealed trait CrossVersion object CrossVersion { - val TransitionScalaVersion = "2.10" - val TransitionSbtVersion = "0.12" + val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion + val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion object Disabled extends CrossVersion { override def toString = "disabled" } final class Binary(val remapVersion: String => String) extends CrossVersion { @@ -71,58 +73,22 @@ object CrossVersion def isStable(v: String): Boolean = isScalaApiCompatible(v) @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full - def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) /** Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - def sbtApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } - } - def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) + def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) /** Returns Scala binary interface x.y API compatible with the given version string v. * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - def scalaApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } - } - val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r - def partialVersion(s: String): Option[(Int,Int)] = - s match { - case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) - case _ => None - } - private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = - major > minMajor || (major == minMajor && minor >= minMinor) - - def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) - def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) + val PartialVersion = CrossVersionUtil.PartialVersion + def partialVersion(s: String): Option[(Int,Int)] = CrossVersionUtil.partialVersion(s) + def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) + def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) - private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = - { - def sub(major: Int, minor: Int) = major + "." + minor - (apiVersion(full), partialVersion(cutoff)) match { - case (Some((major, minor)), None) => sub(major, minor) - case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) - case _ => full - } - } -} + def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) +} diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/util/cross/src/main/input_sources/CrossVersionUtil.scala new file mode 100644 index 000000000..c22106b2e --- /dev/null +++ b/util/cross/src/main/input_sources/CrossVersionUtil.scala @@ -0,0 +1,69 @@ +package ${{cross.package0}}.${{cross.package1}} + +object CrossVersionUtil +{ + val trueString = "true" + val falseString = "false" + val fullString = "full" + val noneString = "none" + val disabledString = "disabled" + val binaryString = "binary" + val TransitionScalaVersion = "2.10" + val TransitionSbtVersion = "0.12" + + def isFull(s: String): Boolean = (s == trueString) || (s == fullString) + def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) + def isBinary(s: String): Boolean = (s == binaryString) + + private[${{cross.package0}}] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + /** Returns sbt binary interface x.y API compatible with the given version string v. + * RCs for x.y.0 are considered API compatible. + * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + */ + private[${{cross.package0}}] def sbtApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + private[${{cross.package0}}] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + /** Returns Scala binary interface x.y API compatible with the given version string v. + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + */ + private[${{cross.package0}}] def scalaApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + private[${{cross.package0}}] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + private[${{cross.package0}}] def partialVersion(s: String): Option[(Int,Int)] = + s match { + case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) + case _ => None + } + def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + private[${{cross.package0}}] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = + major > minMajor || (major == minMajor && minor >= minMinor) + private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = + { + def sub(major: Int, minor: Int) = major + "." + minor + (apiVersion(full), partialVersion(cutoff)) match { + case (Some((major, minor)), None) => sub(major, minor) + case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) + case _ => full + } + } +} From 9fdbf0537e7ea2bed51667facafa1d35e80de590 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 4 Feb 2013 17:30:31 -0500 Subject: [PATCH 0235/1030] -Xlint --- util/cross/src/main/input_sources/CrossVersionUtil.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/util/cross/src/main/input_sources/CrossVersionUtil.scala index c22106b2e..d192a2f8b 100644 --- a/util/cross/src/main/input_sources/CrossVersionUtil.scala +++ b/util/cross/src/main/input_sources/CrossVersionUtil.scala @@ -49,7 +49,7 @@ object CrossVersionUtil private[${{cross.package0}}] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r private[${{cross.package0}}] def partialVersion(s: String): Option[(Int,Int)] = s match { - case PartialVersion(major, minor) => Some(major.toInt, minor.toInt) + case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) case _ => None } def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) From 4e1aa282b7be72e612b156e0a2da2294570bb9c6 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 19 Feb 2013 14:33:22 -0500 Subject: [PATCH 0236/1030] Use Ivy's default name for the resolution report. Ivy hardcodes the resolution report name in the stylesheet that renders the HTML from the XML report. This means that the links to other configurations are broken when using a custom name. --- ivy/src/main/scala/sbt/ResolutionCache.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala index a5026882b..ab693445d 100644 --- a/ivy/src/main/scala/sbt/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/ResolutionCache.scala @@ -19,8 +19,7 @@ private[sbt] final class ResolutionCache(base: File) extends ResolutionCacheMana val f = IvyPatternHelper.substitute(p, m.getOrganisation, m.getName, m.getBranch, m.getRevision, name, name, ext, null, null, m.getAttributes, null) new File(base, f) } - private[this] def reportBase(resolveId: String): File = - new File(new File(base, ReportDirectory), resolveId) + private[this] val reportBase: File = new File(base, ReportDirectory) def getResolutionCacheRoot: File = base def clean() { IO.delete(base) } @@ -30,10 +29,12 @@ private[sbt] final class ResolutionCache(base: File) extends ResolutionCacheMana resolvedFileInCache(mrid, ResolvedName, "xml") def getResolvedIvyPropertiesInCache(mrid: ModuleRevisionId): File = resolvedFileInCache(mrid, ResolvedName, "properties") + // name needs to be the same as Ivy's default because the ivy-report.xsl stylesheet assumes this + // when making links to reports for other configurations def getConfigurationResolveReportInCache(resolveId: String, conf: String): File = - new File(reportBase(resolveId), "/" + conf + "-" + ResolvedName) + new File(reportBase, resolveId + "-" + conf + ".xml") def getConfigurationResolveReportsInCache(resolveId: String): Array[File] = - IO.listFiles(reportBase(resolveId)).flatMap(d => IO.listFiles(d)) + IO.listFiles(reportBase).filter(_.getName.startsWith(resolveId + "-")) } private[sbt] object ResolutionCache { From 825f9b54b85b878981320f32f0a2e474678d545b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 25 Feb 2013 09:24:04 -0500 Subject: [PATCH 0237/1030] deprecations --- ivy/src/main/scala/sbt/ConflictWarning.scala | 4 ++-- ivy/src/main/scala/sbt/Ivy.scala | 6 +++--- ivy/src/main/scala/sbt/IvyCache.scala | 2 +- ivy/src/main/scala/sbt/MakePom.scala | 2 +- ivy/src/main/scala/sbt/ProjectResolver.scala | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 8e0b07f7d..7498a4f13 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -32,7 +32,7 @@ object ConflictWarning log.log(config.level, conflictMsgs.mkString(msg, "\n ", "")) if(config.failOnConflict) - error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) + sys.error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) } } @@ -51,7 +51,7 @@ object ConflictWarning log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) if(config.failOnConflict) { val summary = crossMismatches.map{ case ((org,raw),_) => idString(org,raw)}.mkString(", ") - error("Conflicting cross-version suffixes in: " + summary) + sys.error("Conflicting cross-version suffixes in: " + summary) } } } diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index fee28808e..68dc273d8 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -478,10 +478,10 @@ private object IvySbt { def check(found: NodeSeq, expected: String, label: String) = if(found.isEmpty) - error("Missing " + label + " in inline Ivy XML.") + sys.error("Missing " + label + " in inline Ivy XML.") else { val str = found.text - if(str != expected) error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") + if(str != expected) sys.error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") } check(info \ "@organisation", module.organization, "organisation") check(info \ "@module", module.name, "name") @@ -637,7 +637,7 @@ private object IvySbt md match { case dmd: DefaultModuleDescriptor => dmd - case _ => error("Unknown ModuleDescriptor type.") + case _ => sys.error("Unknown ModuleDescriptor type.") } def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = configurations match diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala index 1a22a9977..3ff8432f0 100644 --- a/ivy/src/main/scala/sbt/IvyCache.scala +++ b/ivy/src/main/scala/sbt/IvyCache.scala @@ -102,6 +102,6 @@ private class FileDownloader extends ResourceDownloader with NotNull val part = new File(dest.getAbsolutePath + ".part") FileUtil.copy(resource.openStream, part, null) if(!part.renameTo(dest)) - error("Could not move temporary file " + part + " to final location " + dest) + sys.error("Could not move temporary file " + part + " to final location " + dest) } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 2421c68c4..639400db0 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -275,7 +275,7 @@ class MakePom(val log: Logger) def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit - private def checkID(id: String, name: String) = if(id.isEmpty) error("Could not convert '" + name + "' to an ID") else id + private def checkID(id: String, name: String) = if(id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id def mavenRepository(repo: MavenRepository): XNode = mavenRepository(toID(repo.name), repo.name, repo.root) def mavenRepository(id: String, name: String, root: String): XNode = diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index 4c2d046db..a3b31c298 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -22,7 +22,7 @@ package sbt class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) extends ResolverAdapter { def getName = name - def setName(name: String) = error("Setting name not supported by ProjectResolver") + def setName(name: String) = sys.error("Setting name not supported by ProjectResolver") override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = @@ -59,7 +59,7 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] } // doesn't support publishing - def publish(artifact: IArtifact, src: File, overwrite: Boolean) = error("Publish not supported by ProjectResolver") + def publish(artifact: IArtifact, src: File, overwrite: Boolean) = sys.error("Publish not supported by ProjectResolver") def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} def abortPublishTransaction() {} def commitPublishTransaction() {} @@ -77,5 +77,5 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def dumpSettings() {} def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } - def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => error("No settings defined for ProjectResolver") } + def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } } From e87136a352182253d574d9b93fa9b98c831f005f Mon Sep 17 00:00:00 2001 From: "Brendan W. McAdams" Date: Thu, 28 Feb 2013 14:11:07 -0800 Subject: [PATCH 0238/1030] Resolves #645: Added 'xml:space="preserve"' attribute to extraDependencyAttributes XML Block * This will keep PrettyPrinter from clobbering and breaking pom files for plugins dependent on other plugins --- ivy/src/main/scala/sbt/MakePom.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 639400db0..cbfb0a5a1 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -10,7 +10,7 @@ package sbt import java.io.File // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation -import scala.xml.{Elem, Node => XNode, NodeSeq, PrettyPrinter} +import scala.xml.{Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute} import Configurations.Optional import org.apache.ivy.{core, plugins, Ivy} @@ -105,11 +105,20 @@ class MakePom(val log: Logger) val allExtra = if(depExtra.isEmpty) extra else extra.updated(CustomPomParser.ExtraAttributesKey, depExtra) if(allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) } - def makeProperties(extra: Map[String,String]): NodeSeq = + def makeProperties(extra: Map[String,String]): NodeSeq = { + def _extraAttributes(k: String) = if (k == CustomPomParser.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null { for( (key,value) <- extra ) yield - ({value}).copy(label = key) + ({value}).copy(label = key, attributes = _extraAttributes(key)) } + } + + /** + * Attribute tag that PrettyPrinter won't ignore, saying "don't mess with my spaces" + * Without this, PrettyPrinter will flatten multiple entries for ExtraDependencyAttributes and make them + * unparseable. (e.g. a plugin that depends on multiple plugins will fail) + */ + def xmlSpacePreserve = new PrefixedAttribute("xml", "space", "preserve", scala.xml.Null) def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else {d} def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else {ls.map(license)} From 03dd25c15e1adab2c1d0686b16f772570695af2a Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 8 Mar 2013 14:23:31 -0500 Subject: [PATCH 0239/1030] ivy cache: ignore the original resolver in more places. Fixes #704 --- ivy/src/main/scala/sbt/Ivy.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 68dc273d8..9a0fd6559 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -14,7 +14,7 @@ import CS.singleton import org.apache.ivy.{core, plugins, util, Ivy} import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager} +import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter} import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} import core.module.descriptor.{OverrideDependencyDescriptorMediator} @@ -335,7 +335,7 @@ private object IvySbt @throws(classOf[ParseException]) override def cacheModuleDescriptor(resolver: DependencyResolver, mdRef: ResolvedResource, dd: DependencyDescriptor, moduleArtifact: IArtifact, downloader: ResourceDownloader, options: CacheMetadataOptions): ResolvedModuleRevision = { - val rmr = super.cacheModuleDescriptor(resolver, mdRef, dd, moduleArtifact, downloader, options) + val rmr = super.cacheModuleDescriptor(null, mdRef, dd, moduleArtifact, downloader, options) val mrid = moduleArtifact.getModuleRevisionId // only handle changing modules whose metadata actually changed. // Typically, the publication date in the metadata has to change to get here. @@ -353,6 +353,9 @@ private object IvySbt } rmr } + // ignore the original resolver wherever possible to avoid issues like #704 + override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} + def isChanging(dd: DependencyDescriptor, requestedRevisionId: ModuleRevisionId): Boolean = dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT") } From 364e469947d0c4977173a1f613c336884b3f8f5c Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 8 Mar 2013 20:11:53 -0500 Subject: [PATCH 0240/1030] Publish test artifacts in Test configuration and corrects classifier to 'tests'. Fixes #683 --- ivy/src/main/scala/sbt/Artifact.scala | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/ivy/src/main/scala/sbt/Artifact.scala index 987a1f8ca..5bd17ef0d 100644 --- a/ivy/src/main/scala/sbt/Artifact.scala +++ b/ivy/src/main/scala/sbt/Artifact.scala @@ -11,7 +11,7 @@ final case class Artifact(name: String, `type`: String, extension: String, class def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) } - import Configurations.{config, Docs, Optional, Pom, Sources} + import Configurations.{config, Docs, Optional, Pom, Sources, Test} object Artifact { @@ -36,6 +36,7 @@ object Artifact val DocType = "doc" val SourceType = "src" val PomType = "pom" + val TestsClassifier = "tests" def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = @@ -64,8 +65,12 @@ object Artifact val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - def classifierConf(classifier: String): Configuration = classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix("test-"), DefaultType) + def classifierConf(classifier: String): Configuration = + if(classifier.startsWith(TestsClassifier)) + Test + else + classifierConfMap.getOrElse(classifier, Optional) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) } From 55b986e6eca3c898c3c7aa5337c8478423af75ed Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 14 Mar 2013 16:17:12 -0400 Subject: [PATCH 0241/1030] Remove the conflict warnings based on the evicted modules. Ref #709. This aspect is better served by a standard Ivy conflict manager. --- ivy/src/main/scala/sbt/ConflictWarning.scala | 41 ++++++++------------ 1 file changed, 17 insertions(+), 24 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 7498a4f13..b5ccd1967 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -2,46 +2,39 @@ package sbt import DependencyFilter._ -final case class ConflictWarning(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean) +final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) +{ + @deprecated("`filter` is no longer used", "0.13.0") + val filter: ModuleFilter = (_: ModuleID) => false + @deprecated("`group` is no longer used", "0.13.0") + val group: ModuleID => String = ConflictWarning.org +} object ConflictWarning { - def disable: ConflictWarning = ConflictWarning("", (_: ModuleID) => false, org, Level.Warn, false) + @deprecated("`group` and `filter` are no longer used. Use a standard Ivy conflict manager.", "0.13.0") + def apply(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean): ConflictWarning = + ConflictWarning(label, level, failOnConflict) - private[this] def org = (_: ModuleID).organization + def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) + + private def org = (_: ModuleID).organization private[this] def idString(org: String, name: String) = s"$org:$name" - def default(label: String): ConflictWarning = ConflictWarning(label, moduleFilter(organization = GlobFilter(SbtArtifacts.Organization) | GlobFilter(ScalaArtifacts.Organization)), org, Level.Warn, false) + def default(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - def strict(label: String): ConflictWarning = ConflictWarning(label, (id: ModuleID) => true, (id: ModuleID) => idString(id.organization, id.name), Level.Error, true) + @deprecated("Warning on evicted modules is no longer done, so this is the same as `default`. Use a standard Ivy conflict manager.", "0.13.0") + def strict(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { - processEvicted(config, report, log) processCrossVersioned(config, report, log) } - private[this] def processEvicted(config: ConflictWarning, report: UpdateReport, log: Logger) - { - val conflicts = IvyActions.groupedConflicts(config.filter, config.group)(report) - if(!conflicts.isEmpty) - { - val prefix = if(config.failOnConflict) "Incompatible" else "Potentially incompatible" - val msg = s"$prefix versions of dependencies of ${config.label}:\n " - val conflictMsgs = - for( (label, versions) <- conflicts ) yield - label + ": " + versions.mkString(", ") - log.log(config.level, conflictMsgs.mkString(msg, "\n ", "")) - - if(config.failOnConflict) - sys.error("Conflicts in " + conflicts.map(_._1).mkString(", ") ) - } - } - private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) { val crossMismatches = crossVersionMismatches(report) if(!crossMismatches.isEmpty) { - val pre = "Modules were resolved with conflicting cross-version suffixes:\n " + val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " val conflictMsgs = for( ((org,rawName), fullNames) <- crossMismatches ) yield { From f728912f12badef53570fbaab82acb0e3575fb68 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 18 Mar 2013 09:52:57 -0400 Subject: [PATCH 0242/1030] use separate ivy home directories in component provider test so tests can run concurrently --- ivy/src/test/scala/ComponentManagerTest.scala | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index a9bbe051f..db3f676cc 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -50,16 +50,18 @@ object ComponentManagerTest extends Specification } "properly cache a file and then retrieve it to an unresolved component" in { - withManager { definingManager => - val hash = defineFile(definingManager, TestID, "a") - try - { - definingManager.cache(TestID) - withManager { usingManager => - checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) + withTemporaryDirectory { ivyHome => + withManagerHome(ivyHome) { definingManager => + val hash = defineFile(definingManager, TestID, "a") + try + { + definingManager.cache(TestID) + withManagerHome(ivyHome) { usingManager => + checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) + } } + finally { definingManager.clearCache(TestID) } } - finally { definingManager.clearCache(TestID) } } } } @@ -78,5 +80,13 @@ object ComponentManagerTest extends Specification private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - TestLogger( logger => withTemporaryDirectory { temp => f(new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), None, logger)) } ) + withTemporaryDirectory { ivyHome => withManagerHome(ivyHome)(f) } + + private def withManagerHome[T](ivyHome: File)(f: ComponentManager => T): T = + TestLogger { logger => + withTemporaryDirectory { temp => + val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + f(mgr) + } + } } From bd134f1f2722d342c4b2bf56997830c9ca7784dd Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Mar 2013 09:17:53 -0400 Subject: [PATCH 0243/1030] add publish-m2 task for publishing to ~/.m2/repository. Fixes #485. --- ivy/src/main/scala/sbt/Resolver.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index e315944da..82aea65d4 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -273,7 +273,9 @@ object Resolver def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - def mavenLocal = MavenRepository("Maven2 Local", (new File(Path.userHome, ".m2/repository/")).toURI.toURL.toExternalForm) + private[this] def mavenLocalDir = new File(Path.userHome, ".m2/repository/") + def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) + def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = From ea48770534ec04b8afd503673906a65561ce5d4b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 27 Mar 2013 09:17:54 -0400 Subject: [PATCH 0244/1030] Correct data constructor for CrossVersion.binaryMapping. Fixes #716. --- ivy/src/main/scala/sbt/CrossVersion.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 6e5df8197..9a984c5c5 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -22,7 +22,7 @@ object CrossVersion def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) def binary: CrossVersion = new Binary(idFun) - def binaryMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) private[this] def idFun[T]: T => T = x => x def append(s: String): Option[String => String] = Some(x => crossName(x, s)) From 7bda0fad1719e5c4b7f68d954dcd1f3b5d80fe40 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 10 Apr 2013 20:15:28 -0400 Subject: [PATCH 0245/1030] Better auto-generated IDs for default projects. Fixes #554. For the global plugins project, the default ID is "global-plugins". For a normal project, the default ID is the name of the build directory. The ID of a build definition for one of the above appends -build. --- ivy/src/main/scala/sbt/StringUtilities.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala index 3a0075bb4..17f6e75a9 100644 --- a/ivy/src/main/scala/sbt/StringUtilities.scala +++ b/ivy/src/main/scala/sbt/StringUtilities.scala @@ -5,7 +5,7 @@ package sbt object StringUtilities { - def normalize(s: String) = s.toLowerCase.replaceAll("""\s+""", "-") + def normalize(s: String) = s.toLowerCase.replaceAll("""\W+""", "-") def nonEmpty(s: String, label: String) { require(s.trim.length > 0, label + " cannot be empty.") From 48f9ff2ec38e7bb4ba4909297ed66d5622496d88 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 5 May 2013 15:42:15 -0400 Subject: [PATCH 0246/1030] account for localOnly when cache subclass overrides isChanging --- ivy/src/main/scala/sbt/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 9a0fd6559..ed1468cb6 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -357,7 +357,7 @@ private object IvySbt override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} def isChanging(dd: DependencyDescriptor, requestedRevisionId: ModuleRevisionId): Boolean = - dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT") + !localOnly && (dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT")) } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) From cee19a157ee6636c4d2a6f39546731ee50a684f0 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 5 May 2013 15:42:15 -0400 Subject: [PATCH 0247/1030] Fix for cache issues when developing sbt itself. Ivy still seems to remember the resolver that found the metadata and records that as the resolver to use for the artifact. Previous fixes have attempted to ignore or blank this resolver. The issue this fix addresses comes from inter-project not being ignored/blanked. inter-project can't provide artifacts because it is only for projects in the current build under development and not for modules in a repository. The symptom is that compiling a build definition fails because the sbt jars aren't on the classpath, but it is ultimately due to the inter-project resolver incorrectly being used to resolve artifacts. --- ivy/src/main/scala/sbt/Ivy.scala | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index ed1468cb6..c99efc821 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -257,7 +257,8 @@ private object IvySbt { if(data.getOptions.getLog != LogOptions.LOG_QUIET) Message.info("Resolving " + dd.getDependencyRevisionId + " ...") - super.getDependency(dd, data) + val gd = super.getDependency(dd, data) + resetArtifactResolver(gd) } } newDefault.setName(name) @@ -308,13 +309,24 @@ private object IvySbt val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir settings.setResolutionCacheManager(new ResolutionCache(base)) } - private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) + // set the artifact resolver to be the main resolver. + // this is because sometimes the artifact resolver saved in the cache is not correct + // the common case is for resolved.getArtifactResolver to be inter-project from a different project's publish-local + // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver + // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver + private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = + if(resolved eq null) + null + else + new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, resolved.getDescriptor, resolved.getReport, resolved.isForce) + + private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) //, artifactResolver: DependencyResolver) { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { - // ignore the resolver- not ideal, but avoids thrashing. - val resolved = super.findModuleInCache(dd,revId,options,null) + // ignore and reset the resolver- not ideal, but avoids thrashing. + val resolved = resetArtifactResolver(super.findModuleInCache(dd,revId,options,null)) // invalidate the cache if the artifact was removed from the local repository if(resolved == null) null else { @@ -335,7 +347,8 @@ private object IvySbt @throws(classOf[ParseException]) override def cacheModuleDescriptor(resolver: DependencyResolver, mdRef: ResolvedResource, dd: DependencyDescriptor, moduleArtifact: IArtifact, downloader: ResourceDownloader, options: CacheMetadataOptions): ResolvedModuleRevision = { - val rmr = super.cacheModuleDescriptor(null, mdRef, dd, moduleArtifact, downloader, options) + val rmrRaw = super.cacheModuleDescriptor(null, mdRef, dd, moduleArtifact, downloader, options) + val rmr = resetArtifactResolver(rmrRaw) val mrid = moduleArtifact.getModuleRevisionId // only handle changing modules whose metadata actually changed. // Typically, the publication date in the metadata has to change to get here. From 7cdb83693f54b029976a76da9bb0dfd8f7718873 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 28 May 2013 11:08:49 -0400 Subject: [PATCH 0248/1030] Use publication date from metadata instead of original file's last modified time. Fixes #764. --- ivy/src/main/scala/sbt/Ivy.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index c99efc821..a938087fd 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -356,8 +356,11 @@ private object IvySbt // this is the locally cached metadata as originally retrieved (e.g. the pom) val original = rmr.getReport.getOriginalLocalFile if(original != null) { - // delete all files in subdirectories that are older than the original metadata file - val lm = original.lastModified + // delete all files in subdirectories that are older than the original metadata file's publication date + // The publication date is used because the metadata will be redownloaded for changing files, + // so the last modified time changes, but the publication date doesn't + val pubDate = rmrRaw.getPublicationDate + val lm = if(pubDate eq null) original.lastModified else pubDate.getTime val indirectFiles = PathFinder(original.getParentFile).*(DirectoryFilter).**(-DirectoryFilter).get.toList val older = indirectFiles.filter(f => f.lastModified < lm).toList Message.verbose("Deleting additional old artifacts from cache for changed module " + mrid + older.mkString(":\n\t", "\n\t", "")) From 64257e427ce2e32e34c99171f5acbfd6e49efbb8 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 28 May 2013 15:08:11 -0400 Subject: [PATCH 0249/1030] Test case and comment fixes #760. The actual fix was introduced in 6d5d641dd718e2cf718d130e8571792cd7a9d84e. --- ivy/src/main/scala/sbt/Ivy.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index a938087fd..5d30520da 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -314,6 +314,7 @@ private object IvySbt // the common case is for resolved.getArtifactResolver to be inter-project from a different project's publish-local // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver + // This also fixes #760, which occurs when metadata exists in a repository, but the artifact doesn't. private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = if(resolved eq null) null From 0051af6a481b4c872d9ff3095e0395ef0389015f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sat, 1 Jun 2013 10:56:30 -0400 Subject: [PATCH 0250/1030] additional docs on ModuleID.extra --- ivy/src/main/scala/sbt/ModuleID.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index df69274d4..e37c84da2 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -64,6 +64,8 @@ final case class ModuleID(organization: String, name: String, revision: String, /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) + /** Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. + * This information will only be published in an ivy.xml and not in a pom.xml. */ def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred @@ -96,6 +98,7 @@ final case class ModuleID(organization: String, name: String, revision: String, } object ModuleID { + /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = for ( (key, value) <- attributes) yield if(key.startsWith("e:")) (key, value) else ("e:" + key, value) From d7e85f58779302dba3d676789dd762d9784aff48 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 3 Jun 2013 22:49:48 -0400 Subject: [PATCH 0251/1030] ProjectResolver should throw an exception when called to retrieve dependency. As suggested by @ezh, ref #770. --- ivy/src/main/scala/sbt/ProjectResolver.scala | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index a3b31c298..917889db8 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -26,11 +26,12 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = + getDependency(dd.getDependencyRevisionId).orNull + + private[this] def getDependency(revisionId: ModuleRevisionId): Option[ResolvedModuleRevision] = { - val revisionId = dd.getDependencyRevisionId def constructResult(descriptor: ModuleDescriptor) = new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) - val dep = (map get revisionId map constructResult).orNull - dep + map get revisionId map constructResult } def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = @@ -46,7 +47,14 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def exists(artifact: IArtifact) = false def locate(artifact: IArtifact) = null def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = - new DownloadReport + { + val r = new DownloadReport + for(artifact <- artifacts) + if(getDependency(artifact.getModuleRevisionId).isEmpty) + r.addArtifactReport(notDownloaded(artifact)) + r + } + def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = notDownloaded(artifact.getArtifact) def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null From 7440613ec20e2431abe5a7a9585b2066fd5305fc Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Tue, 4 Jun 2013 10:33:23 -0400 Subject: [PATCH 0252/1030] Fix regression in 0.12.3 where artifacts without an explicit configuration wouldn't be listed in ivy.xml. --- ivy/src/main/scala/sbt/Ivy.scala | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 5d30520da..9637c232f 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -437,10 +437,10 @@ private object IvySbt } } - private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, configurations: Iterable[String]): MDArtifact = + private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, allConfigurations: Iterable[String]): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - copyConfigurations(a, artifact.addConfiguration) + copyConfigurations(a, artifact.addConfiguration, allConfigurations) artifact } def getExtraAttributes(revID: ExtendableItem): Map[String,String] = @@ -597,10 +597,13 @@ private object IvySbt dependencyDescriptor } def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = - if(artifact.configurations.isEmpty) - addConfiguration("*") - else - artifact.configurations.foreach(c => addConfiguration(c.name)) + copyConfigurations(artifact, addConfiguration, "*" :: Nil) + + private[this] def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit, allConfigurations: Iterable[String]): Unit = + { + val confs = if(artifact.configurations.isEmpty) allConfigurations else artifact.configurations.map(_.name) + confs foreach addConfiguration + } def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = overrides foreach addOverride(moduleID, matcher) @@ -627,7 +630,7 @@ private object IvySbt /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = - for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations if c != "*") + for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) moduleID.addArtifact(c, art) def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = @@ -637,17 +640,7 @@ private object IvySbt { lazy val allConfigurations = moduleID.getPublicConfigurationsNames for(artifact <- artifacts) yield - { - val configurationStrings: Iterable[String] = - { - val artifactConfigurations = artifact.configurations - if(artifactConfigurations.isEmpty) - allConfigurations - else - artifactConfigurations.map(_.name) - } - toIvyArtifact(moduleID, artifact, configurationStrings) - } + toIvyArtifact(moduleID, artifact, allConfigurations) } From 64dc140e487deee3d8c631b36ac658fbb75ce83b Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 5 Jun 2013 19:55:24 -0400 Subject: [PATCH 0253/1030] Invalidate cache when metadata came from ProjectResolver. Based on the core idea in #770 by @ezh. Fixes #768, closes #770, fixes #773. --- ivy/src/main/scala/sbt/Ivy.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 9637c232f..0a162b2b4 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -330,7 +330,10 @@ private object IvySbt val resolved = resetArtifactResolver(super.findModuleInCache(dd,revId,options,null)) // invalidate the cache if the artifact was removed from the local repository if(resolved == null) null - else { + else if(isProjectResolver(resolved.getResolver)) { + resolved.getReport.getLocalFile.delete() + null + } else { val origin = resolved.getReport.getArtifactOrigin if(!origin.isLocal) resolved else { @@ -343,6 +346,10 @@ private object IvySbt } } } + private[this] def isProjectResolver(r: DependencyResolver): Boolean = r match { + case pr: ProjectResolver => true + case _ => false + } /** This is overridden to delete outofdate artifacts of changing modules that are not listed in the metadata. * This occurs for artifacts with classifiers, for example. */ @throws(classOf[ParseException]) @@ -351,9 +358,12 @@ private object IvySbt val rmrRaw = super.cacheModuleDescriptor(null, mdRef, dd, moduleArtifact, downloader, options) val rmr = resetArtifactResolver(rmrRaw) val mrid = moduleArtifact.getModuleRevisionId + def shouldClear(): Boolean = rmr != null && + ( (rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) || + isProjectResolver(rmr.getResolver) ) // only handle changing modules whose metadata actually changed. // Typically, the publication date in the metadata has to change to get here. - if(rmr != null && rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) { + if(shouldClear()) { // this is the locally cached metadata as originally retrieved (e.g. the pom) val original = rmr.getReport.getOriginalLocalFile if(original != null) { From 141d608ed73ec09a6021b581b4a0605aecca321e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 19 Jun 2013 17:13:32 -0400 Subject: [PATCH 0254/1030] Move deprecated scala-tools conveniences to private[sbt] accessibility --- ivy/src/main/scala/sbt/Resolver.scala | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 82aea65d4..fb122d0bc 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -135,10 +135,7 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern } import Resolver._ -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") -object ScalaToolsReleases extends MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) -@deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") -object ScalaToolsSnapshots extends MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) + object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JavaNet1Repository extends JavaNet1Repository @@ -152,14 +149,15 @@ object Resolver val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesName = "Sonatype OSS Releases" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" - @deprecated("Maven repository at scala-tools.org is being phased out, consider using an alternative resolver", "0.11.3") - val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" + + // obsolete: kept only for launcher compatibility + private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" + private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" + private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" + private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" + private[sbt] val ScalaToolsReleases = new MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) + private[sbt] val ScalaToolsSnapshots = new MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) + val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" From c924862d1c9f0801374adea9b9cfad1e1826c301 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Sun, 23 Jun 2013 19:57:30 -0400 Subject: [PATCH 0255/1030] Better auto project ID handling. Ref #776. * Consolidate project ID validation and normalization into Project methods * Provide an earlier and more detailed error message when the directory name can't be used for the project ID --- ivy/src/main/scala/sbt/StringUtilities.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala index 17f6e75a9..b86427449 100644 --- a/ivy/src/main/scala/sbt/StringUtilities.scala +++ b/ivy/src/main/scala/sbt/StringUtilities.scala @@ -5,6 +5,7 @@ package sbt object StringUtilities { + @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") def normalize(s: String) = s.toLowerCase.replaceAll("""\W+""", "-") def nonEmpty(s: String, label: String) { From c2724510e58c366010869c0e89458d8446cefe04 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 11 Jul 2013 18:49:30 -0400 Subject: [PATCH 0256/1030] clean up some ConvertResolver parameter lists --- ivy/src/main/scala/sbt/ConvertResolver.scala | 16 ++++++++-------- ivy/src/main/scala/sbt/Ivy.scala | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 293963a2d..5d3c6836e 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -15,7 +15,7 @@ import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver private object ConvertResolver { /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver)(implicit settings: IvySettings, log: Logger) = + def apply(r: Resolver, settings: IvySettings, log: Logger) = { r match { @@ -45,21 +45,21 @@ private object ConvertResolver case repo: SshRepository => { val resolver = new SshResolver with DescriptorRequired - initializeSSHResolver(resolver, repo) + initializeSSHResolver(resolver, repo, settings) repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) resolver } case repo: SftpRepository => { val resolver = new SFTPResolver - initializeSSHResolver(resolver, repo) + initializeSSHResolver(resolver, repo, settings) resolver } case repo: FileRepository => { val resolver = new FileSystemResolver with DescriptorRequired resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns) + initializePatterns(resolver, repo.patterns, settings) import repo.configuration.{isLocal, isTransactional} resolver.setLocal(isLocal) isTransactional.foreach(value => resolver.setTransactional(value.toString)) @@ -69,7 +69,7 @@ private object ConvertResolver { val resolver = new URLResolver with DescriptorRequired resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns) + initializePatterns(resolver, repo.patterns, settings) resolver } case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) @@ -95,11 +95,11 @@ private object ConvertResolver resolver.setM2compatible(true) resolver.setRoot(root) } - private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository)(implicit settings: IvySettings) + private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings) { resolver.setName(repo.name) resolver.setPassfile(null) - initializePatterns(resolver, repo.patterns) + initializePatterns(resolver, repo.patterns, settings) initializeConnection(resolver, repo.connection) } private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection) @@ -119,7 +119,7 @@ private object ConvertResolver setUser(user) } } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns)(implicit settings: IvySettings) + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings) { resolver.setM2compatible(patterns.isMavenCompatible) patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 0a162b2b4..7b253408a 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -266,7 +266,7 @@ private object IvySbt newDefault.setCheckmodified(false) for(sbtResolver <- resolvers) { log.debug("\t" + sbtResolver) - newDefault.add(ConvertResolver(sbtResolver)(settings, log)) + newDefault.add(ConvertResolver(sbtResolver, settings, log)) } newDefault } @@ -274,7 +274,7 @@ private object IvySbt { for(r <- resolvers) { log.debug("\t" + r) - settings.addResolver(ConvertResolver(r)(settings, log)) + settings.addResolver(ConvertResolver(r, settings, log)) } } /** A hack to detect if the given artifact is an automatically generated request for a classifier, @@ -294,7 +294,7 @@ private object IvySbt import IvyPatternHelper._ import PatternMatcher._ if(!existing.contains(resolver.name)) - settings.addResolver(ConvertResolver(resolver)(settings, log)) + settings.addResolver(ConvertResolver(resolver, settings, log)) val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } From ae0b9457b2d9ca9d3116c09dc695c263c987ece4 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 11 Jul 2013 18:49:30 -0400 Subject: [PATCH 0257/1030] Revert packaging='pom' behavior change introduced in c5823ad1e7b6ad9d2b79. Fixes #810. Ref #636. --- ivy/src/main/scala/sbt/Ivy.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 7b253408a..852103195 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -245,14 +245,17 @@ private object IvySbt // Technically, this should be applied to module configurations. // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). // It would be better to get proper support into Ivy. + // A workaround is to configure the ModuleConfiguration resolver to be a ChainResolver. // // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly - // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive, so - // sbt now requires this artifact to be explicitly declared. - override def locate(artifact: IArtifact) = null -// if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive. + // + // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the + // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. + override def locate(artifact: IArtifact) = if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { if(data.getOptions.getLog != LogOptions.LOG_QUIET) From a76f59c57580653fab9ac987bfd938a11792c595 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 7 Aug 2013 18:24:19 -0400 Subject: [PATCH 0258/1030] Use repo.scala-sbt.org everywhere to be more independent of hosting details. --- ivy/src/main/scala/sbt/Resolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index fb122d0bc..5eefa51c8 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -147,7 +147,7 @@ sealed trait JavaNet1Repository extends Resolver object Resolver { val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" - val SbtPluginRepositoryRoot = "http://scalasbt.artifactoryonline.com/scalasbt" + val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" // obsolete: kept only for launcher compatibility From 8463792b995a37c73386762a2cf3a37ca0c038db Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 16 Aug 2013 14:21:44 -0400 Subject: [PATCH 0259/1030] API docs for CrossVersion --- ivy/src/main/scala/sbt/CrossVersion.scala | 58 ++++++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 9a984c5c5..3425bb1f5 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -4,29 +4,56 @@ import cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) +/** Configures how a module will be cross-versioned. */ sealed trait CrossVersion + object CrossVersion { + /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion + + /** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */ val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion + /** Disables cross versioning for a module.*/ object Disabled extends CrossVersion { override def toString = "disabled" } + + /** Cross-versions a module using the result of applying `remapVersion` to the binary version. + * For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10", + * the module is cross-versioned with "2.10". */ final class Binary(val remapVersion: String => String) extends CrossVersion { override def toString = "Binary" } + + /** Cross-versions a module with the result of applying `remapVersion` to the full version. + * For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3", + * the module is cross-versioned with "2.10". */ final class Full(val remapVersion: String => String) extends CrossVersion { override def toString = "Full" } + /** Cross-versions a module with the full version (typically the full Scala version). */ def full: CrossVersion = new Full(idFun) + + /** Cross-versions a module with the result of applying `remapVersion` to the full version + * (typically the full Scala version). See also [[sbt.CrossVersion.Full]]. */ def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = new Binary(idFun) + + /** Cross-versions a module with the result of applying `remapVersion` to the binary version + * (typically the binary Scala version). See also [[sbt.CrossVersion.Binary]]. */ def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) private[this] def idFun[T]: T => T = x => x + + @deprecated("Will be made private.", "0.13.1") def append(s: String): Option[String => String] = Some(x => crossName(x, s)) + /** Construct a cross-versioning function given cross-versioning configuration `cross`, + * full version `fullVersion` and binary version `binaryVersion`. The behavior of the + * constructed function is as documented for the [[sbt.CrossVersion]] datatypes. */ def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { @@ -35,31 +62,43 @@ object CrossVersion case f: Full => append(f.remapVersion(fullVersion)) } + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: IvyScala): Option[String => String] = CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = is flatMap { i => apply(module, i) } + /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = cross match { case None => artifacts case Some(is) => substituteCrossA(artifacts, cross) } + @deprecated("Will be made private.", "0.13.1") def applyCross(s: String, fopt: Option[String => String]): String = fopt match { case None => s case Some(fopt) => fopt(s) } + @deprecated("Will be made private.", "0.13.1") def crossName(name: String, cross: String): String = name + "_" + cross + + /** Cross-versions `a` according to cross-version function `cross`. */ def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = a.copy(name = applyCross(a.name, cross)) + + @deprecated("Will be made private.", "0.13.1") def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = as.map(art => substituteCross(art, cross)) + /** Constructs a function that will cross-version a ModuleID + * for the given full and binary Scala versions `scalaFullVersion` and `scalaBinaryVersion` + * according to the ModuleID's cross-versioning setting. */ def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => { val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) @@ -71,23 +110,38 @@ object CrossVersion @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") def isStable(v: String): Boolean = isScalaApiCompatible(v) + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full + def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) + /** Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) + def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) + /** Returns Scala binary interface x.y API compatible with the given version string v. - * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. - */ + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) + + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ val PartialVersion = CrossVersionUtil.PartialVersion + + /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ def partialVersion(s: String): Option[(Int,Int)] = CrossVersionUtil.partialVersion(s) + + /** Computes the binary Scala version from the `full` version. + * Full Scala versions earlier than [[sbt.CrossVersion.TransitionScalaVersion]] are returned as is. */ def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) + + /** Computes the binary sbt version from the `full` version. + * Full sbt versions earlier than [[sbt.CrossVersion.TransitionSbtVersion]] are returned as is. */ def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) From 298292c8c55960e3db2b5574131e5366927d6a7c Mon Sep 17 00:00:00 2001 From: William Benton Date: Tue, 13 Aug 2013 16:10:59 -0500 Subject: [PATCH 0260/1030] Additional options for Ivy resolvers. Specify an Ivy resolver with ", descriptorOptional" to make Ivy descriptor files optional for that repository or with ", skipConsistencyCheck" to disable Ivy consistency checks for that repository. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 3 +++ ivy/src/main/scala/sbt/Resolver.scala | 13 ++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 5d3c6836e..91fa137a2 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -76,6 +76,7 @@ private object ConvertResolver case repo: RawRepository => repo.resolver } } + private sealed trait DescriptorRequired extends BasicResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = @@ -122,6 +123,8 @@ private object ConvertResolver private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings) { resolver.setM2compatible(patterns.isMavenCompatible) + resolver.setDescriptor(if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED) + resolver.setCheckconsistency(!patterns.skipConsistencyCheck) patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) } diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 5eefa51c8..fb7daa210 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -23,20 +23,23 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver override def toString = name + ": " + root } -final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean) +final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) - override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible) + override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) override def equals(obj: Any): Boolean = { obj match { case other: Patterns => - ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible + ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible && descriptorOptional == other.descriptorOptional && skipConsistencyCheck == other.skipConsistencyCheck case _ => false } } - override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible).hashCode + override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode + + @deprecated + def this(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) = this(ivyPatterns, artifactPatterns, isMavenCompatible, false, false) } object Patterns { @@ -44,7 +47,7 @@ object Patterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean = false, skipConsistencyCheck: Boolean = false): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } object RepositoryHelpers { From ba7f3db5a0f1de6b9c1677a073d5cca731730f43 Mon Sep 17 00:00:00 2001 From: William Benton Date: Wed, 14 Aug 2013 17:07:26 -0500 Subject: [PATCH 0261/1030] Add factory methods to PatternsBasedRepository This commit adds convenience methods to PatternsBasedRepository that produce a copy of the repository with metadata optional or with consistency checking disabled. --- ivy/src/main/scala/sbt/Resolver.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index fb7daa210..e72db1e46 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -26,6 +26,8 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) + private[sbt] def withoutConsistencyCheck(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, true) private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) @@ -47,7 +49,8 @@ object Patterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean = false, skipConsistencyCheck: Boolean = false): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, false, false) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } object RepositoryHelpers { @@ -81,6 +84,13 @@ sealed abstract class PatternsBasedRepository extends Resolver /** Enables maven 2 compatibility for this repository. */ def mavenStyle() = copy(patterns.mavenStyle()) + + /** Makes descriptor metadata optional for this repository. */ + def descriptorOptional() = copy(patterns.withDescriptorOptional()) + + /** Disables consistency checking for this repository. */ + def skipConsistencyCheck() = copy(patterns.withoutConsistencyCheck()) + /** Adds the given patterns for resolving/publishing Ivy files.*/ def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) /** Adds the given patterns for resolving/publishing artifacts.*/ From b408a9f05742f504e7482356e8cbe4264c4eff7f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 13 Sep 2013 16:37:22 -0400 Subject: [PATCH 0262/1030] Move some logic in custom pom parser to separate methods --- ivy/src/main/scala/sbt/CustomPomParser.scala | 21 +++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 277b50900..bb7395aa1 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -48,12 +48,7 @@ object CustomPomParser def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = { - import collection.JavaConverters._ - // The element of the pom is used to store additional metadata for sbt plugins. - // This is done because the pom XSD does not appear to allow extra metadata anywhere else. - // The pom.xml does not need to be readable by maven because these are only enabled for sbt plugins. - // However, the pom.xml needs to be valid because other tools, like repository managers may read the pom.xml. - val properties = PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap + val properties = getPomProperties(md) // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. // These are attached to the module itself. @@ -72,12 +67,24 @@ object CustomPomParser // Merges artifact sections for duplicate dependency definitions val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) - val unqualify = (filtered - ExtraAttributesKey) map { case (k,v) => ("e:" + k, v) } + val unqualify = toUnqualify(filtered) if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts && !mergeDuplicates) md else addExtra(unqualify, extraDepAttributes, parser, md) } + // The element of the pom is used to store additional metadata, such as for sbt plugins or for the base URL for API docs. + // This is done because the pom XSD does not appear to allow extra metadata anywhere else. + // The extra sbt plugin metadata in pom.xml does not need to be readable by maven, but the other information may be. + // However, the pom.xml needs to be valid in all cases because other tools like repository managers may read the pom.xml. + private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String,String] = + { + import collection.JavaConverters._ + PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap + } + private[sbt] def toUnqualify(propertyAttributes: Map[String, String]): Map[String, String] = + (propertyAttributes - ExtraAttributesKey) map { case (k,v) => ("e:" + k, v) } + private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) From da1b8e1f557198509e59b1abb46b73e32622f736 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 13 Sep 2013 23:18:13 -0400 Subject: [PATCH 0263/1030] do custom pom processing when reading from cache, fixes #876 --- ivy/src/main/scala/sbt/Ivy.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 852103195..51f538740 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -321,8 +321,11 @@ private object IvySbt private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = if(resolved eq null) null - else - new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, resolved.getDescriptor, resolved.getReport, resolved.isForce) + else { + val desc = resolved.getDescriptor + val updatedDescriptor = CustomPomParser.defaultTransform(desc.getParser, desc) + new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, updatedDescriptor, resolved.getReport, resolved.isForce) + } private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) //, artifactResolver: DependencyResolver) { From d9ce0a0a04f3be81fce6d6de03d51b08f292f29f Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Fri, 13 Sep 2013 23:19:06 -0400 Subject: [PATCH 0264/1030] don't transform a module descriptor after it has already been processed by this sbt version. Ref #876. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index bb7395aa1..34147d933 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -43,10 +43,25 @@ object CustomPomParser val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) + private[this] val TransformedHashKey = "sbtTransformHash" + // A hash of the parameters transformation is based on. + // If a descriptor has a different hash, we need to retransform it. + private[this] val TransformHash: String = hash((unqualifiedKeys ++ JarPackagings).toSeq.sorted) + private[this] def hash(ss: Seq[String]): String = Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) + // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + if(transformedByThisVersion(md)) md else defaultTransformImpl(parser, md) + + private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = + { + val extraInfo = md.getExtraInfo + extraInfo != null && extraInfo.get(TransformedHashKey) == TransformHash + } + + private[this] def defaultTransformImpl(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = { val properties = getPomProperties(md) @@ -180,6 +195,7 @@ object CustomPomParser for(l <- md.getLicenses) dmd.addLicense(l) for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) + dmd.addExtraInfo(TransformedHashKey, TransformHash) // mark as transformed by this version, so we don't need to do it again for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) From b7770bc52e15b09679e6cf6a3b77dfc5d0665202 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Mon, 16 Sep 2013 11:57:02 -0400 Subject: [PATCH 0265/1030] parse external pom.xml with CustomPomParser to handle multiple definitions. Fixes #758. This is the same issue fixed by 74c07c64a78447274be47804a6f5f5019c571dab but in this case the cause was the top-level pom.xml, which didn't go through CustomPomParser. --- ivy/src/main/scala/sbt/Ivy.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 51f538740..6154bdbe8 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -168,7 +168,7 @@ final class IvySbt(val configuration: IvyConfiguration) /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ private def configurePom(pc: PomConfiguration) = { - val md = PomModuleDescriptorParser.getInstance.parseDescriptor(settings, toURL(pc.file), pc.validate) + val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) IvySbt.addConfigurations(dmd, Configurations.defaultInternal) val defaultConf = Configurations.DefaultMavenConfiguration.name From 5755689a8c284e158267ca586555d26a7362248d Mon Sep 17 00:00:00 2001 From: James Roper Date: Tue, 24 Sep 2013 12:17:46 +1000 Subject: [PATCH 0266/1030] String upper/lower case no longer locale dependent Fixed many instances of the Turkish i bug. Spare a thought for the poor Turks! --- ivy/src/main/scala/sbt/StringUtilities.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala index b86427449..caf373d3b 100644 --- a/ivy/src/main/scala/sbt/StringUtilities.scala +++ b/ivy/src/main/scala/sbt/StringUtilities.scala @@ -3,10 +3,12 @@ */ package sbt +import java.util.Locale + object StringUtilities { @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") - def normalize(s: String) = s.toLowerCase.replaceAll("""\W+""", "-") + def normalize(s: String) = s.toLowerCase(Locale.ENGLISH).replaceAll("""\W+""", "-") def nonEmpty(s: String, label: String) { require(s.trim.length > 0, label + " cannot be empty.") From e1cd7ebde0aac6ec3f3f7559b9c2407095c8b85e Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 2 Oct 2013 19:39:17 -0400 Subject: [PATCH 0267/1030] 'makePom' should not generate elements for standard classifiers. Fixes #728. The element was generated for any explicit Artifact with a type other than "jar". withSources() and withJavadoc() create explicit Artifacts of this kind, but shouldn't have elements. They are primarily artifacts with classifiers- the type is an Ivy aspect. So, when writing to a pom, don't use write a type for known classifiers. --- ivy/src/main/scala/sbt/MakePom.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index cbfb0a5a1..5e49243d3 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -174,7 +174,13 @@ class MakePom(val log: Logger) case x => x.toArray } val (scope, optional) = getScopeAndOptional(configs) - makeDependencyElem(dependency, scope, optional, artifactClassifier(artifact), artifactType(artifact)) + val classifier = artifactClassifier(artifact) + val baseType = artifactType(artifact) + val tpe = (classifier, baseType) match { + case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None + case _ => baseType + } + makeDependencyElem(dependency, scope, optional, classifier, tpe) } def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = { From dba8bd28cf3350d69a5c0065488ccec2199d88a5 Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Thu, 10 Oct 2013 21:36:11 -0400 Subject: [PATCH 0268/1030] Work around various issues with Maven local repositories. Fixes #321. * when mvn does a local 'install', it doesn't update the pom.xml last modified time if the pom.xml content hasn't changed * an ivy.xml includes publicationDate, so an ivy.xml will always be touched even if the other content hasn't changed * when Ivy checks if a snapshot is uptodate + it sees a SNAPSHOT, so it knows the module metadata and artifacts might change + it then checks the lastModified time of the metadata + if unchanged, it uses the cached information + if useOrigin is effectively false (either it is explicitly false or a resource is remote/isLocal=false), this means that a new artifact won't be retrieved * the Ivy IBiblioResolver + must be used for Maven repositories for proper behavior (no FileResolver, for example) + only returns URLResources, even for file: URLs + a FileResource is needed in combination with useOrigin to avoid copying artifacts from .m2/repository/ This commit fixes the above by setting a custom URLRepository on a constructed IBiblioResolver. This URLRepository returns FileResources for file: URLs and standard URLResources for others. The returned FileResource has isLocal=true and sbt sets useOrigin=true by default, so the artifacts are used from the origin. If it turns out a similar situation happens when mvn publishes to remote repositories, it is likely the fix for that would be to figure out how to disable the lastModified check on the metadata and always download the metadata. This would be slower, however. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 91fa137a2..58ba6d4ac 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -3,6 +3,7 @@ */ package sbt +import java.net.URL import java.util.Collections import org.apache.ivy.{core,plugins} import core.module.id.ModuleRevisionId @@ -11,6 +12,8 @@ import core.resolve.ResolveData import core.settings.IvySettings import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} +import plugins.repository.url.{URLRepository => URLRepo} +import plugins.repository.file.{FileRepository => FileRepo, FileResource} private object ConvertResolver { @@ -29,6 +32,7 @@ private object ConvertResolver } } val resolver = new PluginCapableResolver + resolver.setRepository(new LocalIfFileRepo) initializeMavenStyle(resolver, repo.name, repo.root) resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns resolver @@ -128,4 +132,16 @@ private object ConvertResolver patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) } + /** A custom Ivy URLRepository that returns FileResources for file URLs. + * This allows using the artifacts from the Maven local repository instead of copying them to the Ivy cache. */ + private[this] final class LocalIfFileRepo extends URLRepo { + private[this] val repo = new FileRepo + override def getResource(source: String) = { + val url = new URL(source) + if(url.getProtocol == IO.FileScheme) + new FileResource(repo, IO.toFile(url)) + else + super.getResource(source) + } + } } From 28c189e4e26fadf541251bd48654f072e917012d Mon Sep 17 00:00:00 2001 From: Mark Harrah Date: Wed, 23 Oct 2013 09:46:43 -0400 Subject: [PATCH 0269/1030] Better representation of no cross-version suffix in suffix conflict error message. --- ivy/src/main/scala/sbt/ConflictWarning.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index b5ccd1967..51c69e988 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -38,7 +38,7 @@ object ConflictWarning val conflictMsgs = for( ((org,rawName), fullNames) <- crossMismatches ) yield { - val suffixes = fullNames.map(n => "_" + getCrossSuffix(n)).mkString(", ") + val suffixes = fullNames.map(getCrossSuffix).mkString(", ") s"${idString(org,rawName)} $suffixes" } log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) @@ -73,8 +73,8 @@ object ConflictWarning case _ => s } private[this] def getCrossSuffix(s: String): String = s match { - case CrossSuffixPattern(_, v) => v - case _ => "" + case CrossSuffixPattern(_, v) => "_" + v + case _ => "" } } From 8f74dc552493a2dd5180e01242b10cbaea0a3d22 Mon Sep 17 00:00:00 2001 From: William Benton Date: Fri, 13 Dec 2013 11:39:09 -0600 Subject: [PATCH 0270/1030] Support Ivy 2.3.0-final. This entailed modifying ResolutionCache and the CustomPomParser to reflect changes to the ResolutionCacheManager interface and DefaultExtendsDescriptor class between Ivy 2.3.0-rc1 and 2.3.0-rc2. Specifically, 1. ResolutionCacheManager now includes two additional methods that needed implementations in ResolutionCache: getResolvedModuleDescriptor(mrid: ModuleRevisionId) and saveResolvedModuleDescriptor(md: ModuleDescriptor). I adapted the implementations for these (which are expressed primarily in terms of other interface methods) from Ivy 2.3.0's DefaultResolutionCacheManager. 2. Instead of taking a ModuleRevisionIdentifier and a resolved ModuleRevisionIdentifier as its first two arguments, the DefaultExtendsDescriptor constructor now takes a ModuleDescriptor. This was a trivial change. Note that ResolutionCache.getResolvedModuleDescriptor does not appear to be used by Ivy as sbt uses Ivy and there is thus no test coverage for its implementation. Also note that the DefaultResolutionCacheManager object created in Update.configureResolutionCache now requires a reference to an IvySettings object; DRCM expects this to be non-null. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- ivy/src/main/scala/sbt/Ivy.scala | 2 +- ivy/src/main/scala/sbt/ResolutionCache.scala | 27 +++++++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 34147d933..7023ab8d9 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -203,7 +203,7 @@ object CustomPomParser val unique = IvySbt.mergeDuplicateDefinitions(withExtra) unique foreach dmd.addDependency - for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( mrid, resolvedMrid, ed.getLocation, ed.getExtendsTypes) ) + for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( md, ed.getLocation, ed.getExtendsTypes) ) for( conf <- md.getConfigurations) { dmd.addConfiguration(conf) for(art <- md.getArtifacts(conf.getName)) { diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 6154bdbe8..e1dca53ae 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -310,7 +310,7 @@ private object IvySbt private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir - settings.setResolutionCacheManager(new ResolutionCache(base)) + settings.setResolutionCacheManager(new ResolutionCache(base, settings)) } // set the artifact resolver to be the main resolver. // this is because sometimes the artifact resolver saved in the cache is not correct diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala index ab693445d..d79f25a4c 100644 --- a/ivy/src/main/scala/sbt/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/ResolutionCache.scala @@ -1,18 +1,24 @@ package sbt import java.io.File +import java.io.FileInputStream +import java.util.Properties import org.apache.ivy.core +import org.apache.ivy.plugins.parser import core.IvyPatternHelper +import core.settings.IvySettings import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, DefaultResolutionCacheManager, ResolutionCacheManager} import core.module.id.ModuleRevisionId +import core.module.descriptor.ModuleDescriptor import ResolutionCache.{Name, ReportDirectory, ResolvedName, ResolvedPattern} +import parser.xml.XmlModuleDescriptorParser /** Replaces the standard Ivy resolution cache in order to: * 1. Separate cached resolved Ivy files from resolution reports, making the resolution reports easier to find. * 2. Have them per-project for easier cleaning (possible with standard cache, but central to this custom one). * 3. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. */ -private[sbt] final class ResolutionCache(base: File) extends ResolutionCacheManager +private[sbt] final class ResolutionCache(base: File, settings: IvySettings) extends ResolutionCacheManager { private[this] def resolvedFileInCache(m: ModuleRevisionId, name: String, ext: String): File = { val p = ResolvedPattern @@ -35,6 +41,25 @@ private[sbt] final class ResolutionCache(base: File) extends ResolutionCacheMana new File(reportBase, resolveId + "-" + conf + ".xml") def getConfigurationResolveReportsInCache(resolveId: String): Array[File] = IO.listFiles(reportBase).filter(_.getName.startsWith(resolveId + "-")) + + // XXX: this method is required by ResolutionCacheManager in Ivy 2.3.0 final, + // but it is apparently unused by Ivy as sbt uses Ivy. Therefore, it is + // unexercised in tests. Note that the implementation of this method in Ivy 2.3.0's + // DefaultResolutionCache also resolves parent properties for a given mrid + def getResolvedModuleDescriptor(mrid: ModuleRevisionId): ModuleDescriptor = { + val ivyFile = getResolvedIvyFileInCache(mrid) + if (!ivyFile.exists()) { + throw new IllegalStateException("Ivy file not found in cache for " + mrid + "!") + } + + return XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, ivyFile.toURI().toURL(), false) + } + + def saveResolvedModuleDescriptor(md: ModuleDescriptor): Unit = { + val mrid = md.getResolvedModuleRevisionId + val cachedIvyFile = getResolvedIvyFileInCache(mrid) + md.toIvyFile(cachedIvyFile) + } } private[sbt] object ResolutionCache { From fda1d25350cbc2a4ebb347c3654ac4c6aa9febbe Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 17 Jan 2014 10:39:20 +0000 Subject: [PATCH 0271/1030] Expose overwrite flag in IvyActions.publish, and by default only overwrite if it's a snapshot --- ivy/src/main/scala/sbt/IvyActions.scala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index f3ac22c82..65c45a6a7 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -16,7 +16,8 @@ import core.resolve.ResolveOptions import plugins.resolver.{BasicResolver, DependencyResolver} final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) -final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value) +final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, + val overwrite: Boolean = false) final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) @@ -86,11 +87,11 @@ object IvyActions import configuration._ module.withModule(log) { case (ivy, md, default) => val resolver = ivy.getSettings.getResolver(resolverName) - if(resolver eq null) error("Undefined resolver '" + resolverName + "'") + if(resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList - withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = true) } + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toSeq + withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } } } private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T = From 1e549eb3dc00c8f6fa45fe6265c7433682983808 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 23 Jan 2014 12:07:37 +0000 Subject: [PATCH 0272/1030] Fix binary compatibility with 0.13 --- ivy/src/main/scala/sbt/IvyActions.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 65c45a6a7..0ad3376d3 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -17,7 +17,10 @@ import plugins.resolver.{BasicResolver, DependencyResolver} final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, - val overwrite: Boolean = false) + val overwrite: Boolean) { + def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) = + this(ivyFile, resolverName, artifacts, checksums, logging, false) +} final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) From b25fc2bd00a809d78fbb13f93837e96274688327 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 3 Mar 2014 12:10:37 -0500 Subject: [PATCH 0273/1030] Fix #1136 - Ivy's `+` dependencies not converted to maven style syntax. * Attempt to convert dependencies that end in `+` into maven-style version range * if a failure occurs, just use the original version (could be bad...). --- ivy/src/main/scala/sbt/MakePom.scala | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 5e49243d3..4c4b7c8d0 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -188,7 +188,7 @@ class MakePom(val log: Logger) {mrid.getOrganisation} {mrid.getName} - {mrid.getRevision} + {makeDependencyVersion(mrid.getRevision)} { scopeElem(scope) } { optionalElem(optional) } { classifierElem(classifier) } @@ -197,6 +197,25 @@ class MakePom(val log: Logger) } + + + def makeDependencyVersion(revision: String): String = { + if(revision endsWith "+") try { + // TODO - this is the slowest possible implementation. + val beforePlus = revision.reverse.dropWhile(_ != '.').drop(1).reverse + val lastVersion = beforePlus.reverse.takeWhile(_ != '.').reverse + val lastVersionInt = lastVersion.toInt + val prefixVersion = beforePlus.reverse.dropWhile(_ != '.').drop(1).reverse + s"[$beforePlus, ${prefixVersion}.${lastVersionInt+1})" + } catch { + case e: NumberFormatException => + // TODO - if the version deosn't meet our expectations, maybe we just issue a hard + // error instead of softly ignoring the attempt to rewrite. + //sys.error(s"Could not fix version [$revision] into maven style version") + revision + } else revision + } + @deprecated("No longer used and will be removed.", "0.12.1") def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { From 25400a11d3cf7628dce2c5feab992e15c74ee70e Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 4 Mar 2014 11:36:34 -0500 Subject: [PATCH 0274/1030] Fixes #429 - Add better error messages when credentials are not found. * Create hackery to inspect registered credentials in the IvyCredentialStore. * Create a new authenticator which inserts itself *after* the ivy authenticator. - Will issue an error message detailing host/realm required if credentials are not found. - Also lists out configured Realms with a 'is misspelled' message. - Ignores proxy-related authentication errors, for now. --- ivy/src/main/scala/sbt/Ivy.scala | 2 + .../ivyint/ErrorMessageAuthenticator.scala | 128 ++++++++++++++++++ .../sbt/ivyint/IvyCredentialsLookup.scala | 63 +++++++++ 3 files changed, 193 insertions(+) create mode 100644 ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala create mode 100644 ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index e1dca53ae..2408992e6 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -99,6 +99,8 @@ final class IvySbt(val configuration: IvyConfiguration) def withIvy[T](log: MessageLogger)(f: Ivy => T): T = withDefaultLogger(log) { + // See #429 - We always insert a helper authenticator here which lets us get more useful authentication errors. + ivyint.ErrorMessageAuthenticator.install() ivy.pushContext() ivy.getLoggerEngine.pushLogger(log) try { f(ivy) } diff --git a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala new file mode 100644 index 000000000..3d0d174d8 --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala @@ -0,0 +1,128 @@ +package sbt +package ivyint + +import java.lang.reflect.Field +import java.lang.reflect.Method +import java.net.Authenticator +import java.net.PasswordAuthentication +import org.apache.ivy.util.Credentials +import org.apache.ivy.util.Message +import org.apache.ivy.util.url.IvyAuthenticator +import org.apache.ivy.util.url.CredentialsStore + +/** + * Helper to install an Authenticator that works with the IvyAuthenticator to provide better error messages when + * credentials don't line up. + */ +object ErrorMessageAuthenticator { + private var securityWarningLogged = false + + private def originalAuthenticator: Option[Authenticator] = { + try { + val f = classOf[Authenticator].getDeclaredField("theAuthenticator"); + f.setAccessible(true); + Option(f.get(null).asInstanceOf[Authenticator]) + } catch { + // TODO - Catch more specific errors. + case t: Throwable => + Message.debug("Error occurred while getting the original authenticator: " + t.getMessage) + None + } + } + + private lazy val ivyOriginalField = { + val field = classOf[IvyAuthenticator].getDeclaredField("original") + field.setAccessible(true) + field + } + // Attempts to get the original authenticator form the ivy class or returns null. + private def installIntoIvy(ivy: IvyAuthenticator): Option[Authenticator] = { + // Here we install ourselves as the IvyAuthenticator's default so we get called AFTER Ivy has a chance to run. + def installIntoIvyImpl(original: Option[Authenticator]): Unit = { + val newOriginal = new ErrorMessageAuthenticator(original) + ivyOriginalField.set(ivy, newOriginal) + } + + try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { + case Some(alreadyThere: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) + } catch { + case t: Throwable => + Message.debug("Error occurred will trying to install debug messages into Ivy Authentication" + t.getMessage) + } + Some(ivy) + } + + /** Installs the error message authenticator so we have nicer error messages when using java's URL for downloading. */ + def install() { + // Actually installs the error message authenticator. + def doInstall(original: Option[Authenticator]): Unit = + try Authenticator.setDefault(new ErrorMessageAuthenticator(original)) + catch { + case e: SecurityException if !securityWarningLogged => + securityWarningLogged = true; + Message.warn("Not enough permissions to set the ErorrMessageAuthenticator. " + + "Helpful debug messages disabled!"); + } + // We will try to use the original authenticator as backup authenticator. + // Since there is no getter available, so try to use some reflection to + // obtain it. If that doesn't work, assume there is no original authenticator + def doInstallIfIvy(original: Option[Authenticator]): Unit = + original match { + case Some(installed: ErrorMessageAuthenticator) => // Ignore, we're already installed + case Some(ivy: IvyAuthenticator) => installIntoIvy(ivy) + case original => doInstall(original) + } + doInstallIfIvy(originalAuthenticator) + } +} +/** + * An authenticator which just delegates to a previous authenticator and issues *nice* + * error messages on failure to find credentials. + * + * Since ivy installs its own credentials handler EVERY TIME it resolves or publishes, we want to + * install this one at some point and eventually ivy will capture it and use it. + */ +private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticator]) extends Authenticator { + + protected override def getPasswordAuthentication(): PasswordAuthentication = { + // We're guaranteed to only get here if Ivy's authentication fails + if (!isProxyAuthentication) { + val host = getRequestingHost + // TODO - levenshtein distance "did you mean" message. + Message.error(s"Unable to find credentials for [${getRequestingPrompt} @ ${host}].") + val configuredRealms = IvyCredentialsLookup.realmsForHost.getOrElse(host, Set.empty) + if(!configuredRealms.isEmpty) { + Message.error(s" Is one of these realms mispelled for host [${host}]:") + configuredRealms foreach { realm => + Message.error(s" * ${realm}") + } + } + } + // TODO - Maybe we should work on a helpful proxy message... + + // TODO - To be more maven friendly, we may want to also try to grab the "first" authentication that shows up for a server and try it. + // or maybe allow that behavior to be configured, since maven users aren't used to realms (which they should be). + + // Grabs the authentication that would have been provided had we not been installed... + def originalAuthentication: Option[PasswordAuthentication] = { + Authenticator.setDefault(original.getOrElse(null)) + try Option(Authenticator.requestPasswordAuthentication( + getRequestingHost, + getRequestingSite, + getRequestingPort, + getRequestingProtocol, + getRequestingPrompt, + getRequestingScheme)) + finally Authenticator.setDefault(this) + } + originalAuthentication.getOrElse(null) + } + + /** Returns true if this authentication if for a proxy and not for an HTTP server. + * We want to display different error messages, depending. + */ + private def isProxyAuthentication: Boolean = + getRequestorType == Authenticator.RequestorType.PROXY + +} \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala new file mode 100644 index 000000000..365ffe698 --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala @@ -0,0 +1,63 @@ +package sbt +package ivyint + +import org.apache.ivy.util.url.CredentialsStore +import collection.JavaConverters._ + +/** A key used to store credentials in the ivy credentials store. */ +private[sbt] sealed trait CredentialKey +/** Represents a key in the ivy credentials store that is only specific to a host. */ +private[sbt] case class Host(name: String) extends CredentialKey +/** Represents a key in the ivy credentials store that is keyed to both a host and a "realm". */ +private[sbt] case class Realm(host: String, realm: String) extends CredentialKey + +/** + * Helper mechanism to improve credential related error messages. + * + * This evil class exposes to us the necessary information to warn on credential failure and offer + * spelling/typo suggestions. + */ +private[sbt] object IvyCredentialsLookup { + + /** Helper extractor for Ivy's key-value store of credentials. */ + private object KeySplit { + def unapply(key: String): Option[(String,String)] = { + key.indexOf('@') match { + case -1 => None + case n => Some(key.take(n) -> key.drop(n+1)) + } + } + } + + /** Here we cheat runtime private so we can look in the credentials store. + * + * TODO - Don't bomb at class load time... + */ + private val credKeyringField = { + val tmp = classOf[CredentialsStore].getDeclaredField("KEYRING") + tmp.setAccessible(true) + tmp + } + + /** All the keys for credentials in the ivy configuration store. */ + def keyringKeys: Set[CredentialKey] = { + val map = credKeyringField.get(null).asInstanceOf[java.util.HashMap[String, Any]] + // make a clone of the set... + (map.keySet.asScala.map { + case KeySplit(realm, host) => Realm(host, realm) + case host => Host(host) + })(collection.breakOut) + } + + /** + * A mapping of host -> realms in the ivy credentials store. + */ + def realmsForHost: Map[String, Set[String]] = + keyringKeys collect { + case x: Realm => x + } groupBy { realm => + realm.host + } mapValues { realms => + realms map (_.realm) + } +} \ No newline at end of file From ee28011dfc9d755d61f58840cd90e097abfc1c8b Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 5 Mar 2014 19:14:21 -0500 Subject: [PATCH 0275/1030] Pull in @cunei's suggestion for a more complete Ivy->Maven dynamic revision convertor. We attempt to convert these constructs to maven: * 1.+ * ]1,2] * [2,3[ * 1+ - Albeit this one is a heuristic for accuracy. This should help ivy users which prefer the nicer 1.2.+ syntax. Also adds tests/improves exisitng tests. --- ivy/src/main/scala/sbt/MakePom.scala | 43 ++++++++++++++++++++-------- ivy/src/test/scala/MakePomTest.scala | 29 +++++++++++++++++++ 2 files changed, 60 insertions(+), 12 deletions(-) create mode 100644 ivy/src/test/scala/MakePomTest.scala diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 4c4b7c8d0..16ec28333 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -200,20 +200,39 @@ class MakePom(val log: Logger) def makeDependencyVersion(revision: String): String = { - if(revision endsWith "+") try { - // TODO - this is the slowest possible implementation. - val beforePlus = revision.reverse.dropWhile(_ != '.').drop(1).reverse - val lastVersion = beforePlus.reverse.takeWhile(_ != '.').reverse + def plusRange(s:String, shift:Int = 0) = { + def pow(i:Int):Int = if (i>0) 10 * pow(i-1) else 1 + val (prefixVersion, lastVersion) = (s+"0"*shift).reverse.split("\\.",2) match { + case Array(revLast,revRest) => + ( revRest.reverse + ".", revLast.reverse ) + case Array(revLast) => ("", revLast.reverse) + } val lastVersionInt = lastVersion.toInt - val prefixVersion = beforePlus.reverse.dropWhile(_ != '.').drop(1).reverse - s"[$beforePlus, ${prefixVersion}.${lastVersionInt+1})" + s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt+pow(shift)})" + } + val startSym=Set(']','[','(') + val stopSym=Set(']','[',')') + try { + if (revision endsWith ".+") { + plusRange(revision.substring(0,revision.length-2)) + } else if (revision endsWith "+") { + val base = revision.take(revision.length-1) + // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so + // we assume version ranges never go beyond 5 siginificant digits. + (0 to 5).map(plusRange(base,_)).mkString(",") + } else if (startSym(revision(0)) && stopSym(revision(revision.length-1))) { + val start = revision(0) + val stop = revision(revision.length-1) + val mid = revision.substring(1,revision.length-1) + (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + } else revision } catch { - case e: NumberFormatException => - // TODO - if the version deosn't meet our expectations, maybe we just issue a hard - // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") - revision - } else revision + case e: NumberFormatException => + // TODO - if the version doesn't meet our expectations, maybe we just issue a hard + // error instead of softly ignoring the attempt to rewrite. + //sys.error(s"Could not fix version [$revision] into maven style version") + revision + } } @deprecated("No longer used and will be removed.", "0.12.1") diff --git a/ivy/src/test/scala/MakePomTest.scala b/ivy/src/test/scala/MakePomTest.scala new file mode 100644 index 000000000..1341b207d --- /dev/null +++ b/ivy/src/test/scala/MakePomTest.scala @@ -0,0 +1,29 @@ +package sbt + +import java.io.File +import org.specs2._ +import mutable.Specification + +object MakePomTest extends Specification +{ + val mp = new MakePom(ConsoleLogger()) + import mp.{makeDependencyVersion=>v} + "MakePom makeDependencyVersion" should { + "Handle .+ in versions" in { + v("1.+") must_== "[1,2)" + v("1.2.3.4.+") must_== "[1.2.3.4,1.2.3.5)" + v("12.31.42.+") must_== "[12.31.42,12.31.43)" + } + /* TODO - do we care about this case? + * 1+ --> [1,2),[10,20),[100,200),[1000,2000),[10000,20000),[100000,200000) + */ + "Handle ]* bracket in version ranges" in { + v("]1,3]") must_== "(1,3]" + v("]1.1,1.3]") must_== "(1.1,1.3]" + } + "Handle *[ bracket in version ranges" in { + v("[1,3[") must_== "[1,3)" + v("[1.1,1.3[") must_== "[1.1,1.3)" + } + } +} From 95e9b5cda73cf54827238b5682a32e8612832153 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Sat, 8 Mar 2014 00:24:15 -0500 Subject: [PATCH 0276/1030] Don't fail publishing on overwrite, but issue a warning. Workaround for #1156. * Creates a new FileRepository that will stil allow local files to be transfered if overwrite is true (non-snapshot module), but will issue a warning about deprecated behavior. * Ensure warning is long enough to annoy people into asking what it's about. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 22 ++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 58ba6d4ac..a93a57011 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -61,7 +61,13 @@ private object ConvertResolver } case repo: FileRepository => { - val resolver = new FileSystemResolver with DescriptorRequired + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) + } resolver.setName(repo.name) initializePatterns(resolver, repo.patterns, settings) import repo.configuration.{isLocal, isTransactional} @@ -135,7 +141,7 @@ private object ConvertResolver /** A custom Ivy URLRepository that returns FileResources for file URLs. * This allows using the artifacts from the Maven local repository instead of copying them to the Ivy cache. */ private[this] final class LocalIfFileRepo extends URLRepo { - private[this] val repo = new FileRepo + private[this] val repo = new WarnOnOverwriteFileRepo() override def getResource(source: String) = { val url = new URL(source) if(url.getProtocol == IO.FileScheme) @@ -144,4 +150,16 @@ private object ConvertResolver super.getResource(source) } } + + private[this] final class WarnOnOverwriteFileRepo extends FileRepo() { + override def put(source: java.io.File, destination: String, overwrite: Boolean): Unit = { + try super.put(source, destination, overwrite) + catch { + case e: java.io.IOException if e.getMessage.contains("destination already exists") => + import org.apache.ivy.util.Message + Message.warn(s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0.") + super.put(source, destination, true) + } + } + } } From efab62e89ee28077413a78374676c8f8a424b610 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 19 Mar 2014 11:04:06 +0000 Subject: [PATCH 0277/1030] sbtTransformHash -> e:sbtTransformHash --- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 7023ab8d9..dc56866bb 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -43,7 +43,7 @@ object CustomPomParser val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) - private[this] val TransformedHashKey = "sbtTransformHash" + private[this] val TransformedHashKey = "e:sbtTransformHash" // A hash of the parameters transformation is based on. // If a descriptor has a different hash, we need to retransform it. private[this] val TransformHash: String = hash((unqualifiedKeys ++ JarPackagings).toSeq.sorted) From 51d0df004fc9e6634d534061f1bf0405689d3829 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 21 Mar 2014 23:53:06 -0400 Subject: [PATCH 0278/1030] CustomPomParser compatibility with 0.13.1. #1191 #1192 --- ivy/src/main/scala/sbt/CustomPomParser.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index dc56866bb..871c1f07c 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -57,8 +57,14 @@ object CustomPomParser private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = { + val oldTransformedHashKey = "sbtTransformHash" val extraInfo = md.getExtraInfo - extraInfo != null && extraInfo.get(TransformedHashKey) == TransformHash + // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both + Option(extraInfo).isDefined && + ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + case Some(TransformHash) => true + case _ => false + }) } private[this] def defaultTransformImpl(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = From b95759a138e626b7a8277c31b4c5690559777029 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Sat, 29 Mar 2014 13:06:27 -0400 Subject: [PATCH 0279/1030] Bump to our own nightly of ivy 2.4.0 (RC1+). * Testing the infrastructure to use our own instance of ivy * Allow us to push bug-fixes/performance directly into ivy on our own pace, as we submit patches back to ivy master --- ivy/src/main/scala/sbt/IvyLogger.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyLogger.scala b/ivy/src/main/scala/sbt/IvyLogger.scala index acd07781b..6e1b136fe 100644 --- a/ivy/src/main/scala/sbt/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/IvyLogger.scala @@ -31,7 +31,7 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger def warn(msg: String) = logger.warn(msg) def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) logger.error(msg) - private def emptyList = java.util.Collections.emptyList[T forSome { type T}] + private def emptyList = java.util.Collections.emptyList[String] def getProblems = emptyList def getWarns = emptyList def getErrors = emptyList From 80c09619bffc1f2bfbf4021eea28f0b337376e51 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 4 Apr 2014 16:38:44 -0400 Subject: [PATCH 0280/1030] Ensure that if artifact is published, we overwrite default checksums. Fixes # 1233 * Add a new "shim" for RepositoryResolvers that modifies the "put" method so that it will ignore the overwrite flag for checksums. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 77 +++++++++++++++++++- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index a93a57011..ab1cf95ce 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -10,13 +10,84 @@ import core.module.id.ModuleRevisionId import core.module.descriptor.DependencyDescriptor import core.resolve.ResolveData import core.settings.IvySettings -import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver} +import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver} import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} import plugins.repository.url.{URLRepository => URLRepo} import plugins.repository.file.{FileRepository => FileRepo, FileResource} +import java.io.File +import org.apache.ivy.util.ChecksumHelper +import org.apache.ivy.core.module.descriptor.{Artifact=>IArtifact} + private object ConvertResolver { + /** This class contains all the reflective lookups used in the + * checksum-friendly URL publishing shim. + */ + private object ChecksumFriendlyURLResolver { + import java.lang.reflect.AccessibleObject + private def reflectiveLookup[A <: AccessibleObject](f: Class[_] => A): Option[A] = + try { + val cls = classOf[RepositoryResolver] + val thing = f(cls) + thing.setAccessible(true) + Some(thing) + } catch { + case e: java.lang.ReflectiveOperationException => None + } + private val signerNameField: Option[java.lang.reflect.Field] = + reflectiveLookup(_.getDeclaredField("signerName")) + private val putChecksumMethod: Option[java.lang.reflect.Method] = + reflectiveLookup(_.getDeclaredMethod("putChecksum", + classOf[IArtifact], classOf[File], classOf[String], + classOf[Boolean], classOf[String])) + private val putSignatureMethod: Option[java.lang.reflect.Method] = + reflectiveLookup(_.getDeclaredMethod("putSignature", + classOf[IArtifact], classOf[File], classOf[String], + classOf[Boolean])) + } + /** + * The default behavior of ivy's overwrite flags ignores the fact that a lot of repositories + * will autogenerate checksums *for* an artifact if it doesn't already exist. Therefore + * if we succeed in publishing an artifact, we need to just blast the checksums in place. + * This acts as a "shim" on RepositoryResolvers so that we can hook our methods into + * both the IBiblioResolver + URLResolver without having to duplicate the code in two + * places. However, this does mean our use of reflection is awesome. + * + * TODO - See about contributing back to ivy. + */ + private trait ChecksumFriendlyURLResolver extends RepositoryResolver { + import ChecksumFriendlyURLResolver._ + private def signerName: String = signerNameField match { + case Some(field) => field.get(this).asInstanceOf[String] + case None => null + } + override protected def put(artifact: IArtifact, src: File, dest: String, overwrite: Boolean): Unit = { + // verify the checksum algorithms before uploading artifacts! + val checksums = getChecksumAlgorithms() + val repository = getRepository() + for { + checksum <- checksums + if !ChecksumHelper.isKnownAlgorithm(checksum) + } throw new IllegalArgumentException("Unknown checksum algorithm: " + checksum) + repository.put(artifact, src, dest, overwrite); + // Fix for sbt#1156 - Artifactory will auto-generate MD5/sha1 files, so + // we need to overwrite what it has. + for (checksum <- checksums) { + putChecksumMethod match { + case Some(method) => method.invoke(this, artifact, src, dest, true: java.lang.Boolean, checksum) + case None => // TODO - issue warning? + } + } + if (signerName != null) { + putSignatureMethod match { + case None => () + case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) + } + } + } + } + /** Converts the given sbt resolver into an Ivy resolver..*/ def apply(r: Resolver, settings: IvySettings, log: Logger) = { @@ -25,7 +96,7 @@ private object ConvertResolver case repo: MavenRepository => { val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with DescriptorRequired { + final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { def setPatterns() { // done this way for access to protected methods. setArtifactPatterns(pattern) setIvyPatterns(pattern) @@ -77,7 +148,7 @@ private object ConvertResolver } case repo: URLRepository => { - val resolver = new URLResolver with DescriptorRequired + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired resolver.setName(repo.name) initializePatterns(resolver, repo.patterns, settings) resolver From 8bd930cbe59932c0d39394b828d5848f0c0bbe5c Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 4 Apr 2014 20:25:37 -0400 Subject: [PATCH 0281/1030] Remove JDK7 features from Resolver shim. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index ab1cf95ce..74c5c119c 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -25,15 +25,22 @@ private object ConvertResolver * checksum-friendly URL publishing shim. */ private object ChecksumFriendlyURLResolver { - import java.lang.reflect.AccessibleObject + // TODO - When we dump JDK6 support we can remove this hackery + // import java.lang.reflect.AccessibleObject + type AccessibleObject = { + def setAccessible(value: Boolean): Unit + } private def reflectiveLookup[A <: AccessibleObject](f: Class[_] => A): Option[A] = try { val cls = classOf[RepositoryResolver] val thing = f(cls) + import scala.language.reflectiveCalls thing.setAccessible(true) Some(thing) } catch { - case e: java.lang.ReflectiveOperationException => None + case (_: java.lang.NoSuchFieldException) | + (_: java.lang.SecurityException) | + (_: java.lang.NoSuchMethodException) => None } private val signerNameField: Option[java.lang.reflect.Field] = reflectiveLookup(_.getDeclaredField("signerName")) From 1742e837c4f5ab0ed4ba89c7f131cf779a393ecb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 5 Apr 2014 01:51:08 -0700 Subject: [PATCH 0282/1030] Roll back sbt/sbt@482f99 (aggressive deletion of cache). Fixes #1091. * sbt 0.12.3 introduced sbt/sbt@482f99 to fix #637 and #641. * The underlying issue of #641 was an incorrect classifier, and it was fixed in sbt/sbt@718fa9 for #683 and shipped as sbt 0.13.0. --- ivy/src/main/scala/sbt/Ivy.scala | 36 -------------------------------- 1 file changed, 36 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 2408992e6..a6519c6bc 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -7,7 +7,6 @@ import Resolver.PluginPattern import java.io.File import java.net.URI -import java.text.ParseException import java.util.concurrent.Callable import java.util.{Collection, Collections => CS} import CS.singleton @@ -24,9 +23,7 @@ import core.settings.IvySettings import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser -import plugins.repository.ResourceDownloader import plugins.resolver.{ChainResolver, DependencyResolver} -import plugins.resolver.util.ResolvedResource import util.{Message, MessageLogger} import util.extendable.ExtendableItem @@ -358,41 +355,8 @@ private object IvySbt case pr: ProjectResolver => true case _ => false } - /** This is overridden to delete outofdate artifacts of changing modules that are not listed in the metadata. - * This occurs for artifacts with classifiers, for example. */ - @throws(classOf[ParseException]) - override def cacheModuleDescriptor(resolver: DependencyResolver, mdRef: ResolvedResource, dd: DependencyDescriptor, moduleArtifact: IArtifact, downloader: ResourceDownloader, options: CacheMetadataOptions): ResolvedModuleRevision = - { - val rmrRaw = super.cacheModuleDescriptor(null, mdRef, dd, moduleArtifact, downloader, options) - val rmr = resetArtifactResolver(rmrRaw) - val mrid = moduleArtifact.getModuleRevisionId - def shouldClear(): Boolean = rmr != null && - ( (rmr.getReport != null && rmr.getReport.isSearched && isChanging(dd, mrid)) || - isProjectResolver(rmr.getResolver) ) - // only handle changing modules whose metadata actually changed. - // Typically, the publication date in the metadata has to change to get here. - if(shouldClear()) { - // this is the locally cached metadata as originally retrieved (e.g. the pom) - val original = rmr.getReport.getOriginalLocalFile - if(original != null) { - // delete all files in subdirectories that are older than the original metadata file's publication date - // The publication date is used because the metadata will be redownloaded for changing files, - // so the last modified time changes, but the publication date doesn't - val pubDate = rmrRaw.getPublicationDate - val lm = if(pubDate eq null) original.lastModified else pubDate.getTime - val indirectFiles = PathFinder(original.getParentFile).*(DirectoryFilter).**(-DirectoryFilter).get.toList - val older = indirectFiles.filter(f => f.lastModified < lm).toList - Message.verbose("Deleting additional old artifacts from cache for changed module " + mrid + older.mkString(":\n\t", "\n\t", "")) - IO.delete(older) - } - } - rmr - } // ignore the original resolver wherever possible to avoid issues like #704 override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} - - def isChanging(dd: DependencyDescriptor, requestedRevisionId: ModuleRevisionId): Boolean = - !localOnly && (dd.isChanging || requestedRevisionId.getRevision.contains("-SNAPSHOT")) } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) From be3ff51f0a32ba5e56e01e6dbd53beff281b8eda Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Wed, 30 Apr 2014 14:35:04 +0200 Subject: [PATCH 0283/1030] Do not attempt to publish if no artifacts are present Ivy transactional publishing will abort if no artifacts are published, either because the temporary directory is not being created, or because Ivy will detect an anomalous condition. Therefore, skip publishing altogether if there is nothing to publish to begin with. --- ivy/src/main/scala/sbt/IvyActions.scala | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 0ad3376d3..716579e0f 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -255,16 +255,18 @@ object IvyActions def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = { - checkFilesPresent(artifacts) - try { - resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - for( (artifact, file) <- artifacts) - resolver.publish(artifact, file, overwrite) - resolver.commitPublishTransaction() - } catch { - case e: Throwable => - try { resolver.abortPublishTransaction() } - finally { throw e } + if (artifacts.nonEmpty) { + checkFilesPresent(artifacts) + try { + resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); + for( (artifact, file) <- artifacts) + resolver.publish(artifact, file, overwrite) + resolver.commitPublishTransaction() + } catch { + case e: Throwable => + try { resolver.abortPublishTransaction() } + finally { throw e } + } } } private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) From e64165ce9edd3c3630f98039a4ad4a75b6427ef2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 May 2014 12:50:07 -0400 Subject: [PATCH 0284/1030] added scalariform --- ivy/src/main/scala/sbt/Artifact.scala | 116 +- ivy/src/main/scala/sbt/ComponentManager.scala | 149 +-- ivy/src/main/scala/sbt/Configuration.scala | 100 +- ivy/src/main/scala/sbt/ConflictWarning.scala | 126 +- ivy/src/main/scala/sbt/ConvertResolver.scala | 445 ++++--- ivy/src/main/scala/sbt/Credentials.scala | 105 +- ivy/src/main/scala/sbt/CrossVersion.scala | 231 ++-- ivy/src/main/scala/sbt/CustomPomParser.scala | 376 +++--- ivy/src/main/scala/sbt/CustomXmlParser.scala | 44 +- ivy/src/main/scala/sbt/DependencyFilter.scala | 103 +- ivy/src/main/scala/sbt/Ivy.scala | 1169 ++++++++--------- ivy/src/main/scala/sbt/IvyActions.scala | 473 ++++--- ivy/src/main/scala/sbt/IvyCache.scala | 165 ++- .../main/scala/sbt/IvyConfigurations.scala | 178 ++- ivy/src/main/scala/sbt/IvyInterface.scala | 34 +- ivy/src/main/scala/sbt/IvyLogger.scala | 87 +- ivy/src/main/scala/sbt/IvyRetrieve.scala | 80 +- ivy/src/main/scala/sbt/IvyScala.scala | 189 ++- ivy/src/main/scala/sbt/IvyUtil.scala | 7 +- ivy/src/main/scala/sbt/MakePom.scala | 645 +++++---- ivy/src/main/scala/sbt/ModuleID.scala | 168 +-- ivy/src/main/scala/sbt/ProjectResolver.scala | 139 +- ivy/src/main/scala/sbt/ResolutionCache.scala | 136 +- ivy/src/main/scala/sbt/Resolver.scala | 492 ++++--- ivy/src/main/scala/sbt/StringUtilities.scala | 16 +- ivy/src/main/scala/sbt/UpdateReport.scala | 228 ++-- .../scala/sbt/impl/DependencyBuilders.scala | 103 +- .../ivyint/ErrorMessageAuthenticator.scala | 117 +- .../sbt/ivyint/IvyCredentialsLookup.scala | 17 +- .../scala/sbt/ivyint/MergeDescriptors.scala | 198 ++- 30 files changed, 3180 insertions(+), 3256 deletions(-) diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/ivy/src/main/scala/sbt/Artifact.scala index 5bd17ef0d..325ef7b6b 100644 --- a/ivy/src/main/scala/sbt/Artifact.scala +++ b/ivy/src/main/scala/sbt/Artifact.scala @@ -6,71 +6,69 @@ package sbt import java.io.File import java.net.URL -final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String,String]) -{ - def extra(attributes: (String,String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) +final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String, String]) { + def extra(attributes: (String, String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) } - import Configurations.{config, Docs, Optional, Pom, Sources, Test} +import Configurations.{ config, Docs, Optional, Pom, Sources, Test } -object Artifact -{ - def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) - def apply(name: String, extra: Map[String,String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) - def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) - def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) - def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) - def apply(name: String, url: URL): Artifact =Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = - Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) +object Artifact { + def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) + def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) + def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) + def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) + def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) + def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = + Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) - val DefaultExtension = "jar" - val DefaultType = "jar" + val DefaultExtension = "jar" + val DefaultType = "jar" - def sources(name: String) = classified(name, SourceClassifier) - def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) + def sources(name: String) = classified(name, SourceClassifier) + def javadoc(name: String) = classified(name, DocClassifier) + def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) - val DocClassifier = "javadoc" - val SourceClassifier = "sources" - val DocType = "doc" - val SourceType = "src" - val PomType = "pom" - val TestsClassifier = "tests" + val DocClassifier = "javadoc" + val SourceClassifier = "sources" + val DocType = "doc" + val SourceType = "src" + val PomType = "pom" + val TestsClassifier = "tests" - def extract(url: URL, default: String): String = extract(url.toString, default) - def extract(name: String, default: String): String = - { - val i = name.lastIndexOf('.') - if(i >= 0) - name.substring(i+1) - else - default - } - def defaultArtifact(file: File) = - { - val name = file.getName - val i = name.lastIndexOf('.') - val base = if(i >= 0) name.substring(0, i) else name - Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) - } - def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = - { - import artifact._ - val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) - val base = CrossVersion.applyCross(artifact.name, cross) - base + "-" + module.revision + classifierStr + "." + artifact.extension - } + def extract(url: URL, default: String): String = extract(url.toString, default) + def extract(name: String, default: String): String = + { + val i = name.lastIndexOf('.') + if (i >= 0) + name.substring(i + 1) + else + default + } + def defaultArtifact(file: File) = + { + val name = file.getName + val i = name.lastIndexOf('.') + val base = if (i >= 0) name.substring(0, i) else name + Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) + } + def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = + { + import artifact._ + val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } + val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) + val base = CrossVersion.applyCross(artifact.name, cross) + base + "-" + module.revision + classifierStr + "." + artifact.extension + } - val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) - val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - def classifierConf(classifier: String): Configuration = - if(classifier.startsWith(TestsClassifier)) - Test - else - classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) - def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) + val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) + val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) + def classifierConf(classifier: String): Configuration = + if (classifier.startsWith(TestsClassifier)) + Test + else + classifierConfMap.getOrElse(classifier, Optional) + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) + def classified(name: String, classifier: String): Artifact = + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) } diff --git a/ivy/src/main/scala/sbt/ComponentManager.scala b/ivy/src/main/scala/sbt/ComponentManager.scala index de87a9890..2d6c5a447 100644 --- a/ivy/src/main/scala/sbt/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/ComponentManager.scala @@ -3,90 +3,87 @@ */ package sbt -import java.io.{File,FileOutputStream} +import java.io.{ File, FileOutputStream } import java.util.concurrent.Callable -/** A component manager provides access to the pieces of xsbt that are distributed as components. -* There are two types of components. The first type is compiled subproject jars with their dependencies. -* The second type is a subproject distributed as a source jar so that it can be compiled against a specific -* version of Scala. -* -* The component manager provides services to install and retrieve components to the local repository. -* This is used for compiled source jars so that the compilation need not be repeated for other projects on the same -* machine. -*/ -class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, ivyHome: Option[File], val log: Logger) -{ - private[this] val ivyCache = new IvyCache(ivyHome) - /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ - def files(id: String)(ifMissing: IfMissing): Iterable[File] = - { - def fromGlobal = - lockGlobalCache { - try { update(id); getOrElse(createAndCache) } - catch { case e: NotInCache => createAndCache } - } - def getOrElse(orElse: => Iterable[File]): Iterable[File] = - { - val existing = provider.component(id) - if(existing.isEmpty) orElse else existing - } - def notFound = invalid("Could not find required component '" + id + "'") - def createAndCache = - ifMissing match { - case IfMissing.Fail => notFound - case d: IfMissing.Define => - d() - if(d.cache) cache(id) - getOrElse(notFound) - } +/** + * A component manager provides access to the pieces of xsbt that are distributed as components. + * There are two types of components. The first type is compiled subproject jars with their dependencies. + * The second type is a subproject distributed as a source jar so that it can be compiled against a specific + * version of Scala. + * + * The component manager provides services to install and retrieve components to the local repository. + * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same + * machine. + */ +class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, ivyHome: Option[File], val log: Logger) { + private[this] val ivyCache = new IvyCache(ivyHome) + /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ + def files(id: String)(ifMissing: IfMissing): Iterable[File] = + { + def fromGlobal = + lockGlobalCache { + try { update(id); getOrElse(createAndCache) } + catch { case e: NotInCache => createAndCache } + } + def getOrElse(orElse: => Iterable[File]): Iterable[File] = + { + val existing = provider.component(id) + if (existing.isEmpty) orElse else existing + } + def notFound = invalid("Could not find required component '" + id + "'") + def createAndCache = + ifMissing match { + case IfMissing.Fail => notFound + case d: IfMissing.Define => + d() + if (d.cache) cache(id) + getOrElse(notFound) + } - lockLocalCache { getOrElse(fromGlobal) } - } - /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ - private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)( action ) - /** This is used to ensure atomic access to components in the global Ivy cache.*/ - private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)( action ) - private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) - /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ - def file(id: String)(ifMissing: IfMissing): File = - files(id)(ifMissing).toList match { - case x :: Nil => x - case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) - } - private def invalid(msg: String) = throw new InvalidComponent(msg) - private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) + lockLocalCache { getOrElse(fromGlobal) } + } + /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ + private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action) + /** This is used to ensure atomic access to components in the global Ivy cache.*/ + private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action) + private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) + /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ + def file(id: String)(ifMissing: IfMissing): File = + files(id)(ifMissing).toList match { + case x :: Nil => x + case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) + } + private def invalid(msg: String) = throw new InvalidComponent(msg) + private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) - def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } - /** Retrieve the file for component 'id' from the local repository. */ - private def update(id: String): Unit = ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar)) ) + def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } + /** Retrieve the file for component 'id' from the local repository. */ + private def update(id: String): Unit = ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar))) - private def sbtModuleID(id: String) = ModuleID(SbtArtifacts.Organization, id, ComponentManager.stampedVersion) - /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ - def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) - def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } + private def sbtModuleID(id: String) = ModuleID(SbtArtifacts.Organization, id, ComponentManager.stampedVersion) + /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ + def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) + def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } } -class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) -{ - def this(msg: String) = this(msg, null) +class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { + def this(msg: String) = this(msg, null) } sealed trait IfMissing extends NotNull -object IfMissing -{ - object Fail extends IfMissing - final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } +object IfMissing { + object Fail extends IfMissing + final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } } -object ComponentManager -{ - lazy val (version, timestamp) = - { - val properties = new java.util.Properties - val propertiesStream = versionResource.openStream - try { properties.load(propertiesStream) } finally { propertiesStream.close() } - (properties.getProperty("version"), properties.getProperty("timestamp")) - } - lazy val stampedVersion = version + "_" + timestamp +object ComponentManager { + lazy val (version, timestamp) = + { + val properties = new java.util.Properties + val propertiesStream = versionResource.openStream + try { properties.load(propertiesStream) } finally { propertiesStream.close() } + (properties.getProperty("version"), properties.getProperty("timestamp")) + } + lazy val stampedVersion = version + "_" + timestamp - import java.net.URL - private def versionResource: URL = getClass.getResource("/xsbt.version.properties") + import java.net.URL + private def versionResource: URL = getClass.getResource("/xsbt.version.properties") } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala index a259f99d7..db4ada450 100644 --- a/ivy/src/main/scala/sbt/Configuration.scala +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -3,63 +3,61 @@ */ package sbt -object Configurations -{ - def config(name: String) = new Configuration(name) - def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) - def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) - def names(cs: Seq[Configuration]) = cs.map(_.name) +object Configurations { + def config(name: String) = new Configuration(name) + def default: Seq[Configuration] = defaultMavenConfigurations + def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) + def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) + def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) + def names(cs: Seq[Configuration]) = cs.map(_.name) - lazy val RuntimeInternal = optionalInternal(Runtime) - lazy val TestInternal = fullInternal(Test) - lazy val IntegrationTestInternal = fullInternal(IntegrationTest) - lazy val CompileInternal = fullInternal(Compile) + lazy val RuntimeInternal = optionalInternal(Runtime) + lazy val TestInternal = fullInternal(Test) + lazy val IntegrationTestInternal = fullInternal(IntegrationTest) + lazy val CompileInternal = fullInternal(Compile) - def internalMap(c: Configuration) = c match { - case Compile => CompileInternal - case Test => TestInternal - case Runtime => RuntimeInternal - case IntegrationTest => IntegrationTestInternal - case _ => c - } + def internalMap(c: Configuration) = c match { + case Compile => CompileInternal + case Test => TestInternal + case Runtime => RuntimeInternal + case IntegrationTest => IntegrationTestInternal + case _ => c + } - def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend(ext : _*) hide; - def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) - def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) + def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend (ext: _*) hide; + def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) + def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) - lazy val Default = config("default") - lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend(Runtime) - lazy val Provided = config("provided") ; - lazy val Docs = config("docs") - lazy val Runtime = config("runtime") extend(Compile) - lazy val Test = config("test") extend(Runtime) - lazy val Sources = config("sources") - lazy val System = config("system") - lazy val Optional = config("optional") - lazy val Pom = config("pom") + lazy val Default = config("default") + lazy val Compile = config("compile") + lazy val IntegrationTest = config("it") extend (Runtime) + lazy val Provided = config("provided"); + lazy val Docs = config("docs") + lazy val Runtime = config("runtime") extend (Compile) + lazy val Test = config("test") extend (Runtime) + lazy val Sources = config("sources") + lazy val System = config("system") + lazy val Optional = config("optional") + lazy val Pom = config("pom") - lazy val ScalaTool = config("scala-tool") hide - lazy val CompilerPlugin = config("plugin") hide + lazy val ScalaTool = config("scala-tool") hide + lazy val CompilerPlugin = config("plugin") hide - private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) - private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) - private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration - private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if(mavenStyle) Configurations.Compile else Configurations.Default - private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) + private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) + private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) + private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration + private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default + private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } /** Represents an Ivy configuration. */ -final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) -{ - require(name != null && !name.isEmpty) - require(description != null) - def this(name: String) = this(name, "", true, Nil, true) - def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) - def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) - def notTransitive = intransitive - def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) - def hide = Configuration(name, description, false, extendsConfigs, transitive) - override def toString = name +final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) { + require(name != null && !name.isEmpty) + require(description != null) + def this(name: String) = this(name, "", true, Nil, true) + def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) + def notTransitive = intransitive + def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) + def hide = Configuration(name, description, false, extendsConfigs, transitive) + override def toString = name } diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 51c69e988..7c5c9a918 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -1,80 +1,74 @@ package sbt - import DependencyFilter._ +import DependencyFilter._ -final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) -{ - @deprecated("`filter` is no longer used", "0.13.0") - val filter: ModuleFilter = (_: ModuleID) => false - @deprecated("`group` is no longer used", "0.13.0") - val group: ModuleID => String = ConflictWarning.org +final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) { + @deprecated("`filter` is no longer used", "0.13.0") + val filter: ModuleFilter = (_: ModuleID) => false + @deprecated("`group` is no longer used", "0.13.0") + val group: ModuleID => String = ConflictWarning.org } -object ConflictWarning -{ - @deprecated("`group` and `filter` are no longer used. Use a standard Ivy conflict manager.", "0.13.0") - def apply(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean): ConflictWarning = - ConflictWarning(label, level, failOnConflict) +object ConflictWarning { + @deprecated("`group` and `filter` are no longer used. Use a standard Ivy conflict manager.", "0.13.0") + def apply(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean): ConflictWarning = + ConflictWarning(label, level, failOnConflict) - def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) + def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) - private def org = (_: ModuleID).organization - private[this] def idString(org: String, name: String) = s"$org:$name" + private def org = (_: ModuleID).organization + private[this] def idString(org: String, name: String) = s"$org:$name" - def default(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) + def default(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - @deprecated("Warning on evicted modules is no longer done, so this is the same as `default`. Use a standard Ivy conflict manager.", "0.13.0") - def strict(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) + @deprecated("Warning on evicted modules is no longer done, so this is the same as `default`. Use a standard Ivy conflict manager.", "0.13.0") + def strict(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - def apply(config: ConflictWarning, report: UpdateReport, log: Logger) - { - processCrossVersioned(config, report, log) - } - private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) - { - val crossMismatches = crossVersionMismatches(report) - if(!crossMismatches.isEmpty) - { - val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " - val conflictMsgs = - for( ((org,rawName), fullNames) <- crossMismatches ) yield - { - val suffixes = fullNames.map(getCrossSuffix).mkString(", ") - s"${idString(org,rawName)} $suffixes" - } - log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) - if(config.failOnConflict) { - val summary = crossMismatches.map{ case ((org,raw),_) => idString(org,raw)}.mkString(", ") - sys.error("Conflicting cross-version suffixes in: " + summary) - } - } - } + def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { + processCrossVersioned(config, report, log) + } + private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) { + val crossMismatches = crossVersionMismatches(report) + if (!crossMismatches.isEmpty) { + val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " + val conflictMsgs = + for (((org, rawName), fullNames) <- crossMismatches) yield { + val suffixes = fullNames.map(getCrossSuffix).mkString(", ") + s"${idString(org, rawName)} $suffixes" + } + log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) + if (config.failOnConflict) { + val summary = crossMismatches.map { case ((org, raw), _) => idString(org, raw) }.mkString(", ") + sys.error("Conflicting cross-version suffixes in: " + summary) + } + } + } - /** Map from (organization, rawName) to set of multiple full names. */ - def crossVersionMismatches(report: UpdateReport): Map[(String,String), Set[String]] = - { - val mismatches = report.configurations.flatMap { confReport => - groupByRawName(confReport.allModules).mapValues { modules => - val differentFullNames = modules.map(_.name).toSet - if(differentFullNames.size > 1) differentFullNames else Set.empty[String] - } - } - (Map.empty[(String,String),Set[String]] /: mismatches)(merge) - } - private[this] def merge[A,B](m: Map[A, Set[B]], b: (A, Set[B])): Map[A, Set[B]] = - if(b._2.isEmpty) m else - m.updated(b._1, m.getOrElse(b._1, Set.empty) ++ b._2) + /** Map from (organization, rawName) to set of multiple full names. */ + def crossVersionMismatches(report: UpdateReport): Map[(String, String), Set[String]] = + { + val mismatches = report.configurations.flatMap { confReport => + groupByRawName(confReport.allModules).mapValues { modules => + val differentFullNames = modules.map(_.name).toSet + if (differentFullNames.size > 1) differentFullNames else Set.empty[String] + } + } + (Map.empty[(String, String), Set[String]] /: mismatches)(merge) + } + private[this] def merge[A, B](m: Map[A, Set[B]], b: (A, Set[B])): Map[A, Set[B]] = + if (b._2.isEmpty) m else + m.updated(b._1, m.getOrElse(b._1, Set.empty) ++ b._2) - private[this] def groupByRawName(ms: Seq[ModuleID]): Map[(String,String), Seq[ModuleID]] = - ms.groupBy(m => (m.organization, dropCrossSuffix(m.name))) + private[this] def groupByRawName(ms: Seq[ModuleID]): Map[(String, String), Seq[ModuleID]] = + ms.groupBy(m => (m.organization, dropCrossSuffix(m.name))) - private[this] val CrossSuffixPattern = """(.+)_(\d+\.\d+(?:\.\d+)?(?:-.+)?)""".r - private[this] def dropCrossSuffix(s: String): String = s match { - case CrossSuffixPattern(raw, _) => raw - case _ => s - } - private[this] def getCrossSuffix(s: String): String = s match { - case CrossSuffixPattern(_, v) => "_" + v - case _ => "" - } + private[this] val CrossSuffixPattern = """(.+)_(\d+\.\d+(?:\.\d+)?(?:-.+)?)""".r + private[this] def dropCrossSuffix(s: String): String = s match { + case CrossSuffixPattern(raw, _) => raw + case _ => s + } + private[this] def getCrossSuffix(s: String): String = s match { + case CrossSuffixPattern(_, v) => "_" + v + case _ => "" + } } diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 74c5c119c..613de970e 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -5,239 +5,234 @@ package sbt import java.net.URL import java.util.Collections -import org.apache.ivy.{core,plugins} +import org.apache.ivy.{ core, plugins } import core.module.id.ModuleRevisionId import core.module.descriptor.DependencyDescriptor import core.resolve.ResolveData import core.settings.IvySettings -import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver} -import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} -import plugins.repository.url.{URLRepository => URLRepo} -import plugins.repository.file.{FileRepository => FileRepo, FileResource} +import plugins.resolver.{ BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver } +import plugins.resolver.{ AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver } +import plugins.repository.url.{ URLRepository => URLRepo } +import plugins.repository.file.{ FileRepository => FileRepo, FileResource } import java.io.File import org.apache.ivy.util.ChecksumHelper -import org.apache.ivy.core.module.descriptor.{Artifact=>IArtifact} +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } - -private object ConvertResolver -{ - /** This class contains all the reflective lookups used in the - * checksum-friendly URL publishing shim. - */ - private object ChecksumFriendlyURLResolver { - // TODO - When we dump JDK6 support we can remove this hackery - // import java.lang.reflect.AccessibleObject - type AccessibleObject = { - def setAccessible(value: Boolean): Unit - } - private def reflectiveLookup[A <: AccessibleObject](f: Class[_] => A): Option[A] = - try { - val cls = classOf[RepositoryResolver] - val thing = f(cls) - import scala.language.reflectiveCalls - thing.setAccessible(true) - Some(thing) - } catch { - case (_: java.lang.NoSuchFieldException) | - (_: java.lang.SecurityException) | - (_: java.lang.NoSuchMethodException) => None - } - private val signerNameField: Option[java.lang.reflect.Field] = - reflectiveLookup(_.getDeclaredField("signerName")) - private val putChecksumMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod("putChecksum", - classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean], classOf[String])) - private val putSignatureMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod("putSignature", - classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean])) - } - /** - * The default behavior of ivy's overwrite flags ignores the fact that a lot of repositories - * will autogenerate checksums *for* an artifact if it doesn't already exist. Therefore - * if we succeed in publishing an artifact, we need to just blast the checksums in place. - * This acts as a "shim" on RepositoryResolvers so that we can hook our methods into - * both the IBiblioResolver + URLResolver without having to duplicate the code in two - * places. However, this does mean our use of reflection is awesome. - * - * TODO - See about contributing back to ivy. - */ - private trait ChecksumFriendlyURLResolver extends RepositoryResolver { - import ChecksumFriendlyURLResolver._ - private def signerName: String = signerNameField match { - case Some(field) => field.get(this).asInstanceOf[String] - case None => null - } - override protected def put(artifact: IArtifact, src: File, dest: String, overwrite: Boolean): Unit = { - // verify the checksum algorithms before uploading artifacts! - val checksums = getChecksumAlgorithms() - val repository = getRepository() - for { - checksum <- checksums - if !ChecksumHelper.isKnownAlgorithm(checksum) - } throw new IllegalArgumentException("Unknown checksum algorithm: " + checksum) - repository.put(artifact, src, dest, overwrite); - // Fix for sbt#1156 - Artifactory will auto-generate MD5/sha1 files, so - // we need to overwrite what it has. - for (checksum <- checksums) { - putChecksumMethod match { - case Some(method) => method.invoke(this, artifact, src, dest, true: java.lang.Boolean, checksum) - case None => // TODO - issue warning? - } - } - if (signerName != null) { - putSignatureMethod match { - case None => () - case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) - } - } +private object ConvertResolver { + /** + * This class contains all the reflective lookups used in the + * checksum-friendly URL publishing shim. + */ + private object ChecksumFriendlyURLResolver { + // TODO - When we dump JDK6 support we can remove this hackery + // import java.lang.reflect.AccessibleObject + type AccessibleObject = { + def setAccessible(value: Boolean): Unit } - } + private def reflectiveLookup[A <: AccessibleObject](f: Class[_] => A): Option[A] = + try { + val cls = classOf[RepositoryResolver] + val thing = f(cls) + import scala.language.reflectiveCalls + thing.setAccessible(true) + Some(thing) + } catch { + case (_: java.lang.NoSuchFieldException) | + (_: java.lang.SecurityException) | + (_: java.lang.NoSuchMethodException) => None + } + private val signerNameField: Option[java.lang.reflect.Field] = + reflectiveLookup(_.getDeclaredField("signerName")) + private val putChecksumMethod: Option[java.lang.reflect.Method] = + reflectiveLookup(_.getDeclaredMethod("putChecksum", + classOf[IArtifact], classOf[File], classOf[String], + classOf[Boolean], classOf[String])) + private val putSignatureMethod: Option[java.lang.reflect.Method] = + reflectiveLookup(_.getDeclaredMethod("putSignature", + classOf[IArtifact], classOf[File], classOf[String], + classOf[Boolean])) + } + /** + * The default behavior of ivy's overwrite flags ignores the fact that a lot of repositories + * will autogenerate checksums *for* an artifact if it doesn't already exist. Therefore + * if we succeed in publishing an artifact, we need to just blast the checksums in place. + * This acts as a "shim" on RepositoryResolvers so that we can hook our methods into + * both the IBiblioResolver + URLResolver without having to duplicate the code in two + * places. However, this does mean our use of reflection is awesome. + * + * TODO - See about contributing back to ivy. + */ + private trait ChecksumFriendlyURLResolver extends RepositoryResolver { + import ChecksumFriendlyURLResolver._ + private def signerName: String = signerNameField match { + case Some(field) => field.get(this).asInstanceOf[String] + case None => null + } + override protected def put(artifact: IArtifact, src: File, dest: String, overwrite: Boolean): Unit = { + // verify the checksum algorithms before uploading artifacts! + val checksums = getChecksumAlgorithms() + val repository = getRepository() + for { + checksum <- checksums + if !ChecksumHelper.isKnownAlgorithm(checksum) + } throw new IllegalArgumentException("Unknown checksum algorithm: " + checksum) + repository.put(artifact, src, dest, overwrite); + // Fix for sbt#1156 - Artifactory will auto-generate MD5/sha1 files, so + // we need to overwrite what it has. + for (checksum <- checksums) { + putChecksumMethod match { + case Some(method) => method.invoke(this, artifact, src, dest, true: java.lang.Boolean, checksum) + case None => // TODO - issue warning? + } + } + if (signerName != null) { + putSignatureMethod match { + case None => () + case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) + } + } + } + } - /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver, settings: IvySettings, log: Logger) = - { - r match - { - case repo: MavenRepository => - { - val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns() { // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - } - val resolver = new PluginCapableResolver - resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver - } - case r: JavaNet1Repository => - { - // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: - // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html - val resolver = new IBiblioResolver with DescriptorRequired { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } - initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") - resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") - resolver - } - case repo: SshRepository => - { - val resolver = new SshResolver with DescriptorRequired - initializeSSHResolver(resolver, repo, settings) - repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - resolver - } - case repo: SftpRepository => - { - val resolver = new SFTPResolver - initializeSSHResolver(resolver, repo, settings) - resolver - } - case repo: FileRepository => - { - val resolver = new FileSystemResolver with DescriptorRequired { - // Workaround for #1156 - // Temporarily in sbt 0.13.x we deprecate overwriting - // in local files for non-changing revisions. - // This will be fully enforced in sbt 1.0. - setRepository(new WarnOnOverwriteFileRepo()) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - import repo.configuration.{isLocal, isTransactional} - resolver.setLocal(isLocal) - isTransactional.foreach(value => resolver.setTransactional(value.toString)) - resolver - } - case repo: URLRepository => - { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - resolver - } - case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) - case repo: RawRepository => repo.resolver - } - } - - private sealed trait DescriptorRequired extends BasicResolver - { - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = - { - val prev = descriptorString(isAllownomd) - setDescriptor(descriptorString(hasExplicitURL(dd))) - try super.getDependency(dd, data) finally setDescriptor(prev) - } - def descriptorString(optional: Boolean) = - if(optional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED - def hasExplicitURL(dd: DependencyDescriptor): Boolean = - dd.getAllDependencyArtifacts.exists(_.getUrl != null) - } - private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) - { - resolver.setName(name) - resolver.setM2compatible(true) - resolver.setRoot(root) - } - private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings) - { - resolver.setName(repo.name) - resolver.setPassfile(null) - initializePatterns(resolver, repo.patterns, settings) - initializeConnection(resolver, repo.connection) - } - private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection) - { - import resolver._ - import connection._ - hostname.foreach(setHost) - port.foreach(setPort) - authentication foreach - { - case RepositoryHelpers.PasswordAuthentication(user, password) => - setUser(user) - password.foreach(setUserPassword) - case RepositoryHelpers.KeyFileAuthentication(user, file, password) => - setKeyFile(file) - password.foreach(setKeyFilePassword) - setUser(user) - } - } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings) - { - resolver.setM2compatible(patterns.isMavenCompatible) - resolver.setDescriptor(if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED) - resolver.setCheckconsistency(!patterns.skipConsistencyCheck) - patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) - patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) - } - /** A custom Ivy URLRepository that returns FileResources for file URLs. - * This allows using the artifacts from the Maven local repository instead of copying them to the Ivy cache. */ - private[this] final class LocalIfFileRepo extends URLRepo { - private[this] val repo = new WarnOnOverwriteFileRepo() - override def getResource(source: String) = { - val url = new URL(source) - if(url.getProtocol == IO.FileScheme) - new FileResource(repo, IO.toFile(url)) - else - super.getResource(source) - } - } + /** Converts the given sbt resolver into an Ivy resolver..*/ + def apply(r: Resolver, settings: IvySettings, log: Logger) = + { + r match { + case repo: MavenRepository => + { + val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) + final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + def setPatterns() { // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + } + val resolver = new PluginCapableResolver + resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver + } + case r: JavaNet1Repository => + { + // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: + // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html + val resolver = new IBiblioResolver with DescriptorRequired { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } + initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") + resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") + resolver + } + case repo: SshRepository => + { + val resolver = new SshResolver with DescriptorRequired + initializeSSHResolver(resolver, repo, settings) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver + } + case repo: SftpRepository => + { + val resolver = new SFTPResolver + initializeSSHResolver(resolver, repo, settings) + resolver + } + case repo: FileRepository => + { + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + import repo.configuration.{ isLocal, isTransactional } + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => + { + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + resolver + } + case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) + case repo: RawRepository => repo.resolver + } + } - private[this] final class WarnOnOverwriteFileRepo extends FileRepo() { - override def put(source: java.io.File, destination: String, overwrite: Boolean): Unit = { - try super.put(source, destination, overwrite) - catch { - case e: java.io.IOException if e.getMessage.contains("destination already exists") => - import org.apache.ivy.util.Message - Message.warn(s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0.") - super.put(source, destination, true) - } - } - } + private sealed trait DescriptorRequired extends BasicResolver { + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = + { + val prev = descriptorString(isAllownomd) + setDescriptor(descriptorString(hasExplicitURL(dd))) + try super.getDependency(dd, data) finally setDescriptor(prev) + } + def descriptorString(optional: Boolean) = + if (optional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED + def hasExplicitURL(dd: DependencyDescriptor): Boolean = + dd.getAllDependencyArtifacts.exists(_.getUrl != null) + } + private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) { + resolver.setName(name) + resolver.setM2compatible(true) + resolver.setRoot(root) + } + private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings) { + resolver.setName(repo.name) + resolver.setPassfile(null) + initializePatterns(resolver, repo.patterns, settings) + initializeConnection(resolver, repo.connection) + } + private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection) { + import resolver._ + import connection._ + hostname.foreach(setHost) + port.foreach(setPort) + authentication foreach + { + case RepositoryHelpers.PasswordAuthentication(user, password) => + setUser(user) + password.foreach(setUserPassword) + case RepositoryHelpers.KeyFileAuthentication(user, file, password) => + setKeyFile(file) + password.foreach(setKeyFilePassword) + setUser(user) + } + } + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings) { + resolver.setM2compatible(patterns.isMavenCompatible) + resolver.setDescriptor(if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED) + resolver.setCheckconsistency(!patterns.skipConsistencyCheck) + patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) + patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) + } + /** + * A custom Ivy URLRepository that returns FileResources for file URLs. + * This allows using the artifacts from the Maven local repository instead of copying them to the Ivy cache. + */ + private[this] final class LocalIfFileRepo extends URLRepo { + private[this] val repo = new WarnOnOverwriteFileRepo() + override def getResource(source: String) = { + val url = new URL(source) + if (url.getProtocol == IO.FileScheme) + new FileResource(repo, IO.toFile(url)) + else + super.getResource(source) + } + } + + private[this] final class WarnOnOverwriteFileRepo extends FileRepo() { + override def put(source: java.io.File, destination: String, overwrite: Boolean): Unit = { + try super.put(source, destination, overwrite) + catch { + case e: java.io.IOException if e.getMessage.contains("destination already exists") => + import org.apache.ivy.util.Message + Message.warn(s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0.") + super.put(source, destination, true) + } + } + } } diff --git a/ivy/src/main/scala/sbt/Credentials.scala b/ivy/src/main/scala/sbt/Credentials.scala index 882e1c22b..fd6a85538 100644 --- a/ivy/src/main/scala/sbt/Credentials.scala +++ b/ivy/src/main/scala/sbt/Credentials.scala @@ -6,71 +6,66 @@ package sbt import java.io.File import org.apache.ivy.util.url.CredentialsStore -object Credentials -{ - def apply(realm: String, host: String, userName: String, passwd: String): Credentials = - new DirectCredentials(realm, host, userName, passwd) - def apply(file: File): Credentials = - new FileCredentials(file) +object Credentials { + def apply(realm: String, host: String, userName: String, passwd: String): Credentials = + new DirectCredentials(realm, host, userName, passwd) + def apply(file: File): Credentials = + new FileCredentials(file) - /** Add the provided credentials to Ivy's credentials cache.*/ - def add(realm: String, host: String, userName: String, passwd: String): Unit = - CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) - /** Load credentials from the given file into Ivy's credentials cache.*/ - def add(path: File, log: Logger): Unit = - loadCredentials(path) match - { - case Left(err) => log.warn(err) - case Right(dc) => add(dc.realm, dc.host, dc.userName, dc.passwd) - } + /** Add the provided credentials to Ivy's credentials cache.*/ + def add(realm: String, host: String, userName: String, passwd: String): Unit = + CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) + /** Load credentials from the given file into Ivy's credentials cache.*/ + def add(path: File, log: Logger): Unit = + loadCredentials(path) match { + case Left(err) => log.warn(err) + case Right(dc) => add(dc.realm, dc.host, dc.userName, dc.passwd) + } - def forHost(sc: Seq[Credentials], host: String) = allDirect(sc) find { _.host == host } - def allDirect(sc: Seq[Credentials]): Seq[DirectCredentials] = sc map toDirect - def toDirect(c: Credentials): DirectCredentials = c match { - case dc: DirectCredentials => dc - case fc: FileCredentials => loadCredentials(fc.path) match { - case Left(err) => error(err) - case Right(dc) => dc - } - } + def forHost(sc: Seq[Credentials], host: String) = allDirect(sc) find { _.host == host } + def allDirect(sc: Seq[Credentials]): Seq[DirectCredentials] = sc map toDirect + def toDirect(c: Credentials): DirectCredentials = c match { + case dc: DirectCredentials => dc + case fc: FileCredentials => loadCredentials(fc.path) match { + case Left(err) => error(err) + case Right(dc) => dc + } + } - def loadCredentials(path: File): Either[String, DirectCredentials] = - if(path.exists) - { - val properties = read(path) - def get(keys: List[String]) = keys.flatMap(properties.get).headOption.toRight(keys.head + " not specified in credentials file: " + path) + def loadCredentials(path: File): Either[String, DirectCredentials] = + if (path.exists) { + val properties = read(path) + def get(keys: List[String]) = keys.flatMap(properties.get).headOption.toRight(keys.head + " not specified in credentials file: " + path) - IvyUtil.separate( List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get) ) match - { - case (Nil, List(realm, host, user, pass)) => Right( new DirectCredentials(realm, host, user, pass) ) - case (errors, _) => Left(errors.mkString("\n")) - } - } - else - Left("Credentials file " + path + " does not exist") + IvyUtil.separate(List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get)) match { + case (Nil, List(realm, host, user, pass)) => Right(new DirectCredentials(realm, host, user, pass)) + case (errors, _) => Left(errors.mkString("\n")) + } + } else + Left("Credentials file " + path + " does not exist") - def register(cs: Seq[Credentials], log: Logger): Unit = - cs foreach { - case f: FileCredentials => add(f.path, log) - case d: DirectCredentials => add(d.realm, d.host, d.userName, d.passwd) - } + def register(cs: Seq[Credentials], log: Logger): Unit = + cs foreach { + case f: FileCredentials => add(f.path, log) + case d: DirectCredentials => add(d.realm, d.host, d.userName, d.passwd) + } - private[this] val RealmKeys = List("realm") - private[this] val HostKeys = List("host", "hostname") - private[this] val UserKeys = List("user", "user.name", "username") - private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") + private[this] val RealmKeys = List("realm") + private[this] val HostKeys = List("host", "hostname") + private[this] val UserKeys = List("user", "user.name", "username") + private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") - import collection.JavaConversions._ - private[this] def read(from: File): Map[String,String] = - { - val properties = new java.util.Properties - IO.load(properties, from) - properties map { case (k,v) => (k.toString, v.toString.trim) } toMap; - } + import collection.JavaConversions._ + private[this] def read(from: File): Map[String, String] = + { + val properties = new java.util.Properties + IO.load(properties, from) + properties map { case (k, v) => (k.toString, v.toString.trim) } toMap; + } } sealed trait Credentials final class FileCredentials(val path: File) extends Credentials { - override def toString = "FileCredentials('" + path + "')" + override def toString = "FileCredentials('" + path + "')" } final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 3425bb1f5..79dfe091e 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -7,142 +7,159 @@ final case class ScalaVersion(full: String, binary: String) /** Configures how a module will be cross-versioned. */ sealed trait CrossVersion -object CrossVersion -{ - /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ - val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion +object CrossVersion { + /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ + val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion - /** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */ - val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion + /** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */ + val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion - /** Disables cross versioning for a module.*/ - object Disabled extends CrossVersion { override def toString = "disabled" } + /** Disables cross versioning for a module.*/ + object Disabled extends CrossVersion { override def toString = "disabled" } - /** Cross-versions a module using the result of applying `remapVersion` to the binary version. - * For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10", - * the module is cross-versioned with "2.10". */ - final class Binary(val remapVersion: String => String) extends CrossVersion { - override def toString = "Binary" - } + /** + * Cross-versions a module using the result of applying `remapVersion` to the binary version. + * For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10", + * the module is cross-versioned with "2.10". + */ + final class Binary(val remapVersion: String => String) extends CrossVersion { + override def toString = "Binary" + } - /** Cross-versions a module with the result of applying `remapVersion` to the full version. - * For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3", - * the module is cross-versioned with "2.10". */ - final class Full(val remapVersion: String => String) extends CrossVersion { - override def toString = "Full" - } + /** + * Cross-versions a module with the result of applying `remapVersion` to the full version. + * For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3", + * the module is cross-versioned with "2.10". + */ + final class Full(val remapVersion: String => String) extends CrossVersion { + override def toString = "Full" + } - /** Cross-versions a module with the full version (typically the full Scala version). */ - def full: CrossVersion = new Full(idFun) + /** Cross-versions a module with the full version (typically the full Scala version). */ + def full: CrossVersion = new Full(idFun) - /** Cross-versions a module with the result of applying `remapVersion` to the full version - * (typically the full Scala version). See also [[sbt.CrossVersion.Full]]. */ - def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + /** + * Cross-versions a module with the result of applying `remapVersion` to the full version + * (typically the full Scala version). See also [[sbt.CrossVersion.Full]]. + */ + def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) - /** Cross-versions a module with the binary version (typically the binary Scala version). */ - def binary: CrossVersion = new Binary(idFun) + /** Cross-versions a module with the binary version (typically the binary Scala version). */ + def binary: CrossVersion = new Binary(idFun) - /** Cross-versions a module with the result of applying `remapVersion` to the binary version - * (typically the binary Scala version). See also [[sbt.CrossVersion.Binary]]. */ - def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) + /** + * Cross-versions a module with the result of applying `remapVersion` to the binary version + * (typically the binary Scala version). See also [[sbt.CrossVersion.Binary]]. + */ + def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) - private[this] def idFun[T]: T => T = x => x + private[this] def idFun[T]: T => T = x => x - @deprecated("Will be made private.", "0.13.1") - def append(s: String): Option[String => String] = Some(x => crossName(x, s)) + @deprecated("Will be made private.", "0.13.1") + def append(s: String): Option[String => String] = Some(x => crossName(x, s)) - /** Construct a cross-versioning function given cross-versioning configuration `cross`, - * full version `fullVersion` and binary version `binaryVersion`. The behavior of the - * constructed function is as documented for the [[sbt.CrossVersion]] datatypes. */ - def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = - cross match - { - case Disabled => None - case b: Binary => append(b.remapVersion(binaryVersion)) - case f: Full => append(f.remapVersion(fullVersion)) - } + /** + * Construct a cross-versioning function given cross-versioning configuration `cross`, + * full version `fullVersion` and binary version `binaryVersion`. The behavior of the + * constructed function is as documented for the [[sbt.CrossVersion]] datatypes. + */ + def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = + cross match { + case Disabled => None + case b: Binary => append(b.remapVersion(binaryVersion)) + case f: Full => append(f.remapVersion(fullVersion)) + } - /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ - def apply(module: ModuleID, is: IvyScala): Option[String => String] = - CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ + def apply(module: ModuleID, is: IvyScala): Option[String => String] = + CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) - /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ - def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = - is flatMap { i => apply(module, i) } + /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ + def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = + is flatMap { i => apply(module, i) } - /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ - def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = - cross match { - case None => artifacts - case Some(is) => substituteCrossA(artifacts, cross) - } + /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ + def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + cross match { + case None => artifacts + case Some(is) => substituteCrossA(artifacts, cross) + } - @deprecated("Will be made private.", "0.13.1") - def applyCross(s: String, fopt: Option[String => String]): String = - fopt match { - case None => s - case Some(fopt) => fopt(s) - } + @deprecated("Will be made private.", "0.13.1") + def applyCross(s: String, fopt: Option[String => String]): String = + fopt match { + case None => s + case Some(fopt) => fopt(s) + } - @deprecated("Will be made private.", "0.13.1") - def crossName(name: String, cross: String): String = - name + "_" + cross + @deprecated("Will be made private.", "0.13.1") + def crossName(name: String, cross: String): String = + name + "_" + cross - /** Cross-versions `a` according to cross-version function `cross`. */ - def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = - a.copy(name = applyCross(a.name, cross)) + /** Cross-versions `a` according to cross-version function `cross`. */ + def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = + a.copy(name = applyCross(a.name, cross)) - @deprecated("Will be made private.", "0.13.1") - def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = - as.map(art => substituteCross(art, cross)) + @deprecated("Will be made private.", "0.13.1") + def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + as.map(art => substituteCross(art, cross)) - /** Constructs a function that will cross-version a ModuleID - * for the given full and binary Scala versions `scalaFullVersion` and `scalaBinaryVersion` - * according to the ModuleID's cross-versioning setting. */ - def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => - { - val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) - if(cross.isDefined) - m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) - else - m - } + /** + * Constructs a function that will cross-version a ModuleID + * for the given full and binary Scala versions `scalaFullVersion` and `scalaBinaryVersion` + * according to the ModuleID's cross-versioning setting. + */ + def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => + { + val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) + if (cross.isDefined) + m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + else + m + } - @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") - def isStable(v: String): Boolean = isScalaApiCompatible(v) + @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") + def isStable(v: String): Boolean = isScalaApiCompatible(v) - @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def selectVersion(full: String, binary: String): String = if(isStable(full)) binary else full + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") + def selectVersion(full: String, binary: String): String = if (isStable(full)) binary else full - def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) + def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) - /** Returns sbt binary interface x.y API compatible with the given version string v. - * RCs for x.y.0 are considered API compatible. - * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). - */ - def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) + /** + * Returns sbt binary interface x.y API compatible with the given version string v. + * RCs for x.y.0 are considered API compatible. + * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + */ + def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) - def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) + def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) - /** Returns Scala binary interface x.y API compatible with the given version string v. - * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) + /** + * Returns Scala binary interface x.y API compatible with the given version string v. + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + */ + def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) - /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ - val PartialVersion = CrossVersionUtil.PartialVersion + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ + val PartialVersion = CrossVersionUtil.PartialVersion - /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ - def partialVersion(s: String): Option[(Int,Int)] = CrossVersionUtil.partialVersion(s) + /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ + def partialVersion(s: String): Option[(Int, Int)] = CrossVersionUtil.partialVersion(s) - /** Computes the binary Scala version from the `full` version. - * Full Scala versions earlier than [[sbt.CrossVersion.TransitionScalaVersion]] are returned as is. */ - def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) + /** + * Computes the binary Scala version from the `full` version. + * Full Scala versions earlier than [[sbt.CrossVersion.TransitionScalaVersion]] are returned as is. + */ + def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) - /** Computes the binary sbt version from the `full` version. - * Full sbt versions earlier than [[sbt.CrossVersion.TransitionSbtVersion]] are returned as is. */ - def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) + /** + * Computes the binary sbt version from the `full` version. + * Full sbt versions earlier than [[sbt.CrossVersion.TransitionSbtVersion]] are returned as is. + */ + def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) - @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) + @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") + def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) } diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 871c1f07c..12ae48675 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -1,224 +1,222 @@ package sbt - import org.apache.ivy.{core, plugins, util} - import core.module.id.ModuleRevisionId - import core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} - import core.module.descriptor.{DefaultDependencyDescriptor, DependencyDescriptor} - import plugins.parser.{m2, ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} - import m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} - import plugins.repository.Resource - import plugins.namespace.NamespaceTransformer - import util.extendable.ExtendableItem +import org.apache.ivy.{ core, plugins, util } +import core.module.id.ModuleRevisionId +import core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } +import core.module.descriptor.{ DefaultDependencyDescriptor, DependencyDescriptor } +import plugins.parser.{ m2, ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings } +import m2.{ PomModuleDescriptorBuilder, PomModuleDescriptorParser } +import plugins.repository.Resource +import plugins.namespace.NamespaceTransformer +import util.extendable.ExtendableItem - import java.io.{File, InputStream} - import java.net.URL - import java.util.regex.Pattern +import java.io.{ File, InputStream } +import java.net.URL +import java.util.regex.Pattern -final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser -{ - override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = - transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) - - override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, res: Resource, validate: Boolean) = - transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, res, validate)) - - override def toIvyFile(is: InputStream, res: Resource, destFile: File, md: ModuleDescriptor) = delegate.toIvyFile(is, res, destFile, md) +final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { + override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = + transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) - override def accept(res: Resource) = delegate.accept(res) - override def getType() = delegate.getType() - override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) + override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, res: Resource, validate: Boolean) = + transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, res, validate)) + + override def toIvyFile(is: InputStream, res: Resource, destFile: File, md: ModuleDescriptor) = delegate.toIvyFile(is, res, destFile, md) + + override def accept(res: Resource) = delegate.accept(res) + override def getType() = delegate.getType() + override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) } -object CustomPomParser -{ - /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ - val InfoKeyPrefix = "info." - val ApiURLKey = "info.apiURL" +object CustomPomParser { + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ + val InfoKeyPrefix = "info." + val ApiURLKey = "info.apiURL" - val SbtVersionKey = "sbtVersion" - val ScalaVersionKey = "scalaVersion" - val ExtraAttributesKey = "extraDependencyAttributes" - private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) + val SbtVersionKey = "sbtVersion" + val ScalaVersionKey = "scalaVersion" + val ExtraAttributesKey = "extraDependencyAttributes" + private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) - // packagings that should be jars, but that Ivy doesn't handle as jars - val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") - val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) + // packagings that should be jars, but that Ivy doesn't handle as jars + val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") + val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) - private[this] val TransformedHashKey = "e:sbtTransformHash" - // A hash of the parameters transformation is based on. - // If a descriptor has a different hash, we need to retransform it. - private[this] val TransformHash: String = hash((unqualifiedKeys ++ JarPackagings).toSeq.sorted) - private[this] def hash(ss: Seq[String]): String = Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) + private[this] val TransformedHashKey = "e:sbtTransformHash" + // A hash of the parameters transformation is based on. + // If a descriptor has a different hash, we need to retransform it. + private[this] val TransformHash: String = hash((unqualifiedKeys ++ JarPackagings).toSeq.sorted) + private[this] def hash(ss: Seq[String]): String = Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) - // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. - lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) + // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. + lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) - def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - if(transformedByThisVersion(md)) md else defaultTransformImpl(parser, md) + def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + if (transformedByThisVersion(md)) md else defaultTransformImpl(parser, md) - private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = - { - val oldTransformedHashKey = "sbtTransformHash" - val extraInfo = md.getExtraInfo - // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both - Option(extraInfo).isDefined && - ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { - case Some(TransformHash) => true - case _ => false - }) - } + private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = + { + val oldTransformedHashKey = "sbtTransformHash" + val extraInfo = md.getExtraInfo + // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both + Option(extraInfo).isDefined && + ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + case Some(TransformHash) => true + case _ => false + }) + } - private[this] def defaultTransformImpl(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - { - val properties = getPomProperties(md) + private[this] def defaultTransformImpl(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + { + val properties = getPomProperties(md) - // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. - // These are attached to the module itself. - val filtered = shouldBeUnqualified(properties) + // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. + // These are attached to the module itself. + val filtered = shouldBeUnqualified(properties) - // Extracts extra attributes for the dependencies. - // Because the tag in pom.xml cannot include additional metadata, - // sbt includes extra attributes in a 'extraDependencyAttributes' property. - // This is read/written from/to a pure string (no element structure) because Ivy only - // parses the immediate text nodes of the property. - val extraDepAttributes = getDependencyExtra(filtered) + // Extracts extra attributes for the dependencies. + // Because the tag in pom.xml cannot include additional metadata, + // sbt includes extra attributes in a 'extraDependencyAttributes' property. + // This is read/written from/to a pure string (no element structure) because Ivy only + // parses the immediate text nodes of the property. + val extraDepAttributes = getDependencyExtra(filtered) - // Fixes up the detected extension in some cases missed by Ivy. - val convertArtifacts = artifactExtIncorrect(md) + // Fixes up the detected extension in some cases missed by Ivy. + val convertArtifacts = artifactExtIncorrect(md) - // Merges artifact sections for duplicate dependency definitions - val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) + // Merges artifact sections for duplicate dependency definitions + val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) - val unqualify = toUnqualify(filtered) - if(unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts && !mergeDuplicates) - md - else - addExtra(unqualify, extraDepAttributes, parser, md) - } - // The element of the pom is used to store additional metadata, such as for sbt plugins or for the base URL for API docs. - // This is done because the pom XSD does not appear to allow extra metadata anywhere else. - // The extra sbt plugin metadata in pom.xml does not need to be readable by maven, but the other information may be. - // However, the pom.xml needs to be valid in all cases because other tools like repository managers may read the pom.xml. - private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String,String] = - { - import collection.JavaConverters._ - PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String,String]].asScala.toMap - } - private[sbt] def toUnqualify(propertyAttributes: Map[String, String]): Map[String, String] = - (propertyAttributes - ExtraAttributesKey) map { case (k,v) => ("e:" + k, v) } + val unqualify = toUnqualify(filtered) + if (unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts && !mergeDuplicates) + md + else + addExtra(unqualify, extraDepAttributes, parser, md) + } + // The element of the pom is used to store additional metadata, such as for sbt plugins or for the base URL for API docs. + // This is done because the pom XSD does not appear to allow extra metadata anywhere else. + // The extra sbt plugin metadata in pom.xml does not need to be readable by maven, but the other information may be. + // However, the pom.xml needs to be valid in all cases because other tools like repository managers may read the pom.xml. + private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String, String] = + { + import collection.JavaConverters._ + PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String, String]].asScala.toMap + } + private[sbt] def toUnqualify(propertyAttributes: Map[String, String]): Map[String, String] = + (propertyAttributes - ExtraAttributesKey) map { case (k, v) => ("e:" + k, v) } - private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = - md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) - private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) - - private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = - if(properties.isEmpty) id else addExtra(properties, id) - private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = - { - import collection.JavaConverters._ - val oldExtra = qualifiedExtra(id) - val newExtra = (oldExtra ++ properties).asJava - ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, newExtra) - } + private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = + md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) + private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) - private[this] def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String,String]] = - (m get ExtraAttributesKey) match { - case None => Map.empty - case Some(str) => - def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include=true)) - readDependencyExtra(str).map(processDep).toMap - } + private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = + if (properties.isEmpty) id else addExtra(properties, id) + private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = + { + import collection.JavaConverters._ + val oldExtra = qualifiedExtra(id) + val newExtra = (oldExtra ++ properties).asJava + ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, newExtra) + } - def qualifiedExtra(item: ExtendableItem): Map[String,String] = - { - import collection.JavaConverters._ - item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala.toMap - } - def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String,String] = - (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) + private[this] def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String, String]] = + (m get ExtraAttributesKey) match { + case None => Map.empty + case Some(str) => + def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include = true)) + readDependencyExtra(str).map(processDep).toMap + } - def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = - s.flatMap { dd => - val revId = dd.getDependencyRevisionId - if(filterCustomExtra(revId, include=true).isEmpty) - Nil - else - revId.encodeToString :: Nil - } + def qualifiedExtra(item: ExtendableItem): Map[String, String] = + { + import collection.JavaConverters._ + item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap + } + def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = + (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) - // parses the sequence of dependencies with extra attribute information, with one dependency per line - def readDependencyExtra(s: String): Seq[ModuleRevisionId] = - LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) + def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = + s.flatMap { dd => + val revId = dd.getDependencyRevisionId + if (filterCustomExtra(revId, include = true).isEmpty) + Nil + else + revId.encodeToString :: Nil + } - private[this] val LinesP = Pattern.compile("(?m)^") + // parses the sequence of dependencies with extra attribute information, with one dependency per line + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = + LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) - def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) + private[this] val LinesP = Pattern.compile("(?m)^") - // Reduces the id to exclude custom extra attributes - // This makes the id suitable as a key to associate a dependency parsed from a element - // with the extra attributes from the section - def simplify(id: ModuleRevisionId): ModuleRevisionId = - { - import collection.JavaConverters._ - ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include=false).asJava) - } + def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) - private[this] def addExtra(dep: DependencyDescriptor, extra: Map[ModuleRevisionId, Map[String, String]]): DependencyDescriptor = - { - val extras = if(extra.isEmpty) None else extra get simplify(dep.getDependencyRevisionId) - extras match { - case None => dep - case Some(extraAttrs) => transform(dep, revId => addExtra(extraAttrs, revId)) - } - } - private[this] def transform(dep: DependencyDescriptor, f: ModuleRevisionId => ModuleRevisionId): DependencyDescriptor = - DefaultDependencyDescriptor.transformInstance(dep, namespaceTransformer(dep.getDependencyRevisionId, f), false) - private[this] def extraTransformer(txId: ModuleRevisionId, extra: Map[String, String]): NamespaceTransformer = - namespaceTransformer(txId, revId => addExtra(extra, revId) ) + // Reduces the id to exclude custom extra attributes + // This makes the id suitable as a key to associate a dependency parsed from a element + // with the extra attributes from the section + def simplify(id: ModuleRevisionId): ModuleRevisionId = + { + import collection.JavaConverters._ + ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include = false).asJava) + } - private[this] def namespaceTransformer(txId: ModuleRevisionId, f: ModuleRevisionId => ModuleRevisionId): NamespaceTransformer = - new NamespaceTransformer { - def transform(revId: ModuleRevisionId): ModuleRevisionId = if(revId == txId) f(revId) else revId - def isIdentity = false - } + private[this] def addExtra(dep: DependencyDescriptor, extra: Map[ModuleRevisionId, Map[String, String]]): DependencyDescriptor = + { + val extras = if (extra.isEmpty) None else extra get simplify(dep.getDependencyRevisionId) + extras match { + case None => dep + case Some(extraAttrs) => transform(dep, revId => addExtra(extraAttrs, revId)) + } + } + private[this] def transform(dep: DependencyDescriptor, f: ModuleRevisionId => ModuleRevisionId): DependencyDescriptor = + DefaultDependencyDescriptor.transformInstance(dep, namespaceTransformer(dep.getDependencyRevisionId, f), false) + private[this] def extraTransformer(txId: ModuleRevisionId, extra: Map[String, String]): NamespaceTransformer = + namespaceTransformer(txId, revId => addExtra(extra, revId)) - import collection.JavaConverters._ - def addExtra(properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String,String]], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - { - val dmd = new DefaultModuleDescriptor(parser, md.getResource) + private[this] def namespaceTransformer(txId: ModuleRevisionId, f: ModuleRevisionId => ModuleRevisionId): NamespaceTransformer = + new NamespaceTransformer { + def transform(revId: ModuleRevisionId): ModuleRevisionId = if (revId == txId) f(revId) else revId + def isIdentity = false + } - val mrid = addExtra(properties, md.getModuleRevisionId) - val resolvedMrid = addExtra(properties, md.getResolvedModuleRevisionId) - dmd.setModuleRevisionId(mrid) - dmd.setResolvedModuleRevisionId(resolvedMrid) + import collection.JavaConverters._ + def addExtra(properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String, String]], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = + { + val dmd = new DefaultModuleDescriptor(parser, md.getResource) - dmd.setDefault(md.isDefault) - dmd.setHomePage(md.getHomePage) - dmd.setDescription(md.getDescription) - dmd.setLastModified(md.getLastModified) - dmd.setStatus(md.getStatus()) - dmd.setPublicationDate(md.getPublicationDate()) - dmd.setResolvedPublicationDate(md.getResolvedPublicationDate()) + val mrid = addExtra(properties, md.getModuleRevisionId) + val resolvedMrid = addExtra(properties, md.getResolvedModuleRevisionId) + dmd.setModuleRevisionId(mrid) + dmd.setResolvedModuleRevisionId(resolvedMrid) - for(l <- md.getLicenses) dmd.addLicense(l) - for( (key,value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, TransformHash) // mark as transformed by this version, so we don't need to do it again - for( (key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String,String]].asScala ) dmd.addExtraAttributeNamespace(key, value) - IvySbt.addExtraNamespace(dmd) + dmd.setDefault(md.isDefault) + dmd.setHomePage(md.getHomePage) + dmd.setDescription(md.getDescription) + dmd.setLastModified(md.getLastModified) + dmd.setStatus(md.getStatus()) + dmd.setPublicationDate(md.getPublicationDate()) + dmd.setResolvedPublicationDate(md.getResolvedPublicationDate()) - val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } - val unique = IvySbt.mergeDuplicateDefinitions(withExtra) - unique foreach dmd.addDependency + for (l <- md.getLicenses) dmd.addLicense(l) + for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) + dmd.addExtraInfo(TransformedHashKey, TransformHash) // mark as transformed by this version, so we don't need to do it again + for ((key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraAttributeNamespace(key, value) + IvySbt.addExtraNamespace(dmd) - for( ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor( new DefaultExtendsDescriptor( md, ed.getLocation, ed.getExtendsTypes) ) - for( conf <- md.getConfigurations) { - dmd.addConfiguration(conf) - for(art <- md.getArtifacts(conf.getName)) { - val ext = art.getExt - val newExt = if( JarPackagings(ext) ) "jar" else ext - val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, newExt, art.getUrl, art.getQualifiedExtraAttributes) - dmd.addArtifact(conf.getName, nart) - } - } - dmd - } + val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } + val unique = IvySbt.mergeDuplicateDefinitions(withExtra) + unique foreach dmd.addDependency + + for (ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor(new DefaultExtendsDescriptor(md, ed.getLocation, ed.getExtendsTypes)) + for (conf <- md.getConfigurations) { + dmd.addConfiguration(conf) + for (art <- md.getArtifacts(conf.getName)) { + val ext = art.getExt + val newExt = if (JarPackagings(ext)) "jar" else ext + val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, newExt, art.getUrl, art.getQualifiedExtraAttributes) + dmd.addArtifact(conf.getName, nart) + } + } + dmd + } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/CustomXmlParser.scala b/ivy/src/main/scala/sbt/CustomXmlParser.scala index da44743f6..0afa87fbd 100644 --- a/ivy/src/main/scala/sbt/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/CustomXmlParser.scala @@ -6,33 +6,31 @@ package sbt import java.io.ByteArrayInputStream import java.net.URL -import org.apache.ivy.{core, plugins} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor} +import org.apache.ivy.{ core, plugins } +import core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor } import core.settings.IvySettings import plugins.parser.xml.XmlModuleDescriptorParser import plugins.repository.Resource import plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ -private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser -{ - import XmlModuleDescriptorParser.Parser - class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) - { - def setSource(url: URL) = - { - super.setResource(new URLResource(url)) - super.setInput(url) - } - def setInput(bytes: Array[Byte]) { setInput(new ByteArrayInputStream(bytes)) } - /** Overridden because the super implementation overwrites the module descriptor.*/ - override def setResource(res: Resource) {} - override def setMd(md: DefaultModuleDescriptor) = - { - super.setMd(md) - if(defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") - } - override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) - override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) - } +private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { + import XmlModuleDescriptorParser.Parser + class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) { + def setSource(url: URL) = + { + super.setResource(new URLResource(url)) + super.setInput(url) + } + def setInput(bytes: Array[Byte]) { setInput(new ByteArrayInputStream(bytes)) } + /** Overridden because the super implementation overwrites the module descriptor.*/ + override def setResource(res: Resource) {} + override def setMd(md: DefaultModuleDescriptor) = + { + super.setMd(md) + if (defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") + } + override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) + override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) + } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/DependencyFilter.scala b/ivy/src/main/scala/sbt/DependencyFilter.scala index e31cd4e24..fee8da46c 100644 --- a/ivy/src/main/scala/sbt/DependencyFilter.scala +++ b/ivy/src/main/scala/sbt/DependencyFilter.scala @@ -3,65 +3,58 @@ */ package sbt -trait DependencyFilterExtra -{ - def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = - new ModuleFilter { - def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) - } - def artifactFilter(name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, extension: NameFilter = AllPassFilter, classifier: NameFilter = AllPassFilter): ArtifactFilter = - new ArtifactFilter { - def apply(a: Artifact): Boolean = name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier.accept(a.classifier getOrElse "") - } - def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = - new ConfigurationFilter { - def apply(c: String): Boolean = name.accept(c) - } +trait DependencyFilterExtra { + def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = + new ModuleFilter { + def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) + } + def artifactFilter(name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, extension: NameFilter = AllPassFilter, classifier: NameFilter = AllPassFilter): ArtifactFilter = + new ArtifactFilter { + def apply(a: Artifact): Boolean = name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier.accept(a.classifier getOrElse "") + } + def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = + new ConfigurationFilter { + def apply(c: String): Boolean = name.accept(c) + } } -object DependencyFilter extends DependencyFilterExtra -{ - def make(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): DependencyFilter = - new DependencyFilter { - def apply(c: String, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a) - } - def apply(x: DependencyFilter, y: DependencyFilter, combine: (Boolean, Boolean) => Boolean): DependencyFilter = - new DependencyFilter { - def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) - } - def allPass: DependencyFilter = configurationFilter() - implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) } - implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } - implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) } - implicit def subDepFilterToFn[Arg](f: SubDepFilter[Arg, _]): Arg => Boolean = f apply _ +object DependencyFilter extends DependencyFilterExtra { + def make(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): DependencyFilter = + new DependencyFilter { + def apply(c: String, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a) + } + def apply(x: DependencyFilter, y: DependencyFilter, combine: (Boolean, Boolean) => Boolean): DependencyFilter = + new DependencyFilter { + def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) + } + def allPass: DependencyFilter = configurationFilter() + implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) } + implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } + implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) } + implicit def subDepFilterToFn[Arg](f: SubDepFilter[Arg, _]): Arg => Boolean = f apply _ } -trait DependencyFilter -{ - def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean - final def &&(o: DependencyFilter) = DependencyFilter(this, o, _ && _) - final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _) - final def -- (o: DependencyFilter) = DependencyFilter(this, o, _ && !_) +trait DependencyFilter { + def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean + final def &&(o: DependencyFilter) = DependencyFilter(this, o, _ && _) + final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _) + final def --(o: DependencyFilter) = DependencyFilter(this, o, _ && !_) } -sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter -{ self: Self => - def apply(a: Arg): Boolean - protected def make(f: Arg => Boolean): Self - final def &(o: Self): Self = combine(o, _ && _) - final def |(o: Self): Self = combine(o, _ || _) - final def -(o: Self): Self = combine(o, _ && !_) - private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = make( (m: Arg) => f(this(m), o(m)) ) +sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter { self: Self => + def apply(a: Arg): Boolean + protected def make(f: Arg => Boolean): Self + final def &(o: Self): Self = combine(o, _ && _) + final def |(o: Self): Self = combine(o, _ || _) + final def -(o: Self): Self = combine(o, _ && !_) + private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = make((m: Arg) => f(this(m), o(m))) } -trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter] -{ - protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(module) +trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter] { + protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(module) } -trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] -{ - protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(artifact) +trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] { + protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(artifact) } -trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] -{ - protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) +trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] { + protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index a6519c6bc..be029c422 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -8,636 +8,617 @@ import Resolver.PluginPattern import java.io.File import java.net.URI import java.util.concurrent.Callable -import java.util.{Collection, Collections => CS} +import java.util.{ Collection, Collections => CS } import CS.singleton -import org.apache.ivy.{core, plugins, util, Ivy} -import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter} -import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} -import core.module.descriptor.{OverrideDependencyDescriptorMediator} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} +import org.apache.ivy.{ core, plugins, util, Ivy } +import core.{ IvyPatternHelper, LogOptions } +import core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } +import core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } +import core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } +import core.module.descriptor.{ OverrideDependencyDescriptorMediator } +import core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } +import core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision } import core.settings.IvySettings import plugins.latest.LatestRevisionStrategy import plugins.matcher.PatternMatcher import plugins.parser.m2.PomModuleDescriptorParser -import plugins.resolver.{ChainResolver, DependencyResolver} -import util.{Message, MessageLogger} +import plugins.resolver.{ ChainResolver, DependencyResolver } +import util.{ Message, MessageLogger } import util.extendable.ExtendableItem -import scala.xml.{NodeSeq, Text} +import scala.xml.{ NodeSeq, Text } -final class IvySbt(val configuration: IvyConfiguration) -{ - import configuration.baseDirectory +final class IvySbt(val configuration: IvyConfiguration) { + import configuration.baseDirectory - /** ========== Configuration/Setup ============ - * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. - * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, - * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). - */ - private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = - { - def action() = - IvySbt.synchronized - { - val originalLogger = Message.getDefaultLogger - Message.setDefaultLogger(logger) - try { f } - finally { Message.setDefaultLogger(originalLogger) } - } - // Ivy is not thread-safe nor can the cache be used concurrently. - // If provided a GlobalLock, we can use that to ensure safe access to the cache. - // Otherwise, we can at least synchronize within the JVM. - // For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe. - configuration.lock match - { - case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) - case None => action() - } - } - private lazy val settings: IvySettings = - { - val is = new IvySettings - is.setBaseDir(baseDirectory) - CustomPomParser.registerDefault - configuration match - { - case e: ExternalIvyConfiguration => - IvySbt.addResolvers(e.extraResolvers, is, configuration.log) - IvySbt.loadURI(is, e.uri) - case i: InlineIvyConfiguration => - is.setVariable("ivy.checksums", i.checksums mkString ",") - i.paths.ivyHome foreach is.setDefaultIvyUserDir - IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) - IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) - IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) - } - is - } - private lazy val ivy: Ivy = - { - val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine } - i.setSettings(settings) - i.bind() - i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) - i - } - // Must be the same file as is used in Update in the launcher - private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") - /** ========== End Configuration/Setup ============*/ + /** + * ========== Configuration/Setup ============ + * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. + * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, + * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). + */ + private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = + { + def action() = + IvySbt.synchronized { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(logger) + try { f } + finally { Message.setDefaultLogger(originalLogger) } + } + // Ivy is not thread-safe nor can the cache be used concurrently. + // If provided a GlobalLock, we can use that to ensure safe access to the cache. + // Otherwise, we can at least synchronize within the JVM. + // For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe. + configuration.lock match { + case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) + case None => action() + } + } + private lazy val settings: IvySettings = + { + val is = new IvySettings + is.setBaseDir(baseDirectory) + CustomPomParser.registerDefault + configuration match { + case e: ExternalIvyConfiguration => + IvySbt.addResolvers(e.extraResolvers, is, configuration.log) + IvySbt.loadURI(is, e.uri) + case i: InlineIvyConfiguration => + is.setVariable("ivy.checksums", i.checksums mkString ",") + i.paths.ivyHome foreach is.setDefaultIvyUserDir + IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) + IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) + } + is + } + private lazy val ivy: Ivy = + { + val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine } + i.setSettings(settings) + i.bind() + i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) + i + } + // Must be the same file as is used in Update in the launcher + private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") + /** ========== End Configuration/Setup ============*/ - /** Uses the configured Ivy instance within a safe context.*/ - def withIvy[T](log: Logger)(f: Ivy => T): T = - withIvy(new IvyLoggerInterface(log))(f) + /** Uses the configured Ivy instance within a safe context.*/ + def withIvy[T](log: Logger)(f: Ivy => T): T = + withIvy(new IvyLoggerInterface(log))(f) - def withIvy[T](log: MessageLogger)(f: Ivy => T): T = - withDefaultLogger(log) - { - // See #429 - We always insert a helper authenticator here which lets us get more useful authentication errors. - ivyint.ErrorMessageAuthenticator.install() - ivy.pushContext() - ivy.getLoggerEngine.pushLogger(log) - try { f(ivy) } - finally { - ivy.getLoggerEngine.popLogger() - ivy.popContext() - } - } + def withIvy[T](log: MessageLogger)(f: Ivy => T): T = + withDefaultLogger(log) { + // See #429 - We always insert a helper authenticator here which lets us get more useful authentication errors. + ivyint.ErrorMessageAuthenticator.install() + ivy.pushContext() + ivy.getLoggerEngine.pushLogger(log) + try { f(ivy) } + finally { + ivy.getLoggerEngine.popLogger() + ivy.popContext() + } + } - final class Module(rawModuleSettings: ModuleSettings) - { - val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) - def owner = IvySbt.this - def withModule[T](log: Logger)(f: (Ivy,DefaultModuleDescriptor,String) => T): T = - withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } + final class Module(rawModuleSettings: ModuleSettings) { + val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) + def owner = IvySbt.this + def withModule[T](log: Logger)(f: (Ivy, DefaultModuleDescriptor, String) => T): T = + withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } - def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_,md,_) => md) - def dependencyMapping(log: Logger): (ModuleRevisionId, ModuleDescriptor) = - { - val md = moduleDescriptor(log) - (md.getModuleRevisionId, md) - } - def defaultConfig(log: Logger): String = withModule(log)( (_,_,dc) => dc) - // these should only be referenced by withModule because lazy vals synchronize on this object - // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock - private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = - { - val (baseModule, baseConfiguration) = - moduleSettings match - { - case ic: InlineConfiguration => configureInline(ic, configuration.log) - case ec: EmptyConfiguration => configureEmpty(ec) - case pc: PomConfiguration => configurePom(pc) - case ifc: IvyFileConfiguration => configureIvyFile(ifc) - } - moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) - IvySbt.addExtraNamespace(baseModule) - (baseModule, baseConfiguration) - } - private def configureInline(ic: InlineConfiguration, log: Logger) = - { - import ic._ - val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) - IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) - val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) - log.debug("Using inline dependencies specified in Scala" + (if(ivyXML.isEmpty) "." else " and XML.")) + def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_, md, _) => md) + def dependencyMapping(log: Logger): (ModuleRevisionId, ModuleDescriptor) = + { + val md = moduleDescriptor(log) + (md.getModuleRevisionId, md) + } + def defaultConfig(log: Logger): String = withModule(log)((_, _, dc) => dc) + // these should only be referenced by withModule because lazy vals synchronize on this object + // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock + private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = + { + val (baseModule, baseConfiguration) = + moduleSettings match { + case ic: InlineConfiguration => configureInline(ic, configuration.log) + case ec: EmptyConfiguration => configureEmpty(ec) + case pc: PomConfiguration => configurePom(pc) + case ifc: IvyFileConfiguration => configureIvyFile(ifc) + } + moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) + IvySbt.addExtraNamespace(baseModule) + (baseModule, baseConfiguration) + } + private def configureInline(ic: InlineConfiguration, log: Logger) = + { + import ic._ + val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) + IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) + val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) + log.debug("Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." else " and XML.")) - val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) - IvySbt.addMainArtifact(moduleID) - IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) - val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) - IvySbt.addDependencies(moduleID, transformedDeps, parser) - (moduleID, parser.getDefaultConf) - } - private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = - { - val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) - mod.setLastModified(System.currentTimeMillis) - mod.setDescription(moduleInfo.description) - moduleInfo.homepage foreach { h => mod.setHomePage(h.toString) } - moduleInfo.licenses foreach { l => mod.addLicense(new License(l._1, l._2.toString)) } - IvySbt.addConfigurations(mod, configurations) - IvySbt.addArtifacts(mod, module.explicitArtifacts) - mod - } + val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) + IvySbt.addMainArtifact(moduleID) + IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) + val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) + IvySbt.addDependencies(moduleID, transformedDeps, parser) + (moduleID, parser.getDefaultConf) + } + private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = + { + val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) + mod.setLastModified(System.currentTimeMillis) + mod.setDescription(moduleInfo.description) + moduleInfo.homepage foreach { h => mod.setHomePage(h.toString) } + moduleInfo.licenses foreach { l => mod.addLicense(new License(l._1, l._2.toString)) } + IvySbt.addConfigurations(mod, configurations) + IvySbt.addArtifacts(mod, module.explicitArtifacts) + mod + } - /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ - private def configurePom(pc: PomConfiguration) = - { - val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) - val dmd = IvySbt.toDefaultModuleDescriptor(md) - IvySbt.addConfigurations(dmd, Configurations.defaultInternal) - val defaultConf = Configurations.DefaultMavenConfiguration.name - for( is <- pc.ivyScala) if(pc.autoScalaTools) { - val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) - confParser.setMd(dmd) - addScalaToolDependencies(dmd, confParser, is) - } - (dmd, defaultConf) - } - /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ - private def configureIvyFile(ifc: IvyFileConfiguration) = - { - val parser = new CustomXmlParser.CustomParser(settings, None) - parser.setValidate(ifc.validate) - parser.setSource(toURL(ifc.file)) - parser.parse() - val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) - for( is <- ifc.ivyScala ) if(ifc.autoScalaTools) - addScalaToolDependencies(dmd, parser, is) - (dmd, parser.getDefaultConf) - } - private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala) { - IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) - IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) - } - private def toURL(file: File) = file.toURI.toURL - private def configureEmpty(ec: EmptyConfiguration) = - { - val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION - val mod = newConfiguredModuleID(ec.module, ec.moduleInfo, Seq(Configurations.Default)) - IvySbt.addMainArtifact(mod) - (mod, defaultConf) - } - } + /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ + private def configurePom(pc: PomConfiguration) = + { + val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) + val dmd = IvySbt.toDefaultModuleDescriptor(md) + IvySbt.addConfigurations(dmd, Configurations.defaultInternal) + val defaultConf = Configurations.DefaultMavenConfiguration.name + for (is <- pc.ivyScala) if (pc.autoScalaTools) { + val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) + confParser.setMd(dmd) + addScalaToolDependencies(dmd, confParser, is) + } + (dmd, defaultConf) + } + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ + private def configureIvyFile(ifc: IvyFileConfiguration) = + { + val parser = new CustomXmlParser.CustomParser(settings, None) + parser.setValidate(ifc.validate) + parser.setSource(toURL(ifc.file)) + parser.parse() + val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) + for (is <- ifc.ivyScala) if (ifc.autoScalaTools) + addScalaToolDependencies(dmd, parser, is) + (dmd, parser.getDefaultConf) + } + private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala) { + IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) + IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) + } + private def toURL(file: File) = file.toURI.toURL + private def configureEmpty(ec: EmptyConfiguration) = + { + val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION + val mod = newConfiguredModuleID(ec.module, ec.moduleInfo, Seq(Configurations.Default)) + IvySbt.addMainArtifact(mod) + (mod, defaultConf) + } + } } -private object IvySbt -{ - val DefaultIvyConfigFilename = "ivysettings.xml" - val DefaultIvyFilename = "ivy.xml" - val DefaultMavenFilename = "pom.xml" - val DefaultChecksums = Seq("sha1", "md5") +private object IvySbt { + val DefaultIvyConfigFilename = "ivysettings.xml" + val DefaultIvyFilename = "ivy.xml" + val DefaultMavenFilename = "pom.xml" + val DefaultChecksums = Seq("sha1", "md5") - def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) - def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) - def defaultPOM(project: File) = new File(project, DefaultMavenFilename) + def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) + def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) + def defaultPOM(project: File) = new File(project, DefaultMavenFilename) - def loadURI(is: IvySettings, uri: URI) - { - if(uri.getScheme == "file") - is.load(new File(uri)) // IVY-1114 - else - is.load(uri.toURL) - } + def loadURI(is: IvySettings, uri: URI) { + if (uri.getScheme == "file") + is.load(new File(uri)) // IVY-1114 + else + is.load(uri.toURL) + } - /** Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. - * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: Logger) - { - def makeChain(label: String, name: String, rs: Seq[Resolver]) = { - log.debug(label + " repositories:") - val chain = resolverChain(name, rs, localOnly, settings, log) - settings.addResolver(chain) - chain - } - val otherChain = makeChain("Other", "sbt-other", other) - val mainChain = makeChain("Default", "sbt-chain", resolvers) - settings.setDefaultResolver(mainChain.getName) - } - def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = - { - val newDefault = new ChainResolver { - // Technically, this should be applied to module configurations. - // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). - // It would be better to get proper support into Ivy. - // A workaround is to configure the ModuleConfiguration resolver to be a ChainResolver. - // - // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. - // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" - // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly - // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive. - // - // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the - // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. - override def locate(artifact: IArtifact) = if(hasImplicitClassifier(artifact)) null else super.locate(artifact) + /** + * Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. + * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. + */ + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: Logger) { + def makeChain(label: String, name: String, rs: Seq[Resolver]) = { + log.debug(label + " repositories:") + val chain = resolverChain(name, rs, localOnly, settings, log) + settings.addResolver(chain) + chain + } + val otherChain = makeChain("Other", "sbt-other", other) + val mainChain = makeChain("Default", "sbt-chain", resolvers) + settings.setDefaultResolver(mainChain.getName) + } + def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = + { + val newDefault = new ChainResolver { + // Technically, this should be applied to module configurations. + // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). + // It would be better to get proper support into Ivy. + // A workaround is to configure the ModuleConfiguration resolver to be a ChainResolver. + // + // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. + // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" + // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly + // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive. + // + // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the + // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. + override def locate(artifact: IArtifact) = if (hasImplicitClassifier(artifact)) null else super.locate(artifact) - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = - { - if(data.getOptions.getLog != LogOptions.LOG_QUIET) - Message.info("Resolving " + dd.getDependencyRevisionId + " ...") - val gd = super.getDependency(dd, data) - resetArtifactResolver(gd) - } - } - newDefault.setName(name) - newDefault.setReturnFirst(true) - newDefault.setCheckmodified(false) - for(sbtResolver <- resolvers) { - log.debug("\t" + sbtResolver) - newDefault.add(ConvertResolver(sbtResolver, settings, log)) - } - newDefault - } - def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger) - { - for(r <- resolvers) { - log.debug("\t" + r) - settings.addResolver(ConvertResolver(r, settings, log)) - } - } - /** A hack to detect if the given artifact is an automatically generated request for a classifier, - * as opposed to a user-initiated declaration. It relies on Ivy prefixing classifier with m:, while sbt uses e:. - * Clearly, it would be better to have an explicit option in Ivy to control this.*/ - def hasImplicitClassifier(artifact: IArtifact): Boolean = - { - import collection.JavaConversions._ - artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") - } - private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger) - { - val existing = settings.getResolverNames - for(moduleConf <- moduleConfigurations) - { - import moduleConf._ - import IvyPatternHelper._ - import PatternMatcher._ - if(!existing.contains(resolver.name)) - settings.addResolver(ConvertResolver(resolver, settings, log)) - val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) - settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) - } - } - private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) - { - configureResolutionCache(settings, localOnly, resCacheDir) - configureRepositoryCache(settings, localOnly) - } - private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) - { - val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir - settings.setResolutionCacheManager(new ResolutionCache(base, settings)) - } - // set the artifact resolver to be the main resolver. - // this is because sometimes the artifact resolver saved in the cache is not correct - // the common case is for resolved.getArtifactResolver to be inter-project from a different project's publish-local - // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver - // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver - // This also fixes #760, which occurs when metadata exists in a repository, but the artifact doesn't. - private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = - if(resolved eq null) - null - else { - val desc = resolved.getDescriptor - val updatedDescriptor = CustomPomParser.defaultTransform(desc.getParser, desc) - new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, updatedDescriptor, resolved.getReport, resolved.isForce) - } + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = + { + if (data.getOptions.getLog != LogOptions.LOG_QUIET) + Message.info("Resolving " + dd.getDependencyRevisionId + " ...") + val gd = super.getDependency(dd, data) + resetArtifactResolver(gd) + } + } + newDefault.setName(name) + newDefault.setReturnFirst(true) + newDefault.setCheckmodified(false) + for (sbtResolver <- resolvers) { + log.debug("\t" + sbtResolver) + newDefault.add(ConvertResolver(sbtResolver, settings, log)) + } + newDefault + } + def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger) { + for (r <- resolvers) { + log.debug("\t" + r) + settings.addResolver(ConvertResolver(r, settings, log)) + } + } + /** + * A hack to detect if the given artifact is an automatically generated request for a classifier, + * as opposed to a user-initiated declaration. It relies on Ivy prefixing classifier with m:, while sbt uses e:. + * Clearly, it would be better to have an explicit option in Ivy to control this. + */ + def hasImplicitClassifier(artifact: IArtifact): Boolean = + { + import collection.JavaConversions._ + artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") + } + private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger) { + val existing = settings.getResolverNames + for (moduleConf <- moduleConfigurations) { + import moduleConf._ + import IvyPatternHelper._ + import PatternMatcher._ + if (!existing.contains(resolver.name)) + settings.addResolver(ConvertResolver(resolver, settings, log)) + val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) + settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) + } + } + private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { + configureResolutionCache(settings, localOnly, resCacheDir) + configureRepositoryCache(settings, localOnly) + } + private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { + val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir + settings.setResolutionCacheManager(new ResolutionCache(base, settings)) + } + // set the artifact resolver to be the main resolver. + // this is because sometimes the artifact resolver saved in the cache is not correct + // the common case is for resolved.getArtifactResolver to be inter-project from a different project's publish-local + // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver + // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver + // This also fixes #760, which occurs when metadata exists in a repository, but the artifact doesn't. + private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = + if (resolved eq null) + null + else { + val desc = resolved.getDescriptor + val updatedDescriptor = CustomPomParser.defaultTransform(desc.getParser, desc) + new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, updatedDescriptor, resolved.getReport, resolved.isForce) + } - private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) //, artifactResolver: DependencyResolver) - { - val cacheDir = settings.getDefaultRepositoryCacheBasedir() - val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { - override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { - // ignore and reset the resolver- not ideal, but avoids thrashing. - val resolved = resetArtifactResolver(super.findModuleInCache(dd,revId,options,null)) - // invalidate the cache if the artifact was removed from the local repository - if(resolved == null) null - else if(isProjectResolver(resolved.getResolver)) { - resolved.getReport.getLocalFile.delete() - null - } else { - val origin = resolved.getReport.getArtifactOrigin - if(!origin.isLocal) resolved - else { - val file = new File(origin.getLocation) - if(file == null || file.exists) resolved - else { - resolved.getReport.getLocalFile.delete() - null - } - } - } - } - private[this] def isProjectResolver(r: DependencyResolver): Boolean = r match { - case pr: ProjectResolver => true - case _ => false - } - // ignore the original resolver wherever possible to avoid issues like #704 - override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} - } - manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) - manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) - manager.setIvyPattern(PluginPattern + manager.getIvyPattern) - manager.setUseOrigin(true) - if(localOnly) - manager.setDefaultTTL(java.lang.Long.MAX_VALUE) - else - { - manager.setChangingMatcher(PatternMatcher.REGEXP) - manager.setChangingPattern(".*-SNAPSHOT") - } - settings.addRepositoryCacheManager(manager) - settings.setDefaultRepositoryCacheManager(manager) - } - def toIvyConfiguration(configuration: Configuration) = - { - import org.apache.ivy.core.module.descriptor.{Configuration => IvyConfig} - import IvyConfig.Visibility._ - import configuration._ - new IvyConfig(name, if(isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) - } - def addExtraNamespace(dmd: DefaultModuleDescriptor): Unit = - dmd.addExtraAttributeNamespace("e", "http://ant.apache.org/ivy/extra") + private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) //, artifactResolver: DependencyResolver) + { + val cacheDir = settings.getDefaultRepositoryCacheBasedir() + val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { + override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { + // ignore and reset the resolver- not ideal, but avoids thrashing. + val resolved = resetArtifactResolver(super.findModuleInCache(dd, revId, options, null)) + // invalidate the cache if the artifact was removed from the local repository + if (resolved == null) null + else if (isProjectResolver(resolved.getResolver)) { + resolved.getReport.getLocalFile.delete() + null + } else { + val origin = resolved.getReport.getArtifactOrigin + if (!origin.isLocal) resolved + else { + val file = new File(origin.getLocation) + if (file == null || file.exists) resolved + else { + resolved.getReport.getLocalFile.delete() + null + } + } + } + } + private[this] def isProjectResolver(r: DependencyResolver): Boolean = r match { + case pr: ProjectResolver => true + case _ => false + } + // ignore the original resolver wherever possible to avoid issues like #704 + override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} + } + manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) + manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) + manager.setIvyPattern(PluginPattern + manager.getIvyPattern) + manager.setUseOrigin(true) + if (localOnly) + manager.setDefaultTTL(java.lang.Long.MAX_VALUE) + else { + manager.setChangingMatcher(PatternMatcher.REGEXP) + manager.setChangingPattern(".*-SNAPSHOT") + } + settings.addRepositoryCacheManager(manager) + settings.setDefaultRepositoryCacheManager(manager) + } + def toIvyConfiguration(configuration: Configuration) = + { + import org.apache.ivy.core.module.descriptor.{ Configuration => IvyConfig } + import IvyConfig.Visibility._ + import configuration._ + new IvyConfig(name, if (isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) + } + def addExtraNamespace(dmd: DefaultModuleDescriptor): Unit = + dmd.addExtraAttributeNamespace("e", "http://ant.apache.org/ivy/extra") - /** Adds the ivy.xml main artifact. */ - private def addMainArtifact(moduleID: DefaultModuleDescriptor) - { - val artifact = DefaultArtifact.newIvyArtifact(moduleID.getResolvedModuleRevisionId, moduleID.getPublicationDate) - moduleID.setModuleArtifact(artifact) - moduleID.check() - } - private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings) - { - val mid = ModuleId.newInstance(conflict.organization, conflict.module) - val matcher = is.getMatcher(PatternMatcher.EXACT_OR_REGEXP) - val manager = is.getConflictManager(conflict.name) - moduleID.addConflictManager(mid, matcher, manager) - } + /** Adds the ivy.xml main artifact. */ + private def addMainArtifact(moduleID: DefaultModuleDescriptor) { + val artifact = DefaultArtifact.newIvyArtifact(moduleID.getResolvedModuleRevisionId, moduleID.getPublicationDate) + moduleID.setModuleArtifact(artifact) + moduleID.check() + } + private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings) { + val mid = ModuleId.newInstance(conflict.organization, conflict.module) + val matcher = is.getMatcher(PatternMatcher.EXACT_OR_REGEXP) + val manager = is.getConflictManager(conflict.name) + moduleID.addConflictManager(mid, matcher, manager) + } - /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ - def toID(m: ModuleID) = - { - import m._ - ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes)) - } + /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ + def toID(m: ModuleID) = + { + import m._ + ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes)) + } - private def substituteCross(m: ModuleSettings): ModuleSettings = - m.ivyScala match { - case None => m - case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) - } - private def substituteCross(m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String): ModuleSettings = - { - val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) - m match { - case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) - case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) - case _ => m - } - } + private def substituteCross(m: ModuleSettings): ModuleSettings = + m.ivyScala match { + case None => m + case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) + } + private def substituteCross(m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String): ModuleSettings = + { + val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) + m match { + case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) + case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) + case _ => m + } + } - private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, allConfigurations: Iterable[String]): MDArtifact = - { - val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - copyConfigurations(a, artifact.addConfiguration, allConfigurations) - artifact - } - def getExtraAttributes(revID: ExtendableItem): Map[String,String] = - { - import collection.JavaConverters._ - revID.getExtraAttributes.asInstanceOf[java.util.Map[String,String]].asScala.toMap - } - private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = - { - val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } - javaMap(ea.extraAttributes, unqualify) - } - private[sbt] def javaMap(m: Map[String,String], unqualify: Boolean = false) = - { - val map = if(unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m - if(map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map) - } + private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, allConfigurations: Iterable[String]): MDArtifact = + { + val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) + copyConfigurations(a, artifact.addConfiguration, allConfigurations) + artifact + } + def getExtraAttributes(revID: ExtendableItem): Map[String, String] = + { + import collection.JavaConverters._ + revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap + } + private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = + { + val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } + javaMap(ea.extraAttributes, unqualify) + } + private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = + { + val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m + if (map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map) + } - private object javaMap - { - import java.util.{HashMap, Map} - def apply[K,V](pairs: (K,V)*): Map[K,V] = - { - val map = new HashMap[K,V] - pairs.foreach { case (key, value) => map.put(key, value) } - map - } - } - /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ - private def wrapped(module: ModuleID, dependencies: NodeSeq) = - { - - { if(hasInfo(module, dependencies)) - NodeSeq.Empty - else - addExtraAttributes(defaultInfo(module), module.extraAttributes) - } - {dependencies} - { - // this is because Ivy adds a default artifact if none are specified. - if(dependencies \\ "publications" isEmpty) else NodeSeq.Empty - } - - } - private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { - import module._ - - } - private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = - (elem /: extra) { case (e, (key,value) ) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } - private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = - { - val info = {x} \ "info" - if(!info.isEmpty) - { - def check(found: NodeSeq, expected: String, label: String) = - if(found.isEmpty) - sys.error("Missing " + label + " in inline Ivy XML.") - else { - val str = found.text - if(str != expected) sys.error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") - } - check(info \ "@organisation", module.organization, "organisation") - check(info \ "@module", module.name, "name") - check(info \ "@revision", module.revision, "version") - } - !info.isEmpty - } - /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ - private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = - parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) - /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ - private def parseIvyXML(settings: IvySettings, xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = - { - val parser = new CustomXmlParser.CustomParser(settings, Some(defaultConfiguration)) - parser.setMd(moduleID) - parser.setValidate(validate) - parser.setInput(xml.getBytes) - parser.parse() - parser - } + private object javaMap { + import java.util.{ HashMap, Map } + def apply[K, V](pairs: (K, V)*): Map[K, V] = + { + val map = new HashMap[K, V] + pairs.foreach { case (key, value) => map.put(key, value) } + map + } + } + /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ + private def wrapped(module: ModuleID, dependencies: NodeSeq) = + { + + { + if (hasInfo(module, dependencies)) + NodeSeq.Empty + else + addExtraAttributes(defaultInfo(module), module.extraAttributes) + } + { dependencies } + { + // this is because Ivy adds a default artifact if none are specified. + if (dependencies \\ "publications" isEmpty) else NodeSeq.Empty + } + + } + private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { + import module._ + + } + private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = + (elem /: extra) { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } + private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = + { + val info = { x } \ "info" + if (!info.isEmpty) { + def check(found: NodeSeq, expected: String, label: String) = + if (found.isEmpty) + sys.error("Missing " + label + " in inline Ivy XML.") + else { + val str = found.text + if (str != expected) sys.error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") + } + check(info \ "@organisation", module.organization, "organisation") + check(info \ "@module", module.name, "name") + check(info \ "@revision", module.revision, "version") + } + !info.isEmpty + } + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ + private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = + parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ + private def parseIvyXML(settings: IvySettings, xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = + { + val parser = new CustomXmlParser.CustomParser(settings, Some(defaultConfiguration)) + parser.setMd(moduleID) + parser.setValidate(validate) + parser.setInput(xml.getBytes) + parser.parse() + parser + } - /** This method is used to add inline dependencies to the provided module. */ - def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) - { - val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } - val unique = if(hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted - unique foreach moduleID.addDependency - } - /** Determines if there are multiple dependency definitions for the same dependency ID. */ - def hasDuplicateDependencies(dependencies: Seq[DependencyDescriptor]): Boolean = - { - val ids = dependencies.map(_.getDependencyRevisionId) - ids.toSet.size != ids.size - } + /** This method is used to add inline dependencies to the provided module. */ + def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) { + val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } + val unique = if (hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted + unique foreach moduleID.addDependency + } + /** Determines if there are multiple dependency definitions for the same dependency ID. */ + def hasDuplicateDependencies(dependencies: Seq[DependencyDescriptor]): Boolean = + { + val ids = dependencies.map(_.getDependencyRevisionId) + ids.toSet.size != ids.size + } - /** Combines the artifacts, includes, and excludes of duplicate dependency definitions. - * This is somewhat fragile and is only intended to workaround Ivy (or sbt's use of Ivy) not handling this case properly. - * In particular, Ivy will create multiple dependency entries when converting a pom with a dependency on a classified artifact and a non-classified artifact: - * https://github.com/sbt/sbt/issues/468 - * It will also allow users to declare dependencies on classified modules in different configurations: - * https://groups.google.com/d/topic/simple-build-tool/H2MdAARz6e0/discussion - * as well as basic multi-classifier handling: #285, #419, #480. - * Multiple dependency definitions should otherwise be avoided as much as possible. - */ - def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = - { - // need to preserve basic order of dependencies: can't use dependencies.groupBy - val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] - for( dd <- dependencies ) - { - val id = dd.getDependencyRevisionId - val updated = deps get id match { - case null => dd :: Nil - case v => dd :: v - } - deps.put(id, updated) - } + /** + * Combines the artifacts, includes, and excludes of duplicate dependency definitions. + * This is somewhat fragile and is only intended to workaround Ivy (or sbt's use of Ivy) not handling this case properly. + * In particular, Ivy will create multiple dependency entries when converting a pom with a dependency on a classified artifact and a non-classified artifact: + * https://github.com/sbt/sbt/issues/468 + * It will also allow users to declare dependencies on classified modules in different configurations: + * https://groups.google.com/d/topic/simple-build-tool/H2MdAARz6e0/discussion + * as well as basic multi-classifier handling: #285, #419, #480. + * Multiple dependency definitions should otherwise be avoided as much as possible. + */ + def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = + { + // need to preserve basic order of dependencies: can't use dependencies.groupBy + val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] + for (dd <- dependencies) { + val id = dd.getDependencyRevisionId + val updated = deps get id match { + case null => dd :: Nil + case v => dd :: v + } + deps.put(id, updated) + } - import collection.JavaConverters._ - deps.values.asScala.toSeq.flatMap { dds => - val mergeable = (dds, dds.tail).zipped.forall( ivyint.MergeDescriptors.mergeable _) - if(mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds - } - } + import collection.JavaConverters._ + deps.values.asScala.toSeq.flatMap { dds => + val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _) + if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds + } + } - /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ - def convertDependency(moduleID: DefaultModuleDescriptor, dependency: ModuleID, parser: CustomXmlParser.CustomParser): DefaultDependencyDescriptor = - { - val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) - dependency.configurations match - { - case None => // The configuration for this dependency was not explicitly specified, so use the default - parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency - parser.parseDepsConfs(confs, dependencyDescriptor) - } - for(artifact <- dependency.explicitArtifacts) - { - import artifact.{name, classifier, `type`, extension, url} - val extraMap = extra(artifact) - val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) - copyConfigurations(artifact, ivyArtifact.addConfiguration) - for(conf <- dependencyDescriptor.getModuleConfigurations) - dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) - } - for(excls <- dependency.exclusions) - { - for(conf <- dependencyDescriptor.getModuleConfigurations) - { - dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) - } - } - dependencyDescriptor - } - def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = - copyConfigurations(artifact, addConfiguration, "*" :: Nil) - - private[this] def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit, allConfigurations: Iterable[String]): Unit = - { - val confs = if(artifact.configurations.isEmpty) allConfigurations else artifact.configurations.map(_.name) - confs foreach addConfiguration - } + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ + def convertDependency(moduleID: DefaultModuleDescriptor, dependency: ModuleID, parser: CustomXmlParser.CustomParser): DefaultDependencyDescriptor = + { + val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) + dependency.configurations match { + case None => // The configuration for this dependency was not explicitly specified, so use the default + parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) + case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + parser.parseDepsConfs(confs, dependencyDescriptor) + } + for (artifact <- dependency.explicitArtifacts) { + import artifact.{ name, classifier, `type`, extension, url } + val extraMap = extra(artifact) + val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) + copyConfigurations(artifact, ivyArtifact.addConfiguration) + for (conf <- dependencyDescriptor.getModuleConfigurations) + dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) + } + for (excls <- dependency.exclusions) { + for (conf <- dependencyDescriptor.getModuleConfigurations) { + dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) + } + } + dependencyDescriptor + } + def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = + copyConfigurations(artifact, addConfiguration, "*" :: Nil) - def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = - overrides foreach addOverride(moduleID, matcher) - def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = - { - val overrideID = new ModuleId(overrideDef.organization, overrideDef.name) - val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) - moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) - } - /** It is necessary to explicitly modify direct dependencies because Ivy gives - * "IllegalStateException: impossible to get artifacts when data has not been loaded." - * when a direct dependency is overridden with a newer version."*/ - def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = - { - def key(id: ModuleID) = (id.organization, id.name) - val overridden = overrides.map(id => (key(id), id.revision)).toMap - dependencies map { dep => - overridden get key(dep) match { - case Some(rev) => dep.copy(revision = rev) - case None => dep - } - } - } + private[this] def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit, allConfigurations: Iterable[String]): Unit = + { + val confs = if (artifact.configurations.isEmpty) allConfigurations else artifact.configurations.map(_.name) + confs foreach addConfiguration + } - /** This method is used to add inline artifacts to the provided module. */ - def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = - for(art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) - moduleID.addArtifact(c, art) + def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = + overrides foreach addOverride(moduleID, matcher) + def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = + { + val overrideID = new ModuleId(overrideDef.organization, overrideDef.name) + val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) + moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) + } + /** + * It is necessary to explicitly modify direct dependencies because Ivy gives + * "IllegalStateException: impossible to get artifacts when data has not been loaded." + * when a direct dependency is overridden with a newer version." + */ + def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = + { + def key(id: ModuleID) = (id.organization, id.name) + val overridden = overrides.map(id => (key(id), id.revision)).toMap + dependencies map { dep => + overridden get key(dep) match { + case Some(rev) => dep.copy(revision = rev) + case None => dep + } + } + } - def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = - configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) + /** This method is used to add inline artifacts to the provided module. */ + def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = + for (art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) + moduleID.addArtifact(c, art) - def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = - { - lazy val allConfigurations = moduleID.getPublicConfigurationsNames - for(artifact <- artifacts) yield - toIvyArtifact(moduleID, artifact, allConfigurations) - } + def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = + configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) + def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = + { + lazy val allConfigurations = moduleID.getPublicConfigurationsNames + for (artifact <- artifacts) yield toIvyArtifact(moduleID, artifact, allConfigurations) + } - /** This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. - * Ivy 2.0.0 always produces a DefaultModuleDescriptor. */ - private def toDefaultModuleDescriptor(md: ModuleDescriptor) = - md match - { - case dmd: DefaultModuleDescriptor => dmd - case _ => sys.error("Unknown ModuleDescriptor type.") - } - def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = - configurations match - { - case Some(confs) => confs.map(_.name).toList.toArray - case None => module.getPublicConfigurationsNames - } + /** + * This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. + * Ivy 2.0.0 always produces a DefaultModuleDescriptor. + */ + private def toDefaultModuleDescriptor(md: ModuleDescriptor) = + md match { + case dmd: DefaultModuleDescriptor => dmd + case _ => sys.error("Unknown ModuleDescriptor type.") + } + def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = + configurations match { + case Some(confs) => confs.map(_.name).toList.toArray + case None => module.getPublicConfigurationsNames + } } diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 716579e0f..5e2d0359c 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -4,276 +4,269 @@ package sbt import java.io.File -import scala.xml.{Node => XNode, NodeSeq} +import scala.xml.{ Node => XNode, NodeSeq } -import org.apache.ivy.{core, plugins, Ivy} -import core.{IvyPatternHelper, LogOptions} +import org.apache.ivy.{ core, plugins, Ivy } +import core.{ IvyPatternHelper, LogOptions } import core.deliver.DeliverOptions import core.install.InstallOptions -import core.module.descriptor.{Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor} +import core.module.descriptor.{ Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor } import core.report.ResolveReport import core.resolve.ResolveOptions -import plugins.resolver.{BasicResolver, DependencyResolver} +import plugins.resolver.{ BasicResolver, DependencyResolver } final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, - val overwrite: Boolean) { - def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) = - this(ivyFile, resolverName, artifacts, checksums, logging, false) + val overwrite: Boolean) { + def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) = + this(ivyFile, resolverName, artifacts, checksums, logging, false) } final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) - // exclude is a map on a restricted ModuleID +// exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) -/** Configures logging during an 'update'. `level` determines the amount of other information logged. -* `Full` is the default and logs the most. -* `DownloadOnly` only logs what is downloaded. -* `Quiet` only displays errors.*/ -object UpdateLogging extends Enumeration -{ - val Full, DownloadOnly, Quiet = Value +/** + * Configures logging during an 'update'. `level` determines the amount of other information logged. + * `Full` is the default and logs the most. + * `DownloadOnly` only logs what is downloaded. + * `Quiet` only displays errors. + */ +object UpdateLogging extends Enumeration { + val Full, DownloadOnly, Quiet = Value } -object IvyActions -{ - /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ - def install(module: IvySbt#Module, from: String, to: String, log: Logger) - { - module.withModule(log) { (ivy, md, default) => - for(dependency <- md.getDependencies) - { - log.info("Installing " + dependency) - val options = new InstallOptions - options.setValidate(module.moduleSettings.validate) - options.setTransitive(dependency.isTransitive) - ivy.install(dependency.getDependencyRevisionId, from, to, options) - } - } - } +object IvyActions { + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ + def install(module: IvySbt#Module, from: String, to: String, log: Logger) { + module.withModule(log) { (ivy, md, default) => + for (dependency <- md.getDependencies) { + log.info("Installing " + dependency) + val options = new InstallOptions + options.setValidate(module.moduleSettings.validate) + options.setTransitive(dependency.isTransitive) + ivy.install(dependency.getDependencyRevisionId, from, to, options) + } + } + } - /** Clears the Ivy cache, as configured by 'config'. */ - def cleanCache(ivy: IvySbt, log: Logger) = ivy.withIvy(log) { iv => - iv.getSettings.getResolutionCacheManager.clean() - iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) - } + /** Clears the Ivy cache, as configured by 'config'. */ + def cleanCache(ivy: IvySbt, log: Logger) = ivy.withIvy(log) { iv => + iv.getSettings.getResolutionCacheManager.clean() + iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) + } - /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) - { - import configuration.{allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes} - module.withModule(log) { (ivy, md, default) => - (new MakePom(log)).write(ivy, md, moduleInfo, configurations, includeTypes, extra, process, filterRepositories, allRepositories, file) - log.info("Wrote " + file.getAbsolutePath) - } - } + /** Creates a Maven pom from the given Ivy configuration*/ + def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { + import configuration.{ allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes } + module.withModule(log) { (ivy, md, default) => + (new MakePom(log)).write(ivy, md, moduleInfo, configurations, includeTypes, extra, process, filterRepositories, allRepositories, file) + log.info("Wrote " + file.getAbsolutePath) + } + } - def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = - { - import configuration._ - module.withModule(log) { case (ivy, md, default) => - val revID = md.getModuleRevisionId - val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) - deliveredFile(ivy, deliverIvyPattern, md) - } - } - def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = - ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) + def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = + { + import configuration._ + module.withModule(log) { + case (ivy, md, default) => + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(IvySbt.getConfigurations(md, configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) + } + } + def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = + ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) - def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) - { - import configuration._ - module.withModule(log) { case (ivy, md, default) => - val resolver = ivy.getSettings.getResolver(resolverName) - if(resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") - val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } - val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toSeq - withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } - } - } - private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T = - resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act } - private[this] def withChecksums[T](resolver: BasicResolver, checksums: Seq[String])(act: => T): T = - { - val previous = resolver.getChecksumAlgorithms - resolver.setChecksums(checksums mkString ",") - try { act } - finally { resolver.setChecksums(previous mkString ",") } - } - private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = - moduleSettings match { - case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) - case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) - case _ => None - } - def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = - { - val rawa = artifacts.keys.toSeq - val seqa = CrossVersion.substituteCross(rawa, cross) - val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) - zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } - } - /** Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. - * 'updateConfig' configures the actual resolution and retrieval process. */ - def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = - module.withModule(log) { case (ivy, md, default) => - val (report, err) = resolve(configuration.logging)(ivy, md, default) - err match - { - case Some(x) if !configuration.missingOk => - processUnresolved(x, log) - throw x - case _ => - val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) - val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) - configuration.retrieve match - { - case Some(rConf) => retrieve(ivy, uReport, rConf) - case None => uReport - } - } - } + def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { + import configuration._ + module.withModule(log) { + case (ivy, md, default) => + val resolver = ivy.getSettings.getResolver(resolverName) + if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") + val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } + val cross = crossVersionMap(module.moduleSettings) + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toSeq + withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } + } + } + private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T = + resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act } + private[this] def withChecksums[T](resolver: BasicResolver, checksums: Seq[String])(act: => T): T = + { + val previous = resolver.getChecksumAlgorithms + resolver.setChecksums(checksums mkString ",") + try { act } + finally { resolver.setChecksums(previous mkString ",") } + } + private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = + moduleSettings match { + case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) + case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) + case _ => None + } + def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + { + val rawa = artifacts.keys.toSeq + val seqa = CrossVersion.substituteCross(rawa, cross) + val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) + zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } + } + /** + * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. + * 'updateConfig' configures the actual resolution and retrieval process. + */ + def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = + module.withModule(log) { + case (ivy, md, default) => + val (report, err) = resolve(configuration.logging)(ivy, md, default) + err match { + case Some(x) if !configuration.missingOk => + processUnresolved(x, log) + throw x + case _ => + val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) + val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) + configuration.retrieve match { + case Some(rConf) => retrieve(ivy, uReport, rConf) + case None => uReport + } + } + } - def processUnresolved(err: ResolveException, log: Logger) - { - val withExtra = err.failed.filter(!_.extraDependencyAttributes.isEmpty) - if(!withExtra.isEmpty) - { - log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") - withExtra foreach { id => log.warn("\t\t" + id) } - log.warn("") - } - } - def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = - report.configurations.flatMap { confReport => - val evicted = confReport.evicted.filter(moduleFilter) - val evictedSet = evicted.map( m => (m.organization, m.name) ).toSet - val conflicted = confReport.allModules.filter( mod => evictedSet( (mod.organization, mod.name) ) ) - grouped(grouping)(conflicted ++ evicted) - } toMap; + def processUnresolved(err: ResolveException, log: Logger) { + val withExtra = err.failed.filter(!_.extraDependencyAttributes.isEmpty) + if (!withExtra.isEmpty) { + log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") + withExtra foreach { id => log.warn("\t\t" + id) } + log.warn("") + } + } + def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = + report.configurations.flatMap { confReport => + val evicted = confReport.evicted.filter(moduleFilter) + val evictedSet = evicted.map(m => (m.organization, m.name)).toSet + val conflicted = confReport.allModules.filter(mod => evictedSet((mod.organization, mod.name))) + grouped(grouping)(conflicted ++ evicted) + } toMap; - def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = - mods groupBy(grouping) mapValues(_.map(_.revision).toSet) + def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = + mods groupBy (grouping) mapValues (_.map(_.revision).toSet) - def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - { - import config.{configuration => c, ivyScala, module => mod} - import mod.{id, modules => deps} - val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) - val report = update(module, c, log) - val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, log) - } - def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - { - import config.{configuration => c, module => mod, _} - import mod.{configurations => confs, _} - assert(!classifiers.isEmpty, "classifiers cannot be empty") - val baseModules = modules map { m => restrictedCopy(m, true) } - val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) - val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$","_","")) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) - val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) - update(module, upConf, log) - } - def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = - { - val excluded = exclude getOrElse(restrictedCopy(m, false), Set.empty) - val included = classifiers filterNot excluded - if(included.isEmpty) None else Some(m.copy(isTransitive = false, explicitArtifacts = classifiedArtifacts(m.name, included) )) - } - def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = - report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } - def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = - classifiers map { c => Artifact.classified(name, c) } - private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = - exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) + def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = + { + import config.{ configuration => c, ivyScala, module => mod } + import mod.{ id, modules => deps } + val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) + val report = update(module, c, log) + val newConfig = config.copy(module = mod.copy(modules = report.allModules)) + updateClassifiers(ivySbt, newConfig, log) + } + def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = + { + import config.{ configuration => c, module => mod, _ } + import mod.{ configurations => confs, _ } + assert(!classifiers.isEmpty, "classifiers cannot be empty") + val baseModules = modules map { m => restrictedCopy(m, true) } + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) + val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) + val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) + update(module, upConf, log) + } + def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = + { + val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) + val included = classifiers filterNot excluded + if (included.isEmpty) None else Some(m.copy(isTransitive = false, explicitArtifacts = classifiedArtifacts(m.name, included))) + } + def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = + report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } + def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = + classifiers map { c => Artifact.classified(name, c) } + private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = + exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) - def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy(_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } + def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = + report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } - private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if(confs) m.configurations else None) - private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = - { - val resolveOptions = new ResolveOptions - val resolveId = ResolveOptions.getDefaultResolveId(module) - resolveOptions.setResolveId(resolveId) - resolveOptions.setLog(ivyLogLevel(logging)) - ResolutionCache.cleanModule(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) - val resolveReport = ivy.resolve(module, resolveOptions) - val err = - if(resolveReport.hasError) - { - val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct - val failed = resolveReport.getUnresolvedDependencies.map(node => IvyRetrieve.toModuleID(node.getId)) - Some(new ResolveException(messages, failed)) - } - else None - (resolveReport, err) - } - private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = - retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) + private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = + ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None) + private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = + { + val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(module) + resolveOptions.setResolveId(resolveId) + resolveOptions.setLog(ivyLogLevel(logging)) + ResolutionCache.cleanModule(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) + val resolveReport = ivy.resolve(module, resolveOptions) + val err = + if (resolveReport.hasError) { + val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct + val failed = resolveReport.getUnresolvedDependencies.map(node => IvyRetrieve.toModuleID(node.getId)) + Some(new ResolveException(messages, failed)) + } else None + (resolveReport, err) + } + private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = + retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) - private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = - { - val toCopy = new collection.mutable.HashSet[(File,File)] - val retReport = report retrieve { (conf, mid, art, cached) => - val to = retrieveTarget(conf, mid, art, base, pattern) - toCopy += ((cached, to)) - to - } - IO.copy( toCopy ) - retReport - } - private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = - new File(base, substitute(conf, mid, art, pattern)) + private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = + { + val toCopy = new collection.mutable.HashSet[(File, File)] + val retReport = report retrieve { (conf, mid, art, cached) => + val to = retrieveTarget(conf, mid, art, base, pattern) + toCopy += ((cached, to)) + to + } + IO.copy(toCopy) + retReport + } + private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = + new File(base, substitute(conf, mid, art, pattern)) - private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = - { - val mextra = IvySbt.javaMap(mid.extraAttributes, true) - val aextra = IvySbt.extra(art, true) - IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra) - } + private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = + { + val mextra = IvySbt.javaMap(mid.extraAttributes, true) + val aextra = IvySbt.extra(art, true) + IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra) + } - import UpdateLogging.{Quiet, Full, DownloadOnly} - import LogOptions.{LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY} - private def ivyLogLevel(level: UpdateLogging.Value) = - level match - { - case Quiet => LOG_QUIET - case DownloadOnly => LOG_DOWNLOAD_ONLY - case Full => LOG_DEFAULT - } + import UpdateLogging.{ Quiet, Full, DownloadOnly } + import LogOptions.{ LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY } + private def ivyLogLevel(level: UpdateLogging.Value) = + level match { + case Quiet => LOG_QUIET + case DownloadOnly => LOG_DOWNLOAD_ONLY + case Full => LOG_DEFAULT + } - def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = - { - if (artifacts.nonEmpty) { - checkFilesPresent(artifacts) - try { - resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - for( (artifact, file) <- artifacts) - resolver.publish(artifact, file, overwrite) - resolver.commitPublishTransaction() - } catch { - case e: Throwable => - try { resolver.abortPublishTransaction() } - finally { throw e } - } - } - } - private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) - { - val missing = artifacts filter { case (a, file) => !file.exists } - if(missing.nonEmpty) - error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) - } + def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = + { + if (artifacts.nonEmpty) { + checkFilesPresent(artifacts) + try { + resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); + for ((artifact, file) <- artifacts) + resolver.publish(artifact, file, overwrite) + resolver.commitPublishTransaction() + } catch { + case e: Throwable => + try { resolver.abortPublishTransaction() } + finally { throw e } + } + } + } + private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) { + val missing = artifacts filter { case (a, file) => !file.exists } + if (missing.nonEmpty) + error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) + } } final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala index 3ff8432f0..fe520d96c 100644 --- a/ivy/src/main/scala/sbt/IvyCache.scala +++ b/ivy/src/main/scala/sbt/IvyCache.scala @@ -6,102 +6,93 @@ package sbt import java.io.File import java.net.URL -import org.apache.ivy.{core, plugins, util} -import core.cache.{ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager} -import core.module.descriptor.{Artifact => IvyArtifact, DefaultArtifact} -import plugins.repository.file.{FileRepository=>IvyFileRepository, FileResource} -import plugins.repository.{ArtifactResourceResolver, Resource, ResourceDownloader} +import org.apache.ivy.{ core, plugins, util } +import core.cache.{ ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager } +import core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact } +import plugins.repository.file.{ FileRepository => IvyFileRepository, FileResource } +import plugins.repository.{ ArtifactResourceResolver, Resource, ResourceDownloader } import plugins.resolver.util.ResolvedResource import util.FileUtil class NotInCache(val id: ModuleID, cause: Throwable) - extends RuntimeException(NotInCache(id, cause), cause) -{ - def this(id: ModuleID) = this(id, null) + extends RuntimeException(NotInCache(id, cause), cause) { + def this(id: ModuleID) = this(id, null) } -private object NotInCache -{ - def apply(id: ModuleID, cause: Throwable) = - { - val postfix = if(cause == null) "" else (": " +cause.toString) - "File for " + id + " not in cache" + postfix - } +private object NotInCache { + def apply(id: ModuleID, cause: Throwable) = + { + val postfix = if (cause == null) "" else (": " + cause.toString) + "File for " + id + " not in cache" + postfix + } } /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ -class IvyCache(val ivyHome: Option[File]) -{ - def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") - /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ - def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger) - { - val artifact = defaultArtifact(moduleID) - val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) - withDefaultCache(lock, log) { cache => - val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } - cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) - } - } - /** Clears the cache of the jar for the given ID.*/ - def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger) - { - try { withCachedJar(id, lock, log)(_.delete) } - catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } - } - /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ - def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: Logger) = - withCachedJar(id, lock, log) { cachedFile => - val copyTo = new File(toDirectory, cachedFile.getName) - FileUtil.copy(cachedFile, copyTo, null) - copyTo - } +class IvyCache(val ivyHome: Option[File]) { + def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ + def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger) { + val artifact = defaultArtifact(moduleID) + val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) + withDefaultCache(lock, log) { cache => + val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } + cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) + } + } + /** Clears the cache of the jar for the given ID.*/ + def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger) { + try { withCachedJar(id, lock, log)(_.delete) } + catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } + } + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ + def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: Logger) = + withCachedJar(id, lock, log) { cachedFile => + val copyTo = new File(toDirectory, cachedFile.getName) + FileUtil.copy(cachedFile, copyTo, null) + copyTo + } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ - def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)(f: File => T): T = - { - val cachedFile = - try - { - withDefaultCache(lock, log) { cache => - val artifact = defaultArtifact(id) - cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) - } - } - catch { case e: Exception => throw new NotInCache(id, e) } + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ + def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)(f: File => T): T = + { + val cachedFile = + try { + withDefaultCache(lock, log) { cache => + val artifact = defaultArtifact(id) + cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) + } + } catch { case e: Exception => throw new NotInCache(id, e) } - if(cachedFile.exists) f(cachedFile) else throw new NotInCache(id) - } - /** Calls the given function with the default Ivy cache.*/ - def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = - { - val (ivy, local) = basicLocalIvy(lock, log) - ivy.withIvy(log) { ivy => - val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] - cache.setUseOrigin(false) - f(cache) - } - } - private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) - /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ - private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = - { - val local = Resolver.defaultLocal - val paths = new IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, log) - (new IvySbt(conf), local) - } - /** Creates a default jar artifact based on the given ID.*/ - private def defaultArtifact(moduleID: ModuleID): IvyArtifact = - new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") + if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) + } + /** Calls the given function with the default Ivy cache.*/ + def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = + { + val (ivy, local) = basicLocalIvy(lock, log) + ivy.withIvy(log) { ivy => + val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] + cache.setUseOrigin(false) + f(cache) + } + } + private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ + private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = + { + val local = Resolver.defaultLocal + val paths = new IvyPaths(new File("."), ivyHome) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, log) + (new IvySbt(conf), local) + } + /** Creates a default jar artifact based on the given ID.*/ + private def defaultArtifact(moduleID: ModuleID): IvyArtifact = + new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } /** Required by Ivy for copying to the cache.*/ -private class FileDownloader extends ResourceDownloader with NotNull -{ - def download(artifact: IvyArtifact, resource: Resource, dest: File) - { - if(dest.exists()) dest.delete() - val part = new File(dest.getAbsolutePath + ".part") - FileUtil.copy(resource.openStream, part, null) - if(!part.renameTo(dest)) - sys.error("Could not move temporary file " + part + " to final location " + dest) - } +private class FileDownloader extends ResourceDownloader with NotNull { + def download(artifact: IvyArtifact, resource: Resource, dest: File) { + if (dest.exists()) dest.delete() + val part = new File(dest.getAbsolutePath + ".part") + FileUtil.copy(resource.openStream, part, null) + if (!part.renameTo(dest)) + sys.error("Could not move temporary file " + part + " to final location " + dest) + } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index 256af5f2e..93025e2d7 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -4,120 +4,104 @@ package sbt import java.io.File -import java.net.{URI,URL} +import java.net.{ URI, URL } import scala.xml.NodeSeq -final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) -{ - def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) +final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { + def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) } -sealed trait IvyConfiguration -{ - type This <: IvyConfiguration - def lock: Option[xsbti.GlobalLock] - def baseDirectory: File - def log: Logger - def withBase(newBaseDirectory: File): This +sealed trait IvyConfiguration { + type This <: IvyConfiguration + def lock: Option[xsbti.GlobalLock] + def baseDirectory: File + def log: Logger + def withBase(newBaseDirectory: File): This } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val resolutionCacheDir: Option[File], val log: Logger) extends IvyConfiguration -{ - @deprecated("Use the variant that accepts the resolution cache location.", "0.13.0") - def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], - moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], - checksums: Seq[String], log: Logger) = - this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, log) + val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], + val checksums: Seq[String], val resolutionCacheDir: Option[File], val log: Logger) extends IvyConfiguration { + @deprecated("Use the variant that accepts the resolution cache location.", "0.13.0") + def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], + moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], + checksums: Seq[String], log: Logger) = + this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, log) - type This = InlineIvyConfiguration - def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) + type This = InlineIvyConfiguration + def baseDirectory = paths.baseDirectory + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) } -final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration -{ - type This = ExternalIvyConfiguration - def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, log) +final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration { + type This = ExternalIvyConfiguration + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, log) } -object ExternalIvyConfiguration -{ - def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, log) +object ExternalIvyConfiguration { + def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, log) } -object IvyConfiguration -{ - /** Called to configure Ivy when inline resolvers are not specified. - * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers.*/ - @deprecated("Explicitly use either external or inline configuration.", "0.12.0") - def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration = - { - log.debug("Autodetecting configuration.") - val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) - if(defaultIvyConfigFile.canRead) - ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) - else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log) - } +object IvyConfiguration { + /** + * Called to configure Ivy when inline resolvers are not specified. + * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers. + */ + @deprecated("Explicitly use either external or inline configuration.", "0.12.0") + def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration = + { + log.debug("Autodetecting configuration.") + val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) + if (defaultIvyConfigFile.canRead) + ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) + else + new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log) + } } -sealed trait ModuleSettings -{ - def validate: Boolean - def ivyScala: Option[IvyScala] - def noScala: ModuleSettings +sealed trait ModuleSettings { + def validate: Boolean + def ivyScala: Option[IvyScala] + def noScala: ModuleSettings } -final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings -{ - def noScala = copy(ivyScala = None) +final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { + def noScala = copy(ivyScala = None) } -final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings -{ - def noScala = copy(ivyScala = None) +final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { + def noScala = copy(ivyScala = None) } -final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings -{ - def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) - def noScala = copy(ivyScala = None) +final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { + def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) + def noScala = copy(ivyScala = None) } @deprecated("Define a module using inline Scala (InlineConfiguration), a pom.xml (PomConfiguration), or an ivy.xml (IvyFileConfiguration).", "0.13.0") -final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings -{ - def noScala = copy(ivyScala = None) +final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { + def noScala = copy(ivyScala = None) } -object InlineConfiguration -{ - def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = - if(explicitConfigurations.isEmpty) - { - defaultConfiguration match - { - case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil - case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations - case _ => Nil - } - } - else - explicitConfigurations +object InlineConfiguration { + def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = + if (explicitConfigurations.isEmpty) { + defaultConfiguration match { + case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil + case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations + case _ => Nil + } + } else + explicitConfigurations } -object ModuleSettings -{ - @deprecated("Explicitly select configuration from pom.xml, ivy.xml, or inline Scala.", "0.13.0") - def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = - { - log.debug("Autodetecting dependencies.") - val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) - if(defaultPOMFile.canRead) - new PomConfiguration(defaultPOMFile, ivyScala, validate, true) - else - { - val defaultIvy = IvySbt.defaultIvyFile(baseDirectory) - if(defaultIvy.canRead) - new IvyFileConfiguration(defaultIvy, ivyScala, validate, true) - else - { - log.warn("No dependency configuration found, using defaults.") - new EmptyConfiguration(module, moduleInfo, ivyScala, validate) - } - } - } +object ModuleSettings { + @deprecated("Explicitly select configuration from pom.xml, ivy.xml, or inline Scala.", "0.13.0") + def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = + { + log.debug("Autodetecting dependencies.") + val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) + if (defaultPOMFile.canRead) + new PomConfiguration(defaultPOMFile, ivyScala, validate, true) + else { + val defaultIvy = IvySbt.defaultIvyFile(baseDirectory) + if (defaultIvy.canRead) + new IvyFileConfiguration(defaultIvy, ivyScala, validate, true) + else { + log.warn("No dependency configuration found, using defaults.") + new EmptyConfiguration(module, moduleInfo, ivyScala, validate) + } + } + } } diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 2772b98c3..05720e6aa 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -4,18 +4,17 @@ package sbt import java.io.File -import java.net.{URI, URL} +import java.net.{ URI, URL } import scala.xml.NodeSeq -import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} +import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ -final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) -{ - def formally(name: String) = copy(nameFormal = name) - def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) - def licensed(lics: (String, URL)*) = copy(licenses = lics) - def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) +final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { + def formally(name: String) = copy(nameFormal = name) + def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) + def licensed(lics: (String, URL)*) = copy(licenses = lics) + def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) } /** Basic SCM information for a project module */ @@ -25,20 +24,19 @@ final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Opti final case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) -object ModuleConfiguration -{ - def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) - def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) +object ModuleConfiguration { + def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) + def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) } final case class ConflictManager(name: String, organization: String = "*", module: String = "*") /** See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.*/ object ConflictManager { - val all = ConflictManager("all") - val latestTime = ConflictManager("latest-time") - val latestRevision = ConflictManager("latest-revision") - val latestCompatible = ConflictManager("latest-compatible") - val strict = ConflictManager("strict") - val default = latestRevision + val all = ConflictManager("all") + val latestTime = ConflictManager("latest-time") + val latestRevision = ConflictManager("latest-revision") + val latestCompatible = ConflictManager("latest-compatible") + val strict = ConflictManager("strict") + val default = latestRevision } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/IvyLogger.scala b/ivy/src/main/scala/sbt/IvyLogger.scala index 6e1b136fe..42131a174 100644 --- a/ivy/src/main/scala/sbt/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/IvyLogger.scala @@ -3,56 +3,51 @@ */ package sbt -import org.apache.ivy.util.{Message, MessageLogger, MessageLoggerEngine} +import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } /** Interface to Ivy logging. */ -private final class IvyLoggerInterface(logger: Logger) extends MessageLogger -{ - def rawlog(msg: String, level: Int) = log(msg, level) - def log(msg: String, level: Int) - { - import Message.{MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR} - level match - { - case MSG_DEBUG => debug(msg) - case MSG_VERBOSE => verbose(msg) - case MSG_INFO => info(msg) - case MSG_WARN => warn(msg) - case MSG_ERR => error(msg) - } - } - //DEBUG level messages are very verbose and rarely useful to users. - // TODO: provide access to this information some other way - def debug(msg: String) {} - def verbose(msg: String) = logger.verbose(msg) - def deprecated(msg: String) = warn(msg) - def info(msg: String) = logger.info(msg) - def rawinfo(msg: String) = info(msg) - def warn(msg: String) = logger.warn(msg) - def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) logger.error(msg) - - private def emptyList = java.util.Collections.emptyList[String] - def getProblems = emptyList - def getWarns = emptyList - def getErrors = emptyList +private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { + def rawlog(msg: String, level: Int) = log(msg, level) + def log(msg: String, level: Int) { + import Message.{ MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR } + level match { + case MSG_DEBUG => debug(msg) + case MSG_VERBOSE => verbose(msg) + case MSG_INFO => info(msg) + case MSG_WARN => warn(msg) + case MSG_ERR => error(msg) + } + } + //DEBUG level messages are very verbose and rarely useful to users. + // TODO: provide access to this information some other way + def debug(msg: String) {} + def verbose(msg: String) = logger.verbose(msg) + def deprecated(msg: String) = warn(msg) + def info(msg: String) = logger.info(msg) + def rawinfo(msg: String) = info(msg) + def warn(msg: String) = logger.warn(msg) + def error(msg: String) = if (SbtIvyLogger.acceptError(msg)) logger.error(msg) - def clearProblems = () - def sumupProblems = clearProblems() - def progress = () - def endProgress = () + private def emptyList = java.util.Collections.emptyList[String] + def getProblems = emptyList + def getWarns = emptyList + def getErrors = emptyList - def endProgress(msg: String) = info(msg) - def isShowProgress = false - def setShowProgress(progress: Boolean) {} + def clearProblems = () + def sumupProblems = clearProblems() + def progress = () + def endProgress = () + + def endProgress(msg: String) = info(msg) + def isShowProgress = false + def setShowProgress(progress: Boolean) {} } -private final class SbtMessageLoggerEngine extends MessageLoggerEngine -{ - /** This is a hack to filter error messages about 'unknown resolver ...'. */ - override def error(msg: String) = if(SbtIvyLogger.acceptError(msg)) super.error(msg) - override def sumupProblems = clearProblems() +private final class SbtMessageLoggerEngine extends MessageLoggerEngine { + /** This is a hack to filter error messages about 'unknown resolver ...'. */ + override def error(msg: String) = if (SbtIvyLogger.acceptError(msg)) super.error(msg) + override def sumupProblems = clearProblems() } -private object SbtIvyLogger -{ - val UnknownResolver = "unknown resolver" - def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) +private object SbtIvyLogger { + val UnknownResolver = "unknown resolver" + def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index dd0ffe910..5d0f3f6ec 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -6,51 +6,49 @@ package sbt import java.io.File import collection.mutable -import org.apache.ivy.core.{module, report} -import module.descriptor.{Artifact => IvyArtifact} +import org.apache.ivy.core.{ module, report } +import module.descriptor.{ Artifact => IvyArtifact } import module.id.ModuleRevisionId -import report.{ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport} +import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport } -object IvyRetrieve -{ - def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = - report.getConfigurations map report.getConfigurationReport +object IvyRetrieve { + def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = + report.getConfigurations map report.getConfigurationReport - def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] = - for( revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield - artifactReports(toModuleID(revId), confReport getDownloadReports revId) + def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] = + for (revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield artifactReports(toModuleID(revId), confReport getDownloadReports revId) - def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = - { - val missing = new mutable.ListBuffer[Artifact] - val resolved = new mutable.ListBuffer[(Artifact,File)] - for(r <- artReport) { - val file = r.getLocalFile - val art = toArtifact(r.getArtifact) - if(file eq null) - missing += art - else - resolved += ((art,file)) - } - new ModuleReport(mid, resolved.toSeq, missing.toSeq) - } + def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = + { + val missing = new mutable.ListBuffer[Artifact] + val resolved = new mutable.ListBuffer[(Artifact, File)] + for (r <- artReport) { + val file = r.getLocalFile + val art = toArtifact(r.getArtifact) + if (file eq null) + missing += art + else + resolved += ((art, file)) + } + new ModuleReport(mid, resolved.toSeq, missing.toSeq) + } - def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = - confReport.getEvictedNodes.map(node => toModuleID(node.getId)) - - def toModuleID(revID: ModuleRevisionId): ModuleID = - ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID)) - - def toArtifact(art: IvyArtifact): Artifact = - { - import art._ - Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl)) - } + def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = + confReport.getEvictedNodes.map(node => toModuleID(node.getId)) - def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = - new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps() - def updateStats(report: ResolveReport): UpdateStats = - new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) - def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) + def toModuleID(revID: ModuleRevisionId): ModuleID = + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID)) + + def toArtifact(art: IvyArtifact): Artifact = + { + import art._ + Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl)) + } + + def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = + new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps () + def updateStats(report: ResolveReport): UpdateStats = + new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) + def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) } diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index 23b7597ff..5cc3bdd48 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -6,111 +6,108 @@ package sbt import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.{core, plugins} -import core.module.descriptor.{DefaultExcludeRule, ExcludeRule} -import core.module.descriptor.{DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import org.apache.ivy.{ core, plugins } +import core.module.descriptor.{ DefaultExcludeRule, ExcludeRule } +import core.module.descriptor.{ DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator } +import core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import plugins.matcher.ExactPatternMatcher -object ScalaArtifacts -{ - import xsbti.ArtifactInfo._ - val Organization = ScalaOrganization - val LibraryID = ScalaLibraryID - val CompilerID = ScalaCompilerID - def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) +object ScalaArtifacts { + import xsbti.ArtifactInfo._ + val Organization = ScalaOrganization + val LibraryID = ScalaLibraryID + val CompilerID = ScalaCompilerID + def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) - private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( - scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version) - ) - private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = - ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)") ) + private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( + scalaToolDependency(org, ScalaArtifacts.CompilerID, version), + scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + ) + private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = + ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) } -object SbtArtifacts -{ - import xsbti.ArtifactInfo._ - val Organization = SbtOrganization +object SbtArtifacts { + import xsbti.ArtifactInfo._ + val Organization = SbtOrganization } import ScalaArtifacts._ final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization) -private object IvyScala -{ - /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala) - { - if(check.checkExplicit) - checkDependencies(module, check.scalaBinaryVersion, check.configurations, log) - if(check.filterImplicit) - excludeScalaJars(module, check.configurations) - if(check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaFullVersion) - } - def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) - { - overrideVersion(module, Organization, LibraryID, version) - overrideVersion(module, Organization, CompilerID, version) - } - def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String) - { - val id = new ModuleId(org, name) - val over = new OverrideDependencyDescriptorMediator(null, version) - module.addDependencyDescriptorMediator(id, ExactPatternMatcher.INSTANCE, over) - } - - /** Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the - * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger) - { - val configSet = if(configurations.isEmpty) (c: String) => true else configurationSet(configurations) - def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = - { - val id = dep.getDependencyRevisionId - val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) - val mismatched = id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet) - if(mismatched) - Some("Binary version (" + depBinaryVersion + ") for dependency " + id + - "\n\tin " + module.getModuleRevisionId + - " differs from Scala binary version in project (" + scalaBinaryVersion + ").") - else - None - } - module.getDependencies.toList.flatMap(binaryScalaWarning).toSet foreach { (s: String) => log.warn(s) } - } - private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet +private object IvyScala { + /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ + def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala) { + if (check.checkExplicit) + checkDependencies(module, check.scalaBinaryVersion, check.configurations, log) + if (check.filterImplicit) + excludeScalaJars(module, check.configurations) + if (check.overrideScalaVersion) + overrideScalaVersion(module, check.scalaFullVersion) + } + def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) { + overrideVersion(module, Organization, LibraryID, version) + overrideVersion(module, Organization, CompilerID, version) + } + def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String) { + val id = new ModuleId(org, name) + val over = new OverrideDependencyDescriptorMediator(null, version) + module.addDependencyDescriptorMediator(id, ExactPatternMatcher.INSTANCE, over) + } - /** Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is - * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use - * is done by setting scalaVersion in the project definition. */ - private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) - { - val configurationNames = - { - val names = module.getConfigurationsNames - if(configurations.isEmpty) - names - else - { - val configSet = configurationSet(configurations) - configSet.intersect(HashSet(names : _*)) - configSet.toArray - } - } - def excludeScalaJar(name: String): Unit = - module.addExcludeRule(excludeRule(Organization, name, configurationNames, "jar")) - excludeScalaJar(LibraryID) - excludeScalaJar(CompilerID) - } - /** Creates an ExcludeRule that excludes artifacts with the given module organization and name for - * the given configurations. */ - private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String], excludeTypePattern: String): ExcludeRule = - { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", excludeTypePattern, "*") - val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef,AnyRef]) - configurationNames.foreach(rule.addConfiguration) - rule - } + /** + * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the + * dependencies matches scalaVersion. + */ + private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger) { + val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) + def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = + { + val id = dep.getDependencyRevisionId + val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) + val mismatched = id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet) + if (mismatched) + Some("Binary version (" + depBinaryVersion + ") for dependency " + id + + "\n\tin " + module.getModuleRevisionId + + " differs from Scala binary version in project (" + scalaBinaryVersion + ").") + else + None + } + module.getDependencies.toList.flatMap(binaryScalaWarning).toSet foreach { (s: String) => log.warn(s) } + } + private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet + + /** + * Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is + * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use + * is done by setting scalaVersion in the project definition. + */ + private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) { + val configurationNames = + { + val names = module.getConfigurationsNames + if (configurations.isEmpty) + names + else { + val configSet = configurationSet(configurations) + configSet.intersect(HashSet(names: _*)) + configSet.toArray + } + } + def excludeScalaJar(name: String): Unit = + module.addExcludeRule(excludeRule(Organization, name, configurationNames, "jar")) + excludeScalaJar(LibraryID) + excludeScalaJar(CompilerID) + } + /** + * Creates an ExcludeRule that excludes artifacts with the given module organization and name for + * the given configurations. + */ + private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String], excludeTypePattern: String): ExcludeRule = + { + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", excludeTypePattern, "*") + val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/IvyUtil.scala b/ivy/src/main/scala/sbt/IvyUtil.scala index 1c99bb5d3..0f06b6b84 100644 --- a/ivy/src/main/scala/sbt/IvyUtil.scala +++ b/ivy/src/main/scala/sbt/IvyUtil.scala @@ -1,7 +1,6 @@ package sbt -private[sbt] object IvyUtil -{ - def separate[A,B](l: Seq[Either[A,B]]): (Seq[A], Seq[B]) = - (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) +private[sbt] object IvyUtil { + def separate[A, B](l: Seq[Either[A, B]]): (Seq[A], Seq[B]) = + (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 16ec28333..6e51befca 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -10,349 +10,348 @@ package sbt import java.io.File // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation -import scala.xml.{Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute} +import scala.xml.{ Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute } import Configurations.Optional -import org.apache.ivy.{core, plugins, Ivy} +import org.apache.ivy.{ core, plugins, Ivy } import core.settings.IvySettings -import core.module.descriptor.{DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} -import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} +import core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } +import plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } -class MakePom(val log: Logger) -{ - @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(ivy, module, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], Set(Artifact.DefaultType), extra, process, filterRepositories, allRepositories, output) - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(process(toPom(ivy, module, moduleInfo, configurations, includeTypes, extra, filterRepositories, allRepositories)), output) - // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n - def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") - def write(xmlString: String, output: File, newline: String) - { - IO.write(output, "" + newline + xmlString) - } +class MakePom(val log: Logger) { + @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + write(ivy, module, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], Set(Artifact.DefaultType), extra, process, filterRepositories, allRepositories, output) + def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = + write(process(toPom(ivy, module, moduleInfo, configurations, includeTypes, extra, filterRepositories, allRepositories)), output) + // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n + def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") + def write(xmlString: String, output: File, newline: String) { + IO.write(output, "" + newline + xmlString) + } - def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) - @deprecated("Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", "0.11.2") - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = - toPom(ivy, module, moduleInfo, configurations, Set(Artifact.DefaultType), extra, filterRepositories, allRepositories) - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = - ( - 4.0.0 - { makeModuleID(module) } - {moduleInfo.nameFormal} - { makeStartYear(moduleInfo) } - { makeOrganization(moduleInfo) } - { makeScmInfo(moduleInfo) } - { extra } - { - val deps = depsInConfs(module, configurations) - makeProperties(module, deps) ++ - makeDependencies(deps, includeTypes) - } - { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } - ) + def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) + @deprecated("Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", "0.11.2") + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + toPom(ivy, module, moduleInfo, configurations, Set(Artifact.DefaultType), extra, filterRepositories, allRepositories) + def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + ( + 4.0.0 + { makeModuleID(module) } + { moduleInfo.nameFormal } + { makeStartYear(moduleInfo) } + { makeOrganization(moduleInfo) } + { makeScmInfo(moduleInfo) } + { extra } + { + val deps = depsInConfs(module, configurations) + makeProperties(module, deps) ++ + makeDependencies(deps, includeTypes) + } + { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } + ) - def makeModuleID(module: ModuleDescriptor): NodeSeq = - { - val mrid = moduleDescriptor(module) - val a: NodeSeq = - ({ mrid.getOrganisation } - { mrid.getName } - { packaging(module) }) - val b: NodeSeq = - ( (description(module.getDescription) ++ - homePage(module.getHomePage) ++ - revision(mrid.getRevision) ++ - licenses(module.getLicenses)) : NodeSeq ) - a ++ b - } + def makeModuleID(module: ModuleDescriptor): NodeSeq = + { + val mrid = moduleDescriptor(module) + val a: NodeSeq = + ({ mrid.getOrganisation } + { mrid.getName } + { packaging(module) }) + val b: NodeSeq = + ((description(module.getDescription) ++ + homePage(module.getHomePage) ++ + revision(mrid.getRevision) ++ + licenses(module.getLicenses)): NodeSeq) + a ++ b + } - def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = - moduleInfo.startYear match { - case Some(y) => {y} - case _ => NodeSeq.Empty - } - def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = - { - - {moduleInfo.organizationName} - { moduleInfo.organizationHomepage match { - case Some(h) => {h} - case _ => NodeSeq.Empty - }} - - } - def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = - { - moduleInfo.scmInfo match { - case Some(s) => - - {s.browseUrl} - {s.connection} - {s.devConnection match { - case Some(d) => {d} - case _ => NodeSeq.Empty - }} - - case _ => NodeSeq.Empty - } - } - def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = - { - val extra = IvySbt.getExtraAttributes(module) - val depExtra = CustomPomParser.writeDependencyExtra(dependencies).mkString("\n") - val allExtra = if(depExtra.isEmpty) extra else extra.updated(CustomPomParser.ExtraAttributesKey, depExtra) - if(allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) - } - def makeProperties(extra: Map[String,String]): NodeSeq = { - def _extraAttributes(k: String) = if (k == CustomPomParser.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null - { - for( (key,value) <- extra ) yield - ({value}).copy(label = key, attributes = _extraAttributes(key)) - } - } + def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = + moduleInfo.startYear match { + case Some(y) => { y } + case _ => NodeSeq.Empty + } + def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = + { + + { moduleInfo.organizationName } + { + moduleInfo.organizationHomepage match { + case Some(h)=> { h } + case _ => NodeSeq.Empty + } + } + + } + def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = + { + moduleInfo.scmInfo match { + case Some(s) => + + { s.browseUrl } + { s.connection } + { + s.devConnection match { + case Some(d)=> { d } + case _=> NodeSeq.Empty + } + } + + case _ => NodeSeq.Empty + } + } + def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = + { + val extra = IvySbt.getExtraAttributes(module) + val depExtra = CustomPomParser.writeDependencyExtra(dependencies).mkString("\n") + val allExtra = if (depExtra.isEmpty) extra else extra.updated(CustomPomParser.ExtraAttributesKey, depExtra) + if (allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) + } + def makeProperties(extra: Map[String, String]): NodeSeq = { + def _extraAttributes(k: String) = if (k == CustomPomParser.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null + { + for ((key, value) <- extra) yield ({ value }).copy(label = key, attributes = _extraAttributes(key)) + } + } - /** - * Attribute tag that PrettyPrinter won't ignore, saying "don't mess with my spaces" - * Without this, PrettyPrinter will flatten multiple entries for ExtraDependencyAttributes and make them - * unparseable. (e.g. a plugin that depends on multiple plugins will fail) - */ - def xmlSpacePreserve = new PrefixedAttribute("xml", "space", "preserve", scala.xml.Null) + /** + * Attribute tag that PrettyPrinter won't ignore, saying "don't mess with my spaces" + * Without this, PrettyPrinter will flatten multiple entries for ExtraDependencyAttributes and make them + * unparseable. (e.g. a plugin that depends on multiple plugins will fail) + */ + def xmlSpacePreserve = new PrefixedAttribute("xml", "space", "preserve", scala.xml.Null) - def description(d: String) = if((d eq null) || d.isEmpty) NodeSeq.Empty else {d} - def licenses(ls: Array[License]) = if(ls == null || ls.isEmpty) NodeSeq.Empty else {ls.map(license)} - def license(l: License) = - - {l.getName} - {l.getUrl} - repo - - def homePage(homePage: String) = if(homePage eq null) NodeSeq.Empty else {homePage} - def revision(version: String) = if(version ne null) {version} else NodeSeq.Empty - def packaging(module: ModuleDescriptor) = - module.getAllArtifacts match - { - case Array() => "pom" - case Array(x) => x.getType - case xs => - val types = xs.map(_.getType).toList.filterNot(IgnoreTypes) - types match { - case Nil => Artifact.PomType - case xs if xs.contains(Artifact.DefaultType) => Artifact.DefaultType - case x :: xs => x - } - } - val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) + def description(d: String) = if ((d eq null) || d.isEmpty) NodeSeq.Empty else { d } + def licenses(ls: Array[License]) = if (ls == null || ls.isEmpty) NodeSeq.Empty else { ls.map(license) } + def license(l: License) = + + { l.getName } + { l.getUrl } + repo + + def homePage(homePage: String) = if (homePage eq null) NodeSeq.Empty else { homePage } + def revision(version: String) = if (version ne null) { version } else NodeSeq.Empty + def packaging(module: ModuleDescriptor) = + module.getAllArtifacts match { + case Array() => "pom" + case Array(x) => x.getType + case xs => + val types = xs.map(_.getType).toList.filterNot(IgnoreTypes) + types match { + case Nil => Artifact.PomType + case xs if xs.contains(Artifact.DefaultType) => Artifact.DefaultType + case x :: xs => x + } + } + val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) - def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = - if(dependencies.isEmpty) - NodeSeq.Empty - else - - { dependencies.map(makeDependency(_, includeTypes)) } - + def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = + if (dependencies.isEmpty) + NodeSeq.Empty + else + + { dependencies.map(makeDependency(_, includeTypes)) } + - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = - { - val artifacts = dependency.getAllDependencyArtifacts - val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) - if(artifacts.isEmpty) { - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None) - } - else if(includeArtifacts.isEmpty) - NodeSeq.Empty - else - NodeSeq.fromSeq(artifacts.map( a => makeDependencyElem(dependency, a) )) - } + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = + { + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if (artifacts.isEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None) + } else if (includeArtifacts.isEmpty) + NodeSeq.Empty + else + NodeSeq.fromSeq(artifacts.map(a => makeDependencyElem(dependency, a))) + } - def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Elem = - { - val configs = artifact.getConfigurations.toList match { - case Nil | "*" :: Nil => dependency.getModuleConfigurations - case x => x.toArray - } - val (scope, optional) = getScopeAndOptional(configs) - val classifier = artifactClassifier(artifact) - val baseType = artifactType(artifact) - val tpe = (classifier, baseType) match { - case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None - case _ => baseType - } - makeDependencyElem(dependency, scope, optional, classifier, tpe) - } - def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = - { - val mrid = dependency.getDependencyRevisionId - - {mrid.getOrganisation} - {mrid.getName} - {makeDependencyVersion(mrid.getRevision)} - { scopeElem(scope) } - { optionalElem(optional) } - { classifierElem(classifier) } - { typeElem(tpe) } - { exclusions(dependency) } - - } + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Elem = + { + val configs = artifact.getConfigurations.toList match { + case Nil | "*" :: Nil => dependency.getModuleConfigurations + case x => x.toArray + } + val (scope, optional) = getScopeAndOptional(configs) + val classifier = artifactClassifier(artifact) + val baseType = artifactType(artifact) + val tpe = (classifier, baseType) match { + case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None + case _ => baseType + } + makeDependencyElem(dependency, scope, optional, classifier, tpe) + } + def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = + { + val mrid = dependency.getDependencyRevisionId + + { mrid.getOrganisation } + { mrid.getName } + { makeDependencyVersion(mrid.getRevision) } + { scopeElem(scope) } + { optionalElem(optional) } + { classifierElem(classifier) } + { typeElem(tpe) } + { exclusions(dependency) } + + } + def makeDependencyVersion(revision: String): String = { + def plusRange(s: String, shift: Int = 0) = { + def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 + val (prefixVersion, lastVersion) = (s + "0" * shift).reverse.split("\\.", 2) match { + case Array(revLast, revRest) => + (revRest.reverse + ".", revLast.reverse) + case Array(revLast) => ("", revLast.reverse) + } + val lastVersionInt = lastVersion.toInt + s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt + pow(shift)})" + } + val startSym = Set(']', '[', '(') + val stopSym = Set(']', '[', ')') + try { + if (revision endsWith ".+") { + plusRange(revision.substring(0, revision.length - 2)) + } else if (revision endsWith "+") { + val base = revision.take(revision.length - 1) + // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so + // we assume version ranges never go beyond 5 siginificant digits. + (0 to 5).map(plusRange(base, _)).mkString(",") + } else if (startSym(revision(0)) && stopSym(revision(revision.length - 1))) { + val start = revision(0) + val stop = revision(revision.length - 1) + val mid = revision.substring(1, revision.length - 1) + (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + } else revision + } catch { + case e: NumberFormatException => + // TODO - if the version doesn't meet our expectations, maybe we just issue a hard + // error instead of softly ignoring the attempt to rewrite. + //sys.error(s"Could not fix version [$revision] into maven style version") + revision + } + } + @deprecated("No longer used and will be removed.", "0.12.1") + def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = + { + val jarDep = dependency.getAllDependencyArtifacts.filter(d => includeTypes(d.getType)).headOption + jarDep match { + case Some(a) => classifierElem(artifactClassifier(a)) + case None => NodeSeq.Empty + } + } + def artifactType(artifact: DependencyArtifactDescriptor): Option[String] = + Option(artifact.getType).flatMap { tpe => if (tpe == "jar") None else Some(tpe) } + def typeElem(tpe: Option[String]): NodeSeq = + tpe match { + case Some(t) => { t } + case None => NodeSeq.Empty + } - def makeDependencyVersion(revision: String): String = { - def plusRange(s:String, shift:Int = 0) = { - def pow(i:Int):Int = if (i>0) 10 * pow(i-1) else 1 - val (prefixVersion, lastVersion) = (s+"0"*shift).reverse.split("\\.",2) match { - case Array(revLast,revRest) => - ( revRest.reverse + ".", revLast.reverse ) - case Array(revLast) => ("", revLast.reverse) - } - val lastVersionInt = lastVersion.toInt - s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt+pow(shift)})" - } - val startSym=Set(']','[','(') - val stopSym=Set(']','[',')') - try { - if (revision endsWith ".+") { - plusRange(revision.substring(0,revision.length-2)) - } else if (revision endsWith "+") { - val base = revision.take(revision.length-1) - // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so - // we assume version ranges never go beyond 5 siginificant digits. - (0 to 5).map(plusRange(base,_)).mkString(",") - } else if (startSym(revision(0)) && stopSym(revision(revision.length-1))) { - val start = revision(0) - val stop = revision(revision.length-1) - val mid = revision.substring(1,revision.length-1) - (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) - } else revision - } catch { - case e: NumberFormatException => - // TODO - if the version doesn't meet our expectations, maybe we just issue a hard - // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") - revision - } - } + def artifactClassifier(artifact: DependencyArtifactDescriptor): Option[String] = + Option(artifact.getExtraAttribute("classifier")) + def classifierElem(classifier: Option[String]): NodeSeq = + classifier match { + case Some(c) => { c } + case None => NodeSeq.Empty + } - @deprecated("No longer used and will be removed.", "0.12.1") - def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = - { - val jarDep = dependency.getAllDependencyArtifacts.filter(d => includeTypes(d.getType)).headOption - jarDep match { - case Some(a) => classifierElem(artifactClassifier(a)) - case None => NodeSeq.Empty - } - } - def artifactType(artifact: DependencyArtifactDescriptor): Option[String] = - Option(artifact.getType).flatMap { tpe => if(tpe == "jar") None else Some(tpe) } - def typeElem(tpe: Option[String]): NodeSeq = - tpe match { - case Some(t) => {t} - case None => NodeSeq.Empty - } - - def artifactClassifier(artifact: DependencyArtifactDescriptor): Option[String] = - Option(artifact.getExtraAttribute("classifier")) - def classifierElem(classifier: Option[String]): NodeSeq = - classifier match { - case Some(c) => {c} - case None => NodeSeq.Empty - } + @deprecated("No longer used and will be removed.", "0.12.1") + def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = + { + val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) + scopeElem(scope) ++ optionalElem(opt) + } + def scopeElem(scope: Option[String]): NodeSeq = scope match { + case None | Some(Configurations.Compile.name) => NodeSeq.Empty + case Some(s) => { s } + } + def optionalElem(opt: Boolean) = if (opt) true else NodeSeq.Empty + def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId - @deprecated("No longer used and will be removed.", "0.12.1") - def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = - { - val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) - scopeElem(scope) ++ optionalElem(opt) - } - def scopeElem(scope: Option[String]): NodeSeq = scope match { - case None | Some(Configurations.Compile.name) => NodeSeq.Empty - case Some(s) => {s} - } - def optionalElem(opt: Boolean) = if(opt) true else NodeSeq.Empty - def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId + def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = + { + val (opt, notOptional) = confs.partition(_ == Optional.name) + val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) + val scope = defaultNotOptional.map(_.name) + (scope, !opt.isEmpty) + } - def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = - { - val (opt, notOptional) = confs.partition(_ == Optional.name) - val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) - val scope = defaultNotOptional.map(_.name) - (scope, !opt.isEmpty) - } + def exclusions(dependency: DependencyDescriptor): NodeSeq = + { + val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) + val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) + if (!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) + if (!excls.isEmpty) { excls } + else NodeSeq.Empty + } + def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = + { + val m = exclRule.getId.getModuleId + val (g, a) = (m.getOrganisation, m.getName) + if (g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") + Left("Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.".format(m)) + else + Right( + + { g } + { a } + + ) + } - def exclusions(dependency: DependencyDescriptor): NodeSeq = - { - val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) - val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) - if(!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) - if(!excls.isEmpty) {excls} - else NodeSeq.Empty - } - def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = - { - val m = exclRule.getId.getModuleId - val (g, a) = (m.getOrganisation, m.getName) - if(g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") - Left("Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.".format(m)) - else - Right( - - {g} - {a} - - ) - } + def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = + { + class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) + val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) + val mavenRepositories = + repositories.flatMap { + case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => + MavenRepository(m.getName, m.getRoot) :: Nil + case _ => Nil + } + val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) + if (repositoryElements.isEmpty) repositoryElements else { repositoryElements } + } + def allResolvers(settings: IvySettings): Seq[DependencyResolver] = flatten(castResolvers(settings.getResolvers)).distinct + def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if (rs eq null) Nil else rs.flatMap(resolvers) + def resolvers(r: DependencyResolver): Seq[DependencyResolver] = + r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } - def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = - { - class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) - val repositories = if(includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) - val mavenRepositories = - repositories.flatMap { - case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => - MavenRepository(m.getName, m.getRoot) :: Nil - case _ => Nil - } - val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) - if(repositoryElements.isEmpty) repositoryElements else {repositoryElements} - } - def allResolvers(settings: IvySettings): Seq[DependencyResolver] = flatten(castResolvers(settings.getResolvers)).distinct - def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if(rs eq null) Nil else rs.flatMap(resolvers) - def resolvers(r: DependencyResolver): Seq[DependencyResolver] = - r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } + // cast the contents of a pre-generics collection + private def castResolvers(s: java.util.Collection[_]): Seq[DependencyResolver] = + s.toArray.map(_.asInstanceOf[DependencyResolver]) - // cast the contents of a pre-generics collection - private def castResolvers(s: java.util.Collection[_]): Seq[DependencyResolver] = - s.toArray.map(_.asInstanceOf[DependencyResolver]) + def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) + def isValidIDCharacter(c: Char) = c.isLetterOrDigit + private def checkID(id: String, name: String) = if (id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id + def mavenRepository(repo: MavenRepository): XNode = + mavenRepository(toID(repo.name), repo.name, repo.root) + def mavenRepository(id: String, name: String, root: String): XNode = + + { id } + { name } + { root } + { if (name == JavaNet1Repository.name) "legacy" else "default" } + - def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) - def isValidIDCharacter(c: Char) = c.isLetterOrDigit - private def checkID(id: String, name: String) = if(id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id - def mavenRepository(repo: MavenRepository): XNode = - mavenRepository(toID(repo.name), repo.name, repo.root) - def mavenRepository(id: String, name: String, root: String): XNode = - - {id} - {name} - {root} - { if(name == JavaNet1Repository.name) "legacy" else "default" } - - - /** Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. - * This currently only preserves the information required by makePom*/ - private def depsInConfs(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): Seq[DependencyDescriptor] = - { - val keepConfigurations = IvySbt.getConfigurations(module, configurations) - val keepSet = Set(keepConfigurations.toSeq : _*) - def translate(dependency: DependencyDescriptor) = - { - val keep = dependency.getModuleConfigurations.filter(keepSet.contains) - if(keep.isEmpty) - None - else // TODO: translate the dependency to contain only configurations to keep - Some(dependency) - } - module.getDependencies flatMap translate - } + /** + * Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. + * This currently only preserves the information required by makePom + */ + private def depsInConfs(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): Seq[DependencyDescriptor] = + { + val keepConfigurations = IvySbt.getConfigurations(module, configurations) + val keepSet = Set(keepConfigurations.toSeq: _*) + def translate(dependency: DependencyDescriptor) = + { + val keep = dependency.getModuleConfigurations.filter(keepSet.contains) + if (keep.isEmpty) + None + else // TODO: translate the dependency to contain only configurations to keep + Some(dependency) + } + module.getDependencies flatMap translate + } } diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index e37c84da2..178940666 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -3,103 +3,121 @@ */ package sbt - import java.net.URL +import java.net.URL -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String,String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) -{ - override def toString: String = - organization + ":" + name + ":" + revision + - (configurations match { case Some(s) => ":" + s; case None => "" }) + - (if(extraAttributes.isEmpty) "" else " " + extraString) +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { + override def toString: String = + organization + ":" + name + ":" + revision + + (configurations match { case Some(s) => ":" + s; case None => "" }) + + (if (extraAttributes.isEmpty) "" else " " + extraString) - /** String representation of the extra attributes, excluding any information only attributes. */ - def extraString: String = extraDependencyAttributes.map { case (k,v) => k + "=" + v } mkString("(",", ",")") + /** String representation of the extra attributes, excluding any information only attributes. */ + def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") - /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ - def extraDependencyAttributes: Map[String,String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) + /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ + def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean): ModuleID = cross(if(v) CrossVersion.binary else CrossVersion.Disabled) + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") + def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else CrossVersion.Disabled) - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if(v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) + @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") + def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) - /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ - def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) + /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ + def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) - // () required for chaining - /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ - def notTransitive() = intransitive() + // () required for chaining + /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ + def notTransitive() = intransitive() - /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ - def intransitive() = copy(isTransitive = false) + /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ + def intransitive() = copy(isTransitive = false) - /** Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, - * redownload it. sbt configures all -SNAPSHOT dependencies to be changing. - * - * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. - * */ - def changing() = copy(isChanging = true) + /** + * Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, + * redownload it. sbt configures all -SNAPSHOT dependencies to be changing. + * + * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. + */ + def changing() = copy(isChanging = true) - /** Indicates that conflict resolution should only select this module's revision. - * This prevents a newer revision from being pulled in by a transitive dependency, for example.*/ - def force() = copy(isForce = true) + /** + * Indicates that conflict resolution should only select this module's revision. + * This prevents a newer revision from being pulled in by a transitive dependency, for example. + */ + def force() = copy(isForce = true) - /** Specifies a URL from which the main artifact for this dependency can be downloaded. - * This value is only consulted if the module is not found in a repository. - * It is not included in published metadata.*/ - def from(url: String) = artifacts(Artifact(name, new URL(url))) + /** + * Specifies a URL from which the main artifact for this dependency can be downloaded. + * This value is only consulted if the module is not found in a repository. + * It is not included in published metadata. + */ + def from(url: String) = artifacts(Artifact(name, new URL(url))) - /** Adds a dependency on the artifact for this module with classifier `c`. */ - def classifier(c: String) = artifacts(Artifact(name, c)) + /** Adds a dependency on the artifact for this module with classifier `c`. */ + def classifier(c: String) = artifacts(Artifact(name, c)) - /** Declares the explicit artifacts for this module. If this ModuleID represents a dependency, - * these artifact definitions override the information in the dependency's published metadata. */ - def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + /** + * Declares the explicit artifacts for this module. If this ModuleID represents a dependency, + * these artifact definitions override the information in the dependency's published metadata. + */ + def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) - /** Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify - * both the exact organization and name and nothing else will be included in a pom.xml.*/ - def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + /** + * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify + * both the exact organization and name and nothing else will be included in a pom.xml. + */ + def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) - /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) + /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ + def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) - /** Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. - * This information will only be published in an ivy.xml and not in a pom.xml. */ - def extra(attributes: (String,String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) + /** + * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. + * This information will only be published in an ivy.xml and not in a pom.xml. + */ + def extra(attributes: (String, String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" - * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead.*/ - def sources() = artifacts(Artifact.sources(name)) + /** + * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead. + */ + def sources() = artifacts(Artifact.sources(name)) - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" - * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead.*/ - def javadoc() = artifacts(Artifact.javadoc(name)) + /** + * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead. + */ + def javadoc() = artifacts(Artifact.javadoc(name)) - def pomOnly() = artifacts(Artifact.pom(name)) + def pomOnly() = artifacts(Artifact.pom(name)) - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" - * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ - def withSources() = jarIfEmpty.sources() + /** + * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one. + */ + def withSources() = jarIfEmpty.sources() - /** Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred - * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" - * classifier. If there is not already an explicit dependency on the main artifact, this adds one.*/ - def withJavadoc() = jarIfEmpty.javadoc() + /** + * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred + * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" + * classifier. If there is not already an explicit dependency on the main artifact, this adds one. + */ + def withJavadoc() = jarIfEmpty.javadoc() - private def jarIfEmpty = if(explicitArtifacts.isEmpty) jar() else this + private def jarIfEmpty = if (explicitArtifacts.isEmpty) jar() else this - /** Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such - * as when adding a dependency on an artifact with a classifier.*/ - def jar() = artifacts(Artifact(name)) + /** + * Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such + * as when adding a dependency on an artifact with a classifier. + */ + def jar() = artifacts(Artifact(name)) } -object ModuleID -{ - /** Prefixes all keys with `e:` if they are not already so prefixed. */ - def checkE(attributes: Seq[(String, String)]) = - for ( (key, value) <- attributes) yield - if(key.startsWith("e:")) (key, value) else ("e:" + key, value) +object ModuleID { + /** Prefixes all keys with `e:` if they are not already so prefixed. */ + def checkE(attributes: Seq[(String, String)]) = + for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) } diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index 917889db8..caff3d496 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -3,87 +3,88 @@ */ package sbt - import java.io.File - import java.util.Date +import java.io.File +import java.util.Date - import org.apache.ivy.{core,plugins} - import core.{cache,module, report, resolve,search} - import cache.{ArtifactOrigin,RepositoryCacheManager} - import search.{ModuleEntry, OrganisationEntry, RevisionEntry} - import module.id.ModuleRevisionId - import module.descriptor.{Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor} - import plugins.namespace.Namespace - import plugins.resolver.{DependencyResolver,ResolverSettings} - import report.{ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport} - import resolve.{DownloadOptions, ResolveData, ResolvedModuleRevision} +import org.apache.ivy.{ core, plugins } +import core.{ cache, module, report, resolve, search } +import cache.{ ArtifactOrigin, RepositoryCacheManager } +import search.{ ModuleEntry, OrganisationEntry, RevisionEntry } +import module.id.ModuleRevisionId +import module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor } +import plugins.namespace.Namespace +import plugins.resolver.{ DependencyResolver, ResolverSettings } +import report.{ ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport } +import resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } -/**A Resolver that uses a predefined mapping from module ids to in-memory descriptors. -* It does not handle artifacts.*/ -class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) extends ResolverAdapter -{ - def getName = name - def setName(name: String) = sys.error("Setting name not supported by ProjectResolver") - override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" +/** + * A Resolver that uses a predefined mapping from module ids to in-memory descriptors. + * It does not handle artifacts. + */ +class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) extends ResolverAdapter { + def getName = name + def setName(name: String) = sys.error("Setting name not supported by ProjectResolver") + override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" - def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = - getDependency(dd.getDependencyRevisionId).orNull + def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = + getDependency(dd.getDependencyRevisionId).orNull - private[this] def getDependency(revisionId: ModuleRevisionId): Option[ResolvedModuleRevision] = - { - def constructResult(descriptor: ModuleDescriptor) = new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) - map get revisionId map constructResult - } + private[this] def getDependency(revisionId: ModuleRevisionId): Option[ResolvedModuleRevision] = + { + def constructResult(descriptor: ModuleDescriptor) = new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) + map get revisionId map constructResult + } - def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = - { - val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) - val r = new MetadataArtifactDownloadReport(artifact) - r.setSearched(false) - r.setDownloadStatus(DownloadStatus.FAILED) - r - } + def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = + { + val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) + val r = new MetadataArtifactDownloadReport(artifact) + r.setSearched(false) + r.setDownloadStatus(DownloadStatus.FAILED) + r + } - // this resolver nevers locates artifacts, only resolves dependencies - def exists(artifact: IArtifact) = false - def locate(artifact: IArtifact) = null - def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = - { - val r = new DownloadReport - for(artifact <- artifacts) - if(getDependency(artifact.getModuleRevisionId).isEmpty) - r.addArtifactReport(notDownloaded(artifact)) - r - } + // this resolver nevers locates artifacts, only resolves dependencies + def exists(artifact: IArtifact) = false + def locate(artifact: IArtifact) = null + def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = + { + val r = new DownloadReport + for (artifact <- artifacts) + if (getDependency(artifact.getModuleRevisionId).isEmpty) + r.addArtifactReport(notDownloaded(artifact)) + r + } - def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = - notDownloaded(artifact.getArtifact) - def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null + def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = + notDownloaded(artifact.getArtifact) + def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null - def notDownloaded(artifact: IArtifact): ArtifactDownloadReport= - { - val r = new ArtifactDownloadReport(artifact) - r.setDownloadStatus(DownloadStatus.FAILED) - r - } + def notDownloaded(artifact: IArtifact): ArtifactDownloadReport = + { + val r = new ArtifactDownloadReport(artifact) + r.setDownloadStatus(DownloadStatus.FAILED) + r + } - // doesn't support publishing - def publish(artifact: IArtifact, src: File, overwrite: Boolean) = sys.error("Publish not supported by ProjectResolver") - def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} - def abortPublishTransaction() {} - def commitPublishTransaction() {} + // doesn't support publishing + def publish(artifact: IArtifact, src: File, overwrite: Boolean) = sys.error("Publish not supported by ProjectResolver") + def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} + def abortPublishTransaction() {} + def commitPublishTransaction() {} - def reportFailure() {} - def reportFailure(art: IArtifact) {} + def reportFailure() {} + def reportFailure(art: IArtifact) {} - def listOrganisations() = new Array[OrganisationEntry](0) - def listModules(org: OrganisationEntry) = new Array[ModuleEntry](0) - def listRevisions(module: ModuleEntry) = new Array[RevisionEntry](0) + def listOrganisations() = new Array[OrganisationEntry](0) + def listModules(org: OrganisationEntry) = new Array[ModuleEntry](0) + def listRevisions(module: ModuleEntry) = new Array[RevisionEntry](0) - def getNamespace = Namespace.SYSTEM_NAMESPACE + def getNamespace = Namespace.SYSTEM_NAMESPACE - private[this] var settings: Option[ResolverSettings] = None + private[this] var settings: Option[ResolverSettings] = None - def dumpSettings() {} - def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } - def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } + def dumpSettings() {} + def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } + def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } } diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala index d79f25a4c..41721a784 100644 --- a/ivy/src/main/scala/sbt/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/ResolutionCache.scala @@ -7,84 +7,84 @@ import org.apache.ivy.core import org.apache.ivy.plugins.parser import core.IvyPatternHelper import core.settings.IvySettings -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, DefaultResolutionCacheManager, ResolutionCacheManager} +import core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, DefaultResolutionCacheManager, ResolutionCacheManager } import core.module.id.ModuleRevisionId import core.module.descriptor.ModuleDescriptor -import ResolutionCache.{Name, ReportDirectory, ResolvedName, ResolvedPattern} +import ResolutionCache.{ Name, ReportDirectory, ResolvedName, ResolvedPattern } import parser.xml.XmlModuleDescriptorParser -/** Replaces the standard Ivy resolution cache in order to: -* 1. Separate cached resolved Ivy files from resolution reports, making the resolution reports easier to find. -* 2. Have them per-project for easier cleaning (possible with standard cache, but central to this custom one). -* 3. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. -*/ -private[sbt] final class ResolutionCache(base: File, settings: IvySettings) extends ResolutionCacheManager -{ - private[this] def resolvedFileInCache(m: ModuleRevisionId, name: String, ext: String): File = { - val p = ResolvedPattern - val f = IvyPatternHelper.substitute(p, m.getOrganisation, m.getName, m.getBranch, m.getRevision, name, name, ext, null, null, m.getAttributes, null) - new File(base, f) - } - private[this] val reportBase: File = new File(base, ReportDirectory) +/** + * Replaces the standard Ivy resolution cache in order to: + * 1. Separate cached resolved Ivy files from resolution reports, making the resolution reports easier to find. + * 2. Have them per-project for easier cleaning (possible with standard cache, but central to this custom one). + * 3. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. + */ +private[sbt] final class ResolutionCache(base: File, settings: IvySettings) extends ResolutionCacheManager { + private[this] def resolvedFileInCache(m: ModuleRevisionId, name: String, ext: String): File = { + val p = ResolvedPattern + val f = IvyPatternHelper.substitute(p, m.getOrganisation, m.getName, m.getBranch, m.getRevision, name, name, ext, null, null, m.getAttributes, null) + new File(base, f) + } + private[this] val reportBase: File = new File(base, ReportDirectory) - def getResolutionCacheRoot: File = base - def clean() { IO.delete(base) } - override def toString = Name + def getResolutionCacheRoot: File = base + def clean() { IO.delete(base) } + override def toString = Name - def getResolvedIvyFileInCache(mrid: ModuleRevisionId): File = - resolvedFileInCache(mrid, ResolvedName, "xml") - def getResolvedIvyPropertiesInCache(mrid: ModuleRevisionId): File = - resolvedFileInCache(mrid, ResolvedName, "properties") - // name needs to be the same as Ivy's default because the ivy-report.xsl stylesheet assumes this - // when making links to reports for other configurations - def getConfigurationResolveReportInCache(resolveId: String, conf: String): File = - new File(reportBase, resolveId + "-" + conf + ".xml") - def getConfigurationResolveReportsInCache(resolveId: String): Array[File] = - IO.listFiles(reportBase).filter(_.getName.startsWith(resolveId + "-")) - - // XXX: this method is required by ResolutionCacheManager in Ivy 2.3.0 final, - // but it is apparently unused by Ivy as sbt uses Ivy. Therefore, it is - // unexercised in tests. Note that the implementation of this method in Ivy 2.3.0's - // DefaultResolutionCache also resolves parent properties for a given mrid - def getResolvedModuleDescriptor(mrid: ModuleRevisionId): ModuleDescriptor = { - val ivyFile = getResolvedIvyFileInCache(mrid) - if (!ivyFile.exists()) { - throw new IllegalStateException("Ivy file not found in cache for " + mrid + "!") - } - - return XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, ivyFile.toURI().toURL(), false) - } - - def saveResolvedModuleDescriptor(md: ModuleDescriptor): Unit = { - val mrid = md.getResolvedModuleRevisionId - val cachedIvyFile = getResolvedIvyFileInCache(mrid) - md.toIvyFile(cachedIvyFile) - } + def getResolvedIvyFileInCache(mrid: ModuleRevisionId): File = + resolvedFileInCache(mrid, ResolvedName, "xml") + def getResolvedIvyPropertiesInCache(mrid: ModuleRevisionId): File = + resolvedFileInCache(mrid, ResolvedName, "properties") + // name needs to be the same as Ivy's default because the ivy-report.xsl stylesheet assumes this + // when making links to reports for other configurations + def getConfigurationResolveReportInCache(resolveId: String, conf: String): File = + new File(reportBase, resolveId + "-" + conf + ".xml") + def getConfigurationResolveReportsInCache(resolveId: String): Array[File] = + IO.listFiles(reportBase).filter(_.getName.startsWith(resolveId + "-")) + + // XXX: this method is required by ResolutionCacheManager in Ivy 2.3.0 final, + // but it is apparently unused by Ivy as sbt uses Ivy. Therefore, it is + // unexercised in tests. Note that the implementation of this method in Ivy 2.3.0's + // DefaultResolutionCache also resolves parent properties for a given mrid + def getResolvedModuleDescriptor(mrid: ModuleRevisionId): ModuleDescriptor = { + val ivyFile = getResolvedIvyFileInCache(mrid) + if (!ivyFile.exists()) { + throw new IllegalStateException("Ivy file not found in cache for " + mrid + "!") + } + + return XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, ivyFile.toURI().toURL(), false) + } + + def saveResolvedModuleDescriptor(md: ModuleDescriptor): Unit = { + val mrid = md.getResolvedModuleRevisionId + val cachedIvyFile = getResolvedIvyFileInCache(mrid) + md.toIvyFile(cachedIvyFile) + } } -private[sbt] object ResolutionCache -{ - /** Removes cached files from the resolution cache for the module with ID `mrid` - * and the resolveId (as set on `ResolveOptions`). */ - private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) - { - val files = - Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: - Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: - Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten - IO.delete(files) - } +private[sbt] object ResolutionCache { + /** + * Removes cached files from the resolution cache for the module with ID `mrid` + * and the resolveId (as set on `ResolveOptions`). + */ + private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) { + val files = + Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: + Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: + Option(manager.getConfigurationResolveReportsInCache(resolveId)).toList.flatten + IO.delete(files) + } - private val ReportDirectory = "reports" + private val ReportDirectory = "reports" - // name of the file providing a dependency resolution report for a configuration - private val ReportFileName = "report.xml" + // name of the file providing a dependency resolution report for a configuration + private val ReportFileName = "report.xml" - // base name (name except for extension) of resolution report file - private val ResolvedName = "resolved.xml" + // base name (name except for extension) of resolution report file + private val ResolvedName = "resolved.xml" - // Cache name - private val Name = "sbt-resolution-cache" + // Cache name + private val Name = "sbt-resolution-cache" - // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions - private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]" + // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions + private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]" } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index e72db1e46..f6250705e 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -6,145 +6,131 @@ package sbt import java.io.File import java.net.URL import scala.xml.NodeSeq -import org.apache.ivy.plugins.resolver.{DependencyResolver, IBiblioResolver} +import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } -sealed trait Resolver -{ - def name: String +sealed trait Resolver { + def name: String } -final class RawRepository(val resolver: DependencyResolver) extends Resolver -{ - def name = resolver.getName - override def toString = "Raw(" + resolver.toString + ")" +final class RawRepository(val resolver: DependencyResolver) extends Resolver { + def name = resolver.getName + override def toString = "Raw(" + resolver.toString + ")" } sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver -sealed case class MavenRepository(name: String, root: String) extends Resolver -{ - override def toString = name + ": " + root +sealed case class MavenRepository(name: String, root: String) extends Resolver { + override def toString = name + ": " + root } -final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) -{ - private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) - private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) - private[sbt] def withoutConsistencyCheck(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, true) - private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) - private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) - override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) - override def equals(obj: Any): Boolean = { - obj match { - case other: Patterns => - ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible && descriptorOptional == other.descriptorOptional && skipConsistencyCheck == other.skipConsistencyCheck - case _ => false - } - } - override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode +final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { + private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) + private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) + private[sbt] def withoutConsistencyCheck(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, true) + private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) + private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) + override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + override def equals(obj: Any): Boolean = { + obj match { + case other: Patterns => + ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible && descriptorOptional == other.descriptorOptional && skipConsistencyCheck == other.skipConsistencyCheck + case _ => false + } + } + override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode - @deprecated - def this(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) = this(ivyPatterns, artifactPatterns, isMavenCompatible, false, false) + @deprecated + def this(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) = this(ivyPatterns, artifactPatterns, isMavenCompatible, false, false) } -object Patterns -{ - implicit def defaultPatterns: Patterns = Resolver.defaultPatterns +object Patterns { + implicit def defaultPatterns: Patterns = Resolver.defaultPatterns - def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns : _*) - def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, false, false) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*) + def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, false, false) + def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } -object RepositoryHelpers -{ - final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) - { - def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) - } - /** Configuration specific to an Ivy filesystem resolver. */ - final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) - { - def transactional() = FileConfiguration(isLocal, Some(true)) - def nontransactional() = FileConfiguration(isLocal, Some(false)) - def nonlocal() = FileConfiguration(false, isTransactional) - } - sealed trait SshAuthentication extends NotNull - final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication - final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication +object RepositoryHelpers { + final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) { + def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) + } + /** Configuration specific to an Ivy filesystem resolver. */ + final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) { + def transactional() = FileConfiguration(isLocal, Some(true)) + def nontransactional() = FileConfiguration(isLocal, Some(false)) + def nonlocal() = FileConfiguration(false, isTransactional) + } + sealed trait SshAuthentication extends NotNull + final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication + final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication } -import RepositoryHelpers.{SshConnection, FileConfiguration} -import RepositoryHelpers.{KeyFileAuthentication, PasswordAuthentication, SshAuthentication} +import RepositoryHelpers.{ SshConnection, FileConfiguration } +import RepositoryHelpers.{ KeyFileAuthentication, PasswordAuthentication, SshAuthentication } /** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ -sealed abstract class PatternsBasedRepository extends Resolver -{ - type RepositoryType <: PatternsBasedRepository - /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ - protected def copy(patterns: Patterns): RepositoryType +sealed abstract class PatternsBasedRepository extends Resolver { + type RepositoryType <: PatternsBasedRepository + /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ + protected def copy(patterns: Patterns): RepositoryType - /** The object representing the configured patterns for this repository. */ - def patterns: Patterns + /** The object representing the configured patterns for this repository. */ + def patterns: Patterns - /** Enables maven 2 compatibility for this repository. */ - def mavenStyle() = copy(patterns.mavenStyle()) + /** Enables maven 2 compatibility for this repository. */ + def mavenStyle() = copy(patterns.mavenStyle()) - /** Makes descriptor metadata optional for this repository. */ - def descriptorOptional() = copy(patterns.withDescriptorOptional()) + /** Makes descriptor metadata optional for this repository. */ + def descriptorOptional() = copy(patterns.withDescriptorOptional()) - /** Disables consistency checking for this repository. */ - def skipConsistencyCheck() = copy(patterns.withoutConsistencyCheck()) + /** Disables consistency checking for this repository. */ + def skipConsistencyCheck() = copy(patterns.withoutConsistencyCheck()) - /** Adds the given patterns for resolving/publishing Ivy files.*/ - def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) - /** Adds the given patterns for resolving/publishing artifacts.*/ - def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) + /** Adds the given patterns for resolving/publishing Ivy files.*/ + def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) + /** Adds the given patterns for resolving/publishing artifacts.*/ + def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) } /** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ -final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository -{ - type RepositoryType = FileRepository - protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) - private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) - def transactional() = copy(configuration.transactional()) - def nonlocal() = copy(configuration.nonlocal()) +final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository { + type RepositoryType = FileRepository + protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) + private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) + def transactional() = copy(configuration.transactional()) + def nonlocal() = copy(configuration.nonlocal()) } -final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository -{ - type RepositoryType = URLRepository - protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) +final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository { + type RepositoryType = URLRepository + protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) } /** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ -sealed abstract class SshBasedRepository extends PatternsBasedRepository -{ - type RepositoryType <: SshBasedRepository - protected def copy(connection: SshConnection): RepositoryType - private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) +sealed abstract class SshBasedRepository extends PatternsBasedRepository { + type RepositoryType <: SshBasedRepository + protected def copy(connection: SshConnection): RepositoryType + private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) - /** The object representing the configured ssh connection for this repository. */ - def connection: SshConnection + /** The object representing the configured ssh connection for this repository. */ + def connection: SshConnection - /** Configures this to use the specified user name and password when connecting to the remote repository. */ - def as(user: String, password: String): RepositoryType = as(user, Some(password)) - def as(user: String): RepositoryType = as(user, None) - def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) - /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ - def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) - def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) - def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) + /** Configures this to use the specified user name and password when connecting to the remote repository. */ + def as(user: String, password: String): RepositoryType = as(user, Some(password)) + def as(user: String): RepositoryType = as(user, None) + def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) + /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ + def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) + def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) + def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) } /** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ -final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository -{ - type RepositoryType = SshRepository - protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - /** Defines the permissions to set when publishing to this repository. */ - def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) - def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) +final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository { + type RepositoryType = SshRepository + protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) + /** Defines the permissions to set when publishing to this repository. */ + def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) + def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) } /** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ -final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository -{ - type RepositoryType = SftpRepository - protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) - protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) +final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository { + type RepositoryType = SftpRepository + protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) + protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) } import Resolver._ @@ -152,151 +138,163 @@ import Resolver._ object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JavaNet1Repository extends JavaNet1Repository -sealed trait JavaNet1Repository extends Resolver -{ - def name = "java.net Maven1 Repository" +sealed trait JavaNet1Repository extends Resolver { + def name = "java.net Maven1 Repository" } -object Resolver -{ - val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" - val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" - val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" +object Resolver { + val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" + val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" + val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" - // obsolete: kept only for launcher compatibility - private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" - private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" - private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" - private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" - private[sbt] val ScalaToolsReleases = new MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) - private[sbt] val ScalaToolsSnapshots = new MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) + // obsolete: kept only for launcher compatibility + private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" + private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" + private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" + private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" + private[sbt] val ScalaToolsReleases = new MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) + private[sbt] val ScalaToolsSnapshots = new MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) - val JavaNet2RepositoryName = "java.net Maven2 Repository" - val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" + val JavaNet2RepositoryName = "java.net Maven2 Repository" + val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" - def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) - def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) - def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) - def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) + def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) + def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) + def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) - /** Add the local and Maven Central repositories to the user repositories. */ - def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = - withDefaultResolvers(userResolvers, true) - /** Add the local Ivy repository to the user repositories. - * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = - Seq(Resolver.defaultLocal) ++ - userResolvers ++ - single(DefaultMavenRepository, mavenCentral) - private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if(nonEmpty) Seq(value) else Nil + /** Add the local and Maven Central repositories to the user repositories. */ + def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = + withDefaultResolvers(userResolvers, true) + /** + * Add the local Ivy repository to the user repositories. + * If `mavenCentral` is true, add the Maven Central repository. + */ + def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = + Seq(Resolver.defaultLocal) ++ + userResolvers ++ + single(DefaultMavenRepository, mavenCentral) + private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if (nonEmpty) Seq(value) else Nil - /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ - sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull - { - /** Subclasses should implement this method to */ - protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType - /** Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject - * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, None, None, None) - /** Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), None, None) - /** Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), None, Some(basePath)) - /** Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), Some(port), None) - /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = - apply(name, Some(hostname), Some(port), Some(basePath)) - /** Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial - * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). - * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns.*/ - def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = - construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) - } - /** A factory to construct an interface to an Ivy SSH resolver.*/ - object ssh extends Define[SshRepository] - { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) - } - /** A factory to construct an interface to an Ivy SFTP resolver.*/ - object sftp extends Define[SftpRepository] - { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) - } - /** A factory to construct an interface to an Ivy filesytem resolver. */ - object file - { - /** Constructs a file resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) - /** Constructs a file resolver with the given name and base directory. */ - def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) - } - object url - { - /** Constructs a URL resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object.*/ - def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) - /** Constructs a file resolver with the given name and base directory. */ - def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = - baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) - } - private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = - construct(resolvePatterns(base, basePatterns)) + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull { + /** Subclasses should implement this method to */ + protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType + /** + * Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject + * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, None, None, None) + /** + * Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, None) + /** + * Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), None, Some(basePath)) + /** + * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), None) + /** + * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + apply(name, Some(hostname), Some(port), Some(basePath)) + /** + * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial + * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). + * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. + */ + def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = + construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) + } + /** A factory to construct an interface to an Ivy SSH resolver.*/ + object ssh extends Define[SshRepository] { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) + } + /** A factory to construct an interface to an Ivy SFTP resolver.*/ + object sftp extends Define[SftpRepository] { + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) + } + /** A factory to construct an interface to an Ivy filesytem resolver. */ + object file { + /** + * Constructs a file resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object. + */ + def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = + baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) + } + object url { + /** + * Constructs a URL resolver with the given name. The patterns to use must be explicitly specified + * using the `ivys` or `artifacts` methods on the constructed resolver object. + */ + def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ + def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = + baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) + } + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = + construct(resolvePatterns(base, basePatterns)) - /** If `base` is None, `patterns` is returned unchanged. - * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. */ - private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = - base match - { - case Some(path) => resolvePatterns(path, patterns) - case None => patterns - } - /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ - private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = - { - def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) - Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) - } - private[sbt] def resolvePattern(base: String, pattern: String): String = - { - val normBase = base.replace('\\', '/') - if(normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern - } - def defaultFileConfiguration = FileConfiguration(true, None) - def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) - def ivyStylePatterns = defaultIvyPatterns//Patterns(Nil, Nil, false) + /** + * If `base` is None, `patterns` is returned unchanged. + * Otherwise, the ivy file and artifact patterns in `patterns` are resolved against the given base. + */ + private def resolvePatterns(base: Option[String], patterns: Patterns): Patterns = + base match { + case Some(path) => resolvePatterns(path, patterns) + case None => patterns + } + /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ + private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = + { + def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) + Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) + } + private[sbt] def resolvePattern(base: String, pattern: String): String = + { + val normBase = base.replace('\\', '/') + if (normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern + } + def defaultFileConfiguration = FileConfiguration(true, None) + def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) + def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) - def defaultPatterns = mavenStylePatterns - def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" - def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" - final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" + def defaultPatterns = mavenStylePatterns + def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" + def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" + def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" + final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - private[this] def mavenLocalDir = new File(Path.userHome, ".m2/repository/") - def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) - def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) - def defaultLocal = defaultUserFileRepository("local") - def defaultShared = defaultUserFileRepository("shared") - def defaultUserFileRepository(id: String) = - { - val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil - FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) - } - def defaultIvyPatterns = - { - val pList = List(localBasePattern) - Patterns(pList, pList, false) - } + private[this] def mavenLocalDir = new File(Path.userHome, ".m2/repository/") + def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) + def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) + def defaultLocal = defaultUserFileRepository("local") + def defaultShared = defaultUserFileRepository("shared") + def defaultUserFileRepository(id: String) = + { + val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil + FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) + } + def defaultIvyPatterns = + { + val pList = List(localBasePattern) + Patterns(pList, pList, false) + } } diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala index caf373d3b..fc8327304 100644 --- a/ivy/src/main/scala/sbt/StringUtilities.scala +++ b/ivy/src/main/scala/sbt/StringUtilities.scala @@ -5,13 +5,11 @@ package sbt import java.util.Locale -object StringUtilities -{ - @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") - def normalize(s: String) = s.toLowerCase(Locale.ENGLISH).replaceAll("""\W+""", "-") - def nonEmpty(s: String, label: String) - { - require(s.trim.length > 0, label + " cannot be empty.") - } - def appendable(s: String) = if(s.isEmpty) "" else "_" + s +object StringUtilities { + @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") + def normalize(s: String) = s.toLowerCase(Locale.ENGLISH).replaceAll("""\W+""", "-") + def nonEmpty(s: String, label: String) { + require(s.trim.length > 0, label + " cannot be empty.") + } + def appendable(s: String) = if (s.isEmpty) "" else "_" + s } diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 071643eb2..71d58390b 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -3,142 +3,138 @@ */ package sbt - import java.io.File +import java.io.File -/** Provides information about dependency resolution. -* It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. -* This means that for a given configuration, there should only be one revision for a given organization and module name. -* @param cachedDescriptor the location of the resolved module descriptor in the cache -* @param configurations a sequence containing one report for each configuration resolved. -* @param stats information about the update that produced this report -* @see sbt.RichUpdateReport -*/ -final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File,Long]) -{ - @deprecated("Use the variant that provides timestamps of files.", "0.13.0") - def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = - this(cachedDescriptor, configurations, stats, Map.empty) +/** + * Provides information about dependency resolution. + * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. + * This means that for a given configuration, there should only be one revision for a given organization and module name. + * @param cachedDescriptor the location of the resolved module descriptor in the cache + * @param configurations a sequence containing one report for each configuration resolved. + * @param stats information about the update that produced this report + * @see sbt.RichUpdateReport + */ +final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File, Long]) { + @deprecated("Use the variant that provides timestamps of files.", "0.13.0") + def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = + this(cachedDescriptor, configurations, stats, Map.empty) - override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString + override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString - /** All resolved modules in all configurations. */ - def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + /** All resolved modules in all configurations. */ + def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct - def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(cachedDescriptor, configurations map { _ retrieve f}, stats, stamps ) + def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = + new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) - /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ - def configuration(s: String) = configurations.find(_.configuration == s) + /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ + def configuration(s: String) = configurations.find(_.configuration == s) - /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ - def allConfigurations: Seq[String] = configurations.map(_.configuration) + /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ + def allConfigurations: Seq[String] = configurations.map(_.configuration) } -/** Provides information about resolution of a single configuration. -* @param configuration the configuration this report is for. -* @param modules a seqeuence containing one report for each module resolved for this configuration. -*/ -final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport], val evicted: Seq[ModuleID]) -{ - override def toString = "\t" + configuration + ":\n" + modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString +/** + * Provides information about resolution of a single configuration. + * @param configuration the configuration this report is for. + * @param modules a seqeuence containing one report for each module resolved for this configuration. + */ +final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport], val evicted: Seq[ModuleID]) { + override def toString = "\t" + configuration + ":\n" + modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString - /** All resolved modules for this configuration. - * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. - */ - def allModules: Seq[ModuleID] = modules.map(mr => addConfiguration(mr.module)) - private[this] def addConfiguration(mod: ModuleID): ModuleID = if(mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod - - def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve( (mid,art,file) => f(configuration, mid, art, file)) }, evicted) + /** + * All resolved modules for this configuration. + * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. + */ + def allModules: Seq[ModuleID] = modules.map(mr => addConfiguration(mr.module)) + private[this] def addConfiguration(mod: ModuleID): ModuleID = if (mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod + + def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = + new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, evicted) } -/** Provides information about the resolution of a module. -* This information is in the context of a specific configuration. -* @param module the `ModuleID` this report is for. -* @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. This File may be in the -*/ -final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) -{ - override def toString = - { - val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) - "\t\t" + module + ": " + - (if(arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" - } - def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = - new ModuleReport(module, artifacts.map { case (art,file) => (art, f(module, art, file)) }, missingArtifacts) +/** + * Provides information about the resolution of a module. + * This information is in the context of a specific configuration. + * @param module the `ModuleID` this report is for. + * @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. This File may be in the + */ +final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) { + override def toString = + { + val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + "\t\t" + module + ": " + + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" + } + def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = + new ModuleReport(module, artifacts.map { case (art, file) => (art, f(module, art, file)) }, missingArtifacts) } -object UpdateReport -{ - implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) +object UpdateReport { + implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) - /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ - final class RichUpdateReport(report: UpdateReport) - { - def recomputeStamps(): UpdateReport = - { - val files = report.cachedDescriptor +: allFiles - val stamps = files.map(f => (f, f.lastModified)).toMap - new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) - } + /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ + final class RichUpdateReport(report: UpdateReport) { + def recomputeStamps(): UpdateReport = + { + val files = report.cachedDescriptor +: allFiles + val stamps = files.map(f => (f, f.lastModified)).toMap + new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) + } - import DependencyFilter._ - /** Obtains all successfully retrieved files in all configurations and modules. */ - def allFiles: Seq[File] = matching(DependencyFilter.allPass) + import DependencyFilter._ + /** Obtains all successfully retrieved files in all configurations and modules. */ + def allFiles: Seq[File] = matching(DependencyFilter.allPass) - /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ + def matching(f: DependencyFilter): Seq[File] = select0(f).distinct - /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ - def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = - matching(DependencyFilter.make(configuration, module, artifact)) + /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ + def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = + matching(DependencyFilter.make(configuration, module, artifact)) - private[this] def select0(f: DependencyFilter): Seq[File] = - for(cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { - if(file == null) error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) - file - } - - /** Constructs a new report that only contains files matching the specified filter.*/ - def filter(f: DependencyFilter): UpdateReport = - moduleReportMap { (configuration, modReport) => - import modReport._ - val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } - val newMissing = missingArtifacts filter { art => f(configuration, module, art) } - new ModuleReport(module, newArtifacts, newMissing) - } - def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = - moduleReportMap { (configuration, modReport) => - val newArtifacts = f(configuration, modReport.module, modReport.artifacts) - new ModuleReport(modReport.module, newArtifacts, Nil) - } + private[this] def select0(f: DependencyFilter): Seq[File] = + for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { + if (file == null) error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) + file + } - def toSeq: Seq[(String, ModuleID, Artifact, File)] = - for(confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield - (confReport.configuration, modReport.module, artifact, file) + /** Constructs a new report that only contains files matching the specified filter.*/ + def filter(f: DependencyFilter): UpdateReport = + moduleReportMap { (configuration, modReport) => + import modReport._ + val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } + val newMissing = missingArtifacts filter { art => f(configuration, module, art) } + new ModuleReport(module, newArtifacts, newMissing) + } + def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = + moduleReportMap { (configuration, modReport) => + val newArtifacts = f(configuration, modReport.module, modReport.artifacts) + new ModuleReport(modReport.module, newArtifacts, Nil) + } - def allMissing: Seq[(String, ModuleID, Artifact)] = - for(confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield - (confReport.configuration, modReport.module, artifact) + def toSeq: Seq[(String, ModuleID, Artifact, File)] = + for (confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) - def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = - moduleReportMap { (configuration, modReport) => - import modReport._ - new ModuleReport(module, artifacts, (missingArtifacts ++ f(module)).distinct) - } + def allMissing: Seq[(String, ModuleID, Artifact)] = + for (confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield (confReport.configuration, modReport.module, artifact) - def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = - { - val newConfigurations = report.configurations.map { confReport => - import confReport._ - val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, evicted) - } - new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) - } - } + def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = + moduleReportMap { (configuration, modReport) => + import modReport._ + new ModuleReport(module, artifacts, (missingArtifacts ++ f(module)).distinct) + } + + def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = modules map { modReport => f(configuration, modReport) } + new ConfigurationReport(configuration, newModules, evicted) + } + new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) + } + } } -final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) -{ - override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") +final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { + override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala b/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala index 7d5812aaf..16a1fa504 100755 --- a/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala +++ b/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala @@ -6,67 +6,62 @@ package impl import StringUtilities.nonEmpty -trait DependencyBuilders -{ - final implicit def toGroupID(groupID: String): GroupID = - { - nonEmpty(groupID, "Group ID") - new GroupID(groupID) - } - final implicit def toRepositoryName(name: String): RepositoryName = - { - nonEmpty(name, "Repository name") - new RepositoryName(name) - } - final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = - { - require(m.configurations.isEmpty, "Configurations already specified for module " + m) - new ModuleIDConfigurable(m) - } +trait DependencyBuilders { + final implicit def toGroupID(groupID: String): GroupID = + { + nonEmpty(groupID, "Group ID") + new GroupID(groupID) + } + final implicit def toRepositoryName(name: String): RepositoryName = + { + nonEmpty(name, "Repository name") + new RepositoryName(name) + } + final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = + { + require(m.configurations.isEmpty, "Configurations already specified for module " + m) + new ModuleIDConfigurable(m) + } } -final class GroupID private[sbt] (groupID: String) -{ - def % (artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) - def %% (artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) +final class GroupID private[sbt] (groupID: String) { + def %(artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) + def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) - @deprecated(deprecationMessage, "0.12.0") - def %% (artifactID: String, crossVersion: String => String) = groupArtifact(artifactID, CrossVersion.binaryMapped(crossVersion)) - @deprecated(deprecationMessage, "0.12.0") - def %% (artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, CrossVersion.binaryMapped(Map(alternatives: _*) orElse { case s => s })) + @deprecated(deprecationMessage, "0.12.0") + def %%(artifactID: String, crossVersion: String => String) = groupArtifact(artifactID, CrossVersion.binaryMapped(crossVersion)) + @deprecated(deprecationMessage, "0.12.0") + def %%(artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, CrossVersion.binaryMapped(Map(alternatives: _*) orElse { case s => s })) - private def groupArtifact(artifactID: String, cross: CrossVersion) = - { - nonEmpty(artifactID, "Artifact ID") - new GroupArtifactID(groupID, artifactID, cross) - } + private def groupArtifact(artifactID: String, cross: CrossVersion) = + { + nonEmpty(artifactID, "Artifact ID") + new GroupArtifactID(groupID, artifactID, cross) + } - private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" + private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" } -final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: CrossVersion) -{ - def % (revision: String): ModuleID = - { - nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(crossVersion) - } +final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: CrossVersion) { + def %(revision: String): ModuleID = + { + nonEmpty(revision, "Revision") + ModuleID(groupID, artifactID, revision).cross(crossVersion) + } } -final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) -{ - def % (configuration: Configuration): ModuleID = %(configuration.name) +final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { + def %(configuration: Configuration): ModuleID = %(configuration.name) - def % (configurations: String): ModuleID = - { - nonEmpty(configurations, "Configurations") - val c = configurations - moduleID.copy(configurations = Some(c)) - } + def %(configurations: String): ModuleID = + { + nonEmpty(configurations, "Configurations") + val c = configurations + moduleID.copy(configurations = Some(c)) + } } -final class RepositoryName private[sbt] (name: String) -{ - def at (location: String) = - { - nonEmpty(location, "Repository location") - new MavenRepository(name, location) - } +final class RepositoryName private[sbt] (name: String) { + def at(location: String) = + { + nonEmpty(location, "Repository location") + new MavenRepository(name, location) + } } diff --git a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala index 3d0d174d8..e59e36e34 100644 --- a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala @@ -16,7 +16,7 @@ import org.apache.ivy.util.url.CredentialsStore */ object ErrorMessageAuthenticator { private var securityWarningLogged = false - + private def originalAuthenticator: Option[Authenticator] = { try { val f = classOf[Authenticator].getDeclaredField("theAuthenticator"); @@ -29,7 +29,7 @@ object ErrorMessageAuthenticator { None } } - + private lazy val ivyOriginalField = { val field = classOf[IvyAuthenticator].getDeclaredField("original") field.setAccessible(true) @@ -42,17 +42,17 @@ object ErrorMessageAuthenticator { val newOriginal = new ErrorMessageAuthenticator(original) ivyOriginalField.set(ivy, newOriginal) } - + try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { case Some(alreadyThere: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) + case originalOpt => installIntoIvyImpl(originalOpt) } catch { - case t: Throwable => + case t: Throwable => Message.debug("Error occurred will trying to install debug messages into Ivy Authentication" + t.getMessage) } Some(ivy) } - + /** Installs the error message authenticator so we have nicer error messages when using java's URL for downloading. */ def install() { // Actually installs the error message authenticator. @@ -62,67 +62,68 @@ object ErrorMessageAuthenticator { case e: SecurityException if !securityWarningLogged => securityWarningLogged = true; Message.warn("Not enough permissions to set the ErorrMessageAuthenticator. " - + "Helpful debug messages disabled!"); - } - // We will try to use the original authenticator as backup authenticator. - // Since there is no getter available, so try to use some reflection to - // obtain it. If that doesn't work, assume there is no original authenticator - def doInstallIfIvy(original: Option[Authenticator]): Unit = - original match { - case Some(installed: ErrorMessageAuthenticator) => // Ignore, we're already installed - case Some(ivy: IvyAuthenticator) => installIntoIvy(ivy) - case original => doInstall(original) - } - doInstallIfIvy(originalAuthenticator) + + "Helpful debug messages disabled!"); + } + // We will try to use the original authenticator as backup authenticator. + // Since there is no getter available, so try to use some reflection to + // obtain it. If that doesn't work, assume there is no original authenticator + def doInstallIfIvy(original: Option[Authenticator]): Unit = + original match { + case Some(installed: ErrorMessageAuthenticator) => // Ignore, we're already installed + case Some(ivy: IvyAuthenticator) => installIntoIvy(ivy) + case original => doInstall(original) + } + doInstallIfIvy(originalAuthenticator) } } /** - * An authenticator which just delegates to a previous authenticator and issues *nice* - * error messages on failure to find credentials. - * - * Since ivy installs its own credentials handler EVERY TIME it resolves or publishes, we want to + * An authenticator which just delegates to a previous authenticator and issues *nice* + * error messages on failure to find credentials. + * + * Since ivy installs its own credentials handler EVERY TIME it resolves or publishes, we want to * install this one at some point and eventually ivy will capture it and use it. */ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticator]) extends Authenticator { - protected override def getPasswordAuthentication(): PasswordAuthentication = { - // We're guaranteed to only get here if Ivy's authentication fails - if (!isProxyAuthentication) { - val host = getRequestingHost - // TODO - levenshtein distance "did you mean" message. - Message.error(s"Unable to find credentials for [${getRequestingPrompt} @ ${host}].") - val configuredRealms = IvyCredentialsLookup.realmsForHost.getOrElse(host, Set.empty) - if(!configuredRealms.isEmpty) { - Message.error(s" Is one of these realms mispelled for host [${host}]:") - configuredRealms foreach { realm => - Message.error(s" * ${realm}") - } - } + protected override def getPasswordAuthentication(): PasswordAuthentication = { + // We're guaranteed to only get here if Ivy's authentication fails + if (!isProxyAuthentication) { + val host = getRequestingHost + // TODO - levenshtein distance "did you mean" message. + Message.error(s"Unable to find credentials for [${getRequestingPrompt} @ ${host}].") + val configuredRealms = IvyCredentialsLookup.realmsForHost.getOrElse(host, Set.empty) + if (!configuredRealms.isEmpty) { + Message.error(s" Is one of these realms mispelled for host [${host}]:") + configuredRealms foreach { realm => + Message.error(s" * ${realm}") } - // TODO - Maybe we should work on a helpful proxy message... - - // TODO - To be more maven friendly, we may want to also try to grab the "first" authentication that shows up for a server and try it. - // or maybe allow that behavior to be configured, since maven users aren't used to realms (which they should be). - - // Grabs the authentication that would have been provided had we not been installed... - def originalAuthentication: Option[PasswordAuthentication] = { - Authenticator.setDefault(original.getOrElse(null)) - try Option(Authenticator.requestPasswordAuthentication( - getRequestingHost, - getRequestingSite, - getRequestingPort, - getRequestingProtocol, - getRequestingPrompt, - getRequestingScheme)) - finally Authenticator.setDefault(this) - } - originalAuthentication.getOrElse(null) + } } + // TODO - Maybe we should work on a helpful proxy message... - /** Returns true if this authentication if for a proxy and not for an HTTP server. - * We want to display different error messages, depending. - */ - private def isProxyAuthentication: Boolean = - getRequestorType == Authenticator.RequestorType.PROXY + // TODO - To be more maven friendly, we may want to also try to grab the "first" authentication that shows up for a server and try it. + // or maybe allow that behavior to be configured, since maven users aren't used to realms (which they should be). + + // Grabs the authentication that would have been provided had we not been installed... + def originalAuthentication: Option[PasswordAuthentication] = { + Authenticator.setDefault(original.getOrElse(null)) + try Option(Authenticator.requestPasswordAuthentication( + getRequestingHost, + getRequestingSite, + getRequestingPort, + getRequestingProtocol, + getRequestingPrompt, + getRequestingScheme)) + finally Authenticator.setDefault(this) + } + originalAuthentication.getOrElse(null) + } + + /** + * Returns true if this authentication if for a proxy and not for an HTTP server. + * We want to display different error messages, depending. + */ + private def isProxyAuthentication: Boolean = + getRequestorType == Authenticator.RequestorType.PROXY } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala index 365ffe698..aeef4d428 100644 --- a/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala @@ -13,7 +13,7 @@ private[sbt] case class Realm(host: String, realm: String) extends CredentialKey /** * Helper mechanism to improve credential related error messages. - * + * * This evil class exposes to us the necessary information to warn on credential failure and offer * spelling/typo suggestions. */ @@ -21,17 +21,18 @@ private[sbt] object IvyCredentialsLookup { /** Helper extractor for Ivy's key-value store of credentials. */ private object KeySplit { - def unapply(key: String): Option[(String,String)] = { + def unapply(key: String): Option[(String, String)] = { key.indexOf('@') match { case -1 => None - case n => Some(key.take(n) -> key.drop(n+1)) + case n => Some(key.take(n) -> key.drop(n + 1)) } } } - /** Here we cheat runtime private so we can look in the credentials store. + /** + * Here we cheat runtime private so we can look in the credentials store. * - * TODO - Don't bomb at class load time... + * TODO - Don't bomb at class load time... */ private val credKeyringField = { val tmp = classOf[CredentialsStore].getDeclaredField("KEYRING") @@ -45,10 +46,10 @@ private[sbt] object IvyCredentialsLookup { // make a clone of the set... (map.keySet.asScala.map { case KeySplit(realm, host) => Realm(host, realm) - case host => Host(host) + case host => Host(host) })(collection.breakOut) } - + /** * A mapping of host -> realms in the ivy credentials store. */ @@ -58,6 +59,6 @@ private[sbt] object IvyCredentialsLookup { } groupBy { realm => realm.host } mapValues { realms => - realms map (_.realm) + realms map (_.realm) } } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala index e1c07c780..486d8b7bd 100644 --- a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala @@ -3,134 +3,132 @@ package ivyint import java.io.File import java.net.URI -import java.util.{Collection, Collections => CS} +import java.util.{ Collection, Collections => CS } import CS.singleton -import org.apache.ivy.{core, plugins, util, Ivy} -import core.module.descriptor.{DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor} -import core.module.descriptor.{DefaultDependencyDescriptor => DDD, DependencyDescriptor} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import org.apache.ivy.{ core, plugins, util, Ivy } +import core.module.descriptor.{ DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } +import core.module.descriptor.{ DefaultDependencyDescriptor => DDD, DependencyDescriptor } +import core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import plugins.namespace.Namespace import util.extendable.ExtendableItem -private[sbt] object MergeDescriptors -{ - def mergeable(a: DependencyDescriptor, b: DependencyDescriptor): Boolean = - a.isForce == b.isForce && - a.isChanging == b.isChanging && - a.isTransitive == b.isTransitive && - a.getParentRevisionId == b.getParentRevisionId && - a.getNamespace == b.getNamespace && { - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - amrid == bmrid - } && { - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - adyn == bdyn - } +private[sbt] object MergeDescriptors { + def mergeable(a: DependencyDescriptor, b: DependencyDescriptor): Boolean = + a.isForce == b.isForce && + a.isChanging == b.isChanging && + a.isTransitive == b.isTransitive && + a.getParentRevisionId == b.getParentRevisionId && + a.getNamespace == b.getNamespace && { + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } - def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = - { - assert(mergeable(a,b)) - new MergedDescriptors(a,b) - } + def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = + { + assert(mergeable(a, b)) + new MergedDescriptors(a, b) + } } // combines the artifacts, configurations, includes, and excludes for DependencyDescriptors `a` and `b` // that otherwise have equal IDs -private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor -{ - def getDependencyId = a.getDependencyId - def isForce = a.isForce - def isChanging = a.isChanging - def isTransitive = a.isTransitive - def getNamespace = a.getNamespace - def getParentRevisionId = a.getParentRevisionId - def getDependencyRevisionId = a.getDependencyRevisionId - def getDynamicConstraintDependencyRevisionId = a.getDynamicConstraintDependencyRevisionId +private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor { + def getDependencyId = a.getDependencyId + def isForce = a.isForce + def isChanging = a.isChanging + def isTransitive = a.isTransitive + def getNamespace = a.getNamespace + def getParentRevisionId = a.getParentRevisionId + def getDependencyRevisionId = a.getDependencyRevisionId + def getDynamicConstraintDependencyRevisionId = a.getDynamicConstraintDependencyRevisionId - def getModuleConfigurations = concat(a.getModuleConfigurations, b.getModuleConfigurations) + def getModuleConfigurations = concat(a.getModuleConfigurations, b.getModuleConfigurations) - def getDependencyConfigurations(moduleConfiguration: String, requestedConfiguration: String) = - concat(a.getDependencyConfigurations(moduleConfiguration, requestedConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + def getDependencyConfigurations(moduleConfiguration: String, requestedConfiguration: String) = + concat(a.getDependencyConfigurations(moduleConfiguration, requestedConfiguration), b.getDependencyConfigurations(moduleConfiguration)) - def getDependencyConfigurations(moduleConfiguration: String) = - concat(a.getDependencyConfigurations(moduleConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + def getDependencyConfigurations(moduleConfiguration: String) = + concat(a.getDependencyConfigurations(moduleConfiguration), b.getDependencyConfigurations(moduleConfiguration)) - def getDependencyConfigurations(moduleConfigurations: Array[String]) = - concat(a.getDependencyConfigurations(moduleConfigurations), b.getDependencyConfigurations(moduleConfigurations)) + def getDependencyConfigurations(moduleConfigurations: Array[String]) = + concat(a.getDependencyConfigurations(moduleConfigurations), b.getDependencyConfigurations(moduleConfigurations)) - def getAllDependencyArtifacts = concatArtifacts(a, a.getAllDependencyArtifacts, b, b.getAllDependencyArtifacts) + def getAllDependencyArtifacts = concatArtifacts(a, a.getAllDependencyArtifacts, b, b.getAllDependencyArtifacts) - def getDependencyArtifacts(moduleConfigurations: String) = - concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + def getDependencyArtifacts(moduleConfigurations: String) = + concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) - def getDependencyArtifacts(moduleConfigurations: Array[String]) = - concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + def getDependencyArtifacts(moduleConfigurations: Array[String]) = + concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) - def getAllIncludeRules = concat(a.getAllIncludeRules, b.getAllIncludeRules) + def getAllIncludeRules = concat(a.getAllIncludeRules, b.getAllIncludeRules) - def getIncludeRules(moduleConfigurations: String) = - concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) + def getIncludeRules(moduleConfigurations: String) = + concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) - def getIncludeRules(moduleConfigurations: Array[String]) = - concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) + def getIncludeRules(moduleConfigurations: Array[String]) = + concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) - private[this] def concatArtifacts(a: DependencyDescriptor, as: Array[DependencyArtifactDescriptor], b: DependencyDescriptor, bs: Array[DependencyArtifactDescriptor]) = - { - if(as.isEmpty) - if(bs.isEmpty) as - else defaultArtifact(a) +: explicitConfigurations(b, bs) - else if(bs.isEmpty) explicitConfigurations(a, as) :+ defaultArtifact(b) - else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) - } - private[this] def explicitConfigurations(base: DependencyDescriptor, arts: Array[DependencyArtifactDescriptor]): Array[DependencyArtifactDescriptor] = - arts map { art => explicitConfigurations(base, art) } - private[this] def explicitConfigurations(base: DependencyDescriptor, art: DependencyArtifactDescriptor): DependencyArtifactDescriptor = - { - val aConfs = art.getConfigurations - if(aConfs == null || aConfs.isEmpty) - copyWithConfigurations(art, base.getModuleConfigurations) - else - art - } - private[this] def defaultArtifact(a: DependencyDescriptor): DependencyArtifactDescriptor = - { - val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) - addConfigurations(dd, a.getModuleConfigurations) - dd - } - private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = - { - val dextra = dd.getQualifiedExtraAttributes - val newd = new DefaultDependencyArtifactDescriptor(dd.getDependencyDescriptor, dd.getName, dd.getType, dd.getExt, dd.getUrl, dextra) - addConfigurations(newd, confs) - newd - } - private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = - confs foreach dd.addConfiguration + private[this] def concatArtifacts(a: DependencyDescriptor, as: Array[DependencyArtifactDescriptor], b: DependencyDescriptor, bs: Array[DependencyArtifactDescriptor]) = + { + if (as.isEmpty) + if (bs.isEmpty) as + else defaultArtifact(a) +: explicitConfigurations(b, bs) + else if (bs.isEmpty) explicitConfigurations(a, as) :+ defaultArtifact(b) + else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) + } + private[this] def explicitConfigurations(base: DependencyDescriptor, arts: Array[DependencyArtifactDescriptor]): Array[DependencyArtifactDescriptor] = + arts map { art => explicitConfigurations(base, art) } + private[this] def explicitConfigurations(base: DependencyDescriptor, art: DependencyArtifactDescriptor): DependencyArtifactDescriptor = + { + val aConfs = art.getConfigurations + if (aConfs == null || aConfs.isEmpty) + copyWithConfigurations(art, base.getModuleConfigurations) + else + art + } + private[this] def defaultArtifact(a: DependencyDescriptor): DependencyArtifactDescriptor = + { + val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) + addConfigurations(dd, a.getModuleConfigurations) + dd + } + private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = + { + val dextra = dd.getQualifiedExtraAttributes + val newd = new DefaultDependencyArtifactDescriptor(dd.getDependencyDescriptor, dd.getName, dd.getType, dd.getExt, dd.getUrl, dextra) + addConfigurations(newd, confs) + newd + } + private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = + confs foreach dd.addConfiguration - private[this] def concat[T: ClassManifest](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray + private[this] def concat[T: ClassManifest](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray - def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) + def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) - def getExcludeRules(moduleConfigurations: String) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + def getExcludeRules(moduleConfigurations: String) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) - def getExcludeRules(moduleConfigurations: Array[String]) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + def getExcludeRules(moduleConfigurations: Array[String]) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) - def doesExclude(moduleConfigurations: Array[String], artifactId: ArtifactId) = a.doesExclude(moduleConfigurations, artifactId) || b.doesExclude(moduleConfigurations, artifactId) + def doesExclude(moduleConfigurations: Array[String], artifactId: ArtifactId) = a.doesExclude(moduleConfigurations, artifactId) || b.doesExclude(moduleConfigurations, artifactId) - def canExclude = a.canExclude || b.canExclude + def canExclude = a.canExclude || b.canExclude - def asSystem = this + def asSystem = this - def clone(revision: ModuleRevisionId) = new MergedDescriptors(a.clone(revision), b.clone(revision)) + def clone(revision: ModuleRevisionId) = new MergedDescriptors(a.clone(revision), b.clone(revision)) - def getAttribute(name: String): String = a.getAttribute(name) - def getAttributes = a.getAttributes - def getExtraAttribute(name: String) = a.getExtraAttribute(name) - def getExtraAttributes = a.getExtraAttributes - def getQualifiedExtraAttributes = a.getQualifiedExtraAttributes - def getSourceModule = a.getSourceModule + def getAttribute(name: String): String = a.getAttribute(name) + def getAttributes = a.getAttributes + def getExtraAttribute(name: String) = a.getExtraAttribute(name) + def getExtraAttributes = a.getExtraAttributes + def getQualifiedExtraAttributes = a.getQualifiedExtraAttributes + def getSourceModule = a.getSourceModule } From fc5da1fa652c2e99d1a10b19c6d03c2380b41eb4 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 7 May 2014 11:52:23 -0400 Subject: [PATCH 0285/1030] Scalariforming test code --- ivy/src/test/scala/ComponentManagerTest.scala | 157 ++++++------ ivy/src/test/scala/CrossVersionTest.scala | 229 +++++++++--------- ivy/src/test/scala/MakePomTest.scala | 39 ++- 3 files changed, 210 insertions(+), 215 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index db3f676cc..80c3f4639 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -3,90 +3,87 @@ package sbt import java.io.File import org.specs2._ import mutable.Specification -import IO.{createDirectory, delete, touch, withTemporaryDirectory} +import IO.{ createDirectory, delete, touch, withTemporaryDirectory } import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail -object ComponentManagerTest extends Specification -{ - val TestID = "manager-test" - "Component manager" should { - "throw an exception if 'file' is called for a non-existing component" in { - withManager { _.file(TestID)(Fail) must throwA[InvalidComponent] } - } - "throw an exception if 'file' is called for an empty component" in { - withManager { manager => - manager.define(TestID, Nil) - ( manager.file(TestID)(Fail) ) must throwA[InvalidComponent] - } - } - "return the file for a single-file component" in { - withManager { manager => - val hash = defineFile(manager, TestID, "a") - checksum(manager.file(TestID)(Fail)) must beEqualTo(hash) - } - } +object ComponentManagerTest extends Specification { + val TestID = "manager-test" + "Component manager" should { + "throw an exception if 'file' is called for a non-existing component" in { + withManager { _.file(TestID)(Fail) must throwA[InvalidComponent] } + } + "throw an exception if 'file' is called for an empty component" in { + withManager { manager => + manager.define(TestID, Nil) + (manager.file(TestID)(Fail)) must throwA[InvalidComponent] + } + } + "return the file for a single-file component" in { + withManager { manager => + val hash = defineFile(manager, TestID, "a") + checksum(manager.file(TestID)(Fail)) must beEqualTo(hash) + } + } - "throw an exception if 'file' is called for multi-file component" in { - withManager { manager => - defineFiles(manager, TestID, "a", "b") - ( manager.file(TestID)(Fail) ) must throwA[InvalidComponent] - } - } - "return the files for a multi-file component" in { - withManager { manager => - val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) - } - } - "return the files for a single-file component" in { - withManager { manager => - val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) - } - } - "throw an exception if 'files' is called for a non-existing component" in { - withManager { _.files(TestID)(Fail) must throwA[InvalidComponent] } - } + "throw an exception if 'file' is called for multi-file component" in { + withManager { manager => + defineFiles(manager, TestID, "a", "b") + (manager.file(TestID)(Fail)) must throwA[InvalidComponent] + } + } + "return the files for a multi-file component" in { + withManager { manager => + val hashes = defineFiles(manager, TestID, "a", "b") + checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) + } + } + "return the files for a single-file component" in { + withManager { manager => + val hashes = defineFiles(manager, TestID, "a") + checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) + } + } + "throw an exception if 'files' is called for a non-existing component" in { + withManager { _.files(TestID)(Fail) must throwA[InvalidComponent] } + } - "properly cache a file and then retrieve it to an unresolved component" in { - withTemporaryDirectory { ivyHome => - withManagerHome(ivyHome) { definingManager => - val hash = defineFile(definingManager, TestID, "a") - try - { - definingManager.cache(TestID) - withManagerHome(ivyHome) { usingManager => - checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) - } - } - finally { definingManager.clearCache(TestID) } - } - } - } - } - private def checksum(files: Iterable[File]): Seq[String] = files.map(checksum).toSeq - private def checksum(file: File): String = if(file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" - private def defineFile(manager: ComponentManager, id: String, name: String): String = createFile(manager, id, name)(checksum) - private def defineFiles(manager: ComponentManager, id: String, names: String*): Seq[String] = createFiles(manager, id, names : _*)(checksum) - private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = createFiles(manager, id, name)(files => f(files.toList.head)) - private def createFiles[T](manager: ComponentManager, id: String, names: String*)(f: Seq[File] => T): T = - withTemporaryDirectory { dir => - val files = names.map(name => new File(dir, name) ) - files.foreach(writeRandomContent) - manager.define(id, files) - f(files) - } - private def writeRandomContent(file: File) = IO.write(file, randomString) - private def randomString = "asdf" - private def withManager[T](f: ComponentManager => T): T = - withTemporaryDirectory { ivyHome => withManagerHome(ivyHome)(f) } + "properly cache a file and then retrieve it to an unresolved component" in { + withTemporaryDirectory { ivyHome => + withManagerHome(ivyHome) { definingManager => + val hash = defineFile(definingManager, TestID, "a") + try { + definingManager.cache(TestID) + withManagerHome(ivyHome) { usingManager => + checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) + } + } finally { definingManager.clearCache(TestID) } + } + } + } + } + private def checksum(files: Iterable[File]): Seq[String] = files.map(checksum).toSeq + private def checksum(file: File): String = if (file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" + private def defineFile(manager: ComponentManager, id: String, name: String): String = createFile(manager, id, name)(checksum) + private def defineFiles(manager: ComponentManager, id: String, names: String*): Seq[String] = createFiles(manager, id, names: _*)(checksum) + private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = createFiles(manager, id, name)(files => f(files.toList.head)) + private def createFiles[T](manager: ComponentManager, id: String, names: String*)(f: Seq[File] => T): T = + withTemporaryDirectory { dir => + val files = names.map(name => new File(dir, name)) + files.foreach(writeRandomContent) + manager.define(id, files) + f(files) + } + private def writeRandomContent(file: File) = IO.write(file, randomString) + private def randomString = "asdf" + private def withManager[T](f: ComponentManager => T): T = + withTemporaryDirectory { ivyHome => withManagerHome(ivyHome)(f) } - private def withManagerHome[T](ivyHome: File)(f: ComponentManager => T): T = - TestLogger { logger => - withTemporaryDirectory { temp => - val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) - f(mgr) - } - } + private def withManagerHome[T](ivyHome: File)(f: ComponentManager => T): T = + TestLogger { logger => + withTemporaryDirectory { temp => + val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + f(mgr) + } + } } diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala index cd89b1358..364d6c67e 100644 --- a/ivy/src/test/scala/CrossVersionTest.scala +++ b/ivy/src/test/scala/CrossVersionTest.scala @@ -4,120 +4,119 @@ import java.io.File import org.specs2._ import mutable.Specification -object CrossVersionTest extends Specification -{ - "Cross version" should { - "return sbt API for xyz as None" in { - CrossVersion.sbtApiVersion("xyz") must_== None - } - "return sbt API for 0.12 as None" in { - CrossVersion.sbtApiVersion("0.12") must_== None - } - "return sbt API for 0.12.0-SNAPSHOT as None" in { - CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") must_== None - } - "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0-RC1") must_== Some((0, 12)) - } - "return sbt API for 0.12.0 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0") must_== Some((0, 12)) - } - "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") must_== Some((0, 12)) - } - "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-RC1") must_== Some((0, 12)) - } - "return sbt API for 0.12.1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1") must_== Some((0, 12)) - } - "return sbt API compatibility for 0.12.0-M1 as false" in { - CrossVersion.isSbtApiCompatible("0.12.0-M1") must_== false - } - "return sbt API compatibility for 0.12.0-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.0-RC1") must_== true - } - "return sbt API compatibility for 0.12.1-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.1-RC1") must_== true - } - "return binary sbt version for 0.11.3 as 0.11.3" in { - CrossVersion.binarySbtVersion("0.11.3") must_== "0.11.3" - } - "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { - CrossVersion.binarySbtVersion("0.12.0-M1") must_== "0.12.0-M1" - } - "return binary sbt version for 0.12.0-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0-RC1") must_== "0.12" - } - "return binary sbt version for 0.12.0 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0") must_== "0.12" - } - "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") must_== "0.12" - } - "return binary sbt version for 0.12.1-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-RC1") must_== "0.12" - } - "return binary sbt version for 0.12.1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1") must_== "0.12" - } +object CrossVersionTest extends Specification { + "Cross version" should { + "return sbt API for xyz as None" in { + CrossVersion.sbtApiVersion("xyz") must_== None + } + "return sbt API for 0.12 as None" in { + CrossVersion.sbtApiVersion("0.12") must_== None + } + "return sbt API for 0.12.0-SNAPSHOT as None" in { + CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") must_== None + } + "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0-RC1") must_== Some((0, 12)) + } + "return sbt API for 0.12.0 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0") must_== Some((0, 12)) + } + "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") must_== Some((0, 12)) + } + "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-RC1") must_== Some((0, 12)) + } + "return sbt API for 0.12.1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1") must_== Some((0, 12)) + } + "return sbt API compatibility for 0.12.0-M1 as false" in { + CrossVersion.isSbtApiCompatible("0.12.0-M1") must_== false + } + "return sbt API compatibility for 0.12.0-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.0-RC1") must_== true + } + "return sbt API compatibility for 0.12.1-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.1-RC1") must_== true + } + "return binary sbt version for 0.11.3 as 0.11.3" in { + CrossVersion.binarySbtVersion("0.11.3") must_== "0.11.3" + } + "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { + CrossVersion.binarySbtVersion("0.12.0-M1") must_== "0.12.0-M1" + } + "return binary sbt version for 0.12.0-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0-RC1") must_== "0.12" + } + "return binary sbt version for 0.12.0 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0") must_== "0.12" + } + "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") must_== "0.12" + } + "return binary sbt version for 0.12.1-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-RC1") must_== "0.12" + } + "return binary sbt version for 0.12.1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1") must_== "0.12" + } - "return Scala API for xyz as None" in { - CrossVersion.scalaApiVersion("xyz") must_== None - } - "return Scala API for 2.10 as None" in { - CrossVersion.scalaApiVersion("2.10") must_== None - } - "return Scala API for 2.10.0-SNAPSHOT as None" in { - CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") must_== None - } - "return Scala API for 2.10.0-RC1 as None" in { - CrossVersion.scalaApiVersion("2.10.0-RC1") must_== None - } - "return Scala API for 2.10.0 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0") must_== Some((2, 10)) - } - "return Scala API for 2.10.0-1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0-1") must_== Some((2, 10)) - } - "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") must_== Some((2, 10)) - } - "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-RC1") must_== Some((2, 10)) - } - "return Scala API for 2.10.1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1") must_== Some((2, 10)) - } - "return Scala API compatibility for 2.10.0-M1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-M1") must_== false - } - "return Scala API compatibility for 2.10.0-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-RC1") must_== false - } - "return Scala API compatibility for 2.10.1-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.1-RC1") must_== true - } - "return binary Scala version for 2.9.2 as 2.9.2" in { - CrossVersion.binaryScalaVersion("2.9.2") must_== "2.9.2" - } - "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { - CrossVersion.binaryScalaVersion("2.10.0-M1") must_== "2.10.0-M1" - } - "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { - CrossVersion.binaryScalaVersion("2.10.0-RC1") must_== "2.10.0-RC1" - } - "return binary Scala version for 2.10.0 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.0") must_== "2.10" - } - "return binary Scala version for 2.10.1-M1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-M1") must_== "2.10" - } - "return binary Scala version for 2.10.1-RC1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-RC1") must_== "2.10" - } - "return binary Scala version for 2.10.1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1") must_== "2.10" - } - } + "return Scala API for xyz as None" in { + CrossVersion.scalaApiVersion("xyz") must_== None + } + "return Scala API for 2.10 as None" in { + CrossVersion.scalaApiVersion("2.10") must_== None + } + "return Scala API for 2.10.0-SNAPSHOT as None" in { + CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") must_== None + } + "return Scala API for 2.10.0-RC1 as None" in { + CrossVersion.scalaApiVersion("2.10.0-RC1") must_== None + } + "return Scala API for 2.10.0 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0") must_== Some((2, 10)) + } + "return Scala API for 2.10.0-1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0-1") must_== Some((2, 10)) + } + "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") must_== Some((2, 10)) + } + "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-RC1") must_== Some((2, 10)) + } + "return Scala API for 2.10.1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1") must_== Some((2, 10)) + } + "return Scala API compatibility for 2.10.0-M1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-M1") must_== false + } + "return Scala API compatibility for 2.10.0-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-RC1") must_== false + } + "return Scala API compatibility for 2.10.1-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.1-RC1") must_== true + } + "return binary Scala version for 2.9.2 as 2.9.2" in { + CrossVersion.binaryScalaVersion("2.9.2") must_== "2.9.2" + } + "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { + CrossVersion.binaryScalaVersion("2.10.0-M1") must_== "2.10.0-M1" + } + "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { + CrossVersion.binaryScalaVersion("2.10.0-RC1") must_== "2.10.0-RC1" + } + "return binary Scala version for 2.10.0 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.0") must_== "2.10" + } + "return binary Scala version for 2.10.1-M1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-M1") must_== "2.10" + } + "return binary Scala version for 2.10.1-RC1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-RC1") must_== "2.10" + } + "return binary Scala version for 2.10.1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1") must_== "2.10" + } + } } diff --git a/ivy/src/test/scala/MakePomTest.scala b/ivy/src/test/scala/MakePomTest.scala index 1341b207d..c96d2102e 100644 --- a/ivy/src/test/scala/MakePomTest.scala +++ b/ivy/src/test/scala/MakePomTest.scala @@ -4,26 +4,25 @@ import java.io.File import org.specs2._ import mutable.Specification -object MakePomTest extends Specification -{ - val mp = new MakePom(ConsoleLogger()) - import mp.{makeDependencyVersion=>v} - "MakePom makeDependencyVersion" should { - "Handle .+ in versions" in { - v("1.+") must_== "[1,2)" - v("1.2.3.4.+") must_== "[1.2.3.4,1.2.3.5)" - v("12.31.42.+") must_== "[12.31.42,12.31.43)" - } - /* TODO - do we care about this case? +object MakePomTest extends Specification { + val mp = new MakePom(ConsoleLogger()) + import mp.{ makeDependencyVersion => v } + "MakePom makeDependencyVersion" should { + "Handle .+ in versions" in { + v("1.+") must_== "[1,2)" + v("1.2.3.4.+") must_== "[1.2.3.4,1.2.3.5)" + v("12.31.42.+") must_== "[12.31.42,12.31.43)" + } + /* TODO - do we care about this case? * 1+ --> [1,2),[10,20),[100,200),[1000,2000),[10000,20000),[100000,200000) */ - "Handle ]* bracket in version ranges" in { - v("]1,3]") must_== "(1,3]" - v("]1.1,1.3]") must_== "(1.1,1.3]" - } - "Handle *[ bracket in version ranges" in { - v("[1,3[") must_== "[1,3)" - v("[1.1,1.3[") must_== "[1.1,1.3)" - } - } + "Handle ]* bracket in version ranges" in { + v("]1,3]") must_== "(1,3]" + v("]1.1,1.3]") must_== "(1.1,1.3]" + } + "Handle *[ bracket in version ranges" in { + v("[1,3[") must_== "[1,3)" + v("[1.1,1.3[") must_== "[1.1,1.3)" + } + } } From 5ea556a3971d9c718cd5f380091a99b07d29708a Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 14 May 2014 12:30:56 -0400 Subject: [PATCH 0286/1030] Bump expected 2.11 module versions so we can compile with 2.11 Add scala 2.11 test/build verification. * Add 2.11 build configuratoin to travis ci * Create command which runs `safe` unit tests * Create command to test the scala 2.11 build * Update scalacheck to 1.11.4 * Update specs2 to 2.3.11 * Fix various 2.11/deprecation removals and other changes. Fix eval test failure in scala 2.11 with XML not existing. --- ivy/src/test/scala/ComponentManagerTest.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 80c3f4639..1995bb304 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -35,13 +35,13 @@ object ComponentManagerTest extends Specification { "return the files for a multi-file component" in { withManager { manager => val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) + checksum(manager.files(TestID)(Fail)) must containTheSameElementsAs(hashes) } } "return the files for a single-file component" in { withManager { manager => val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)(Fail)) must haveTheSameElementsAs(hashes) + checksum(manager.files(TestID)(Fail)) must containTheSameElementsAs(hashes) } } "throw an exception if 'files' is called for a non-existing component" in { From 1f68d3f6fdc3be243fd4762bdff937d5bf2ef936 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 28 May 2014 08:55:29 -0400 Subject: [PATCH 0287/1030] Fix import issues to generate sxr/scaladoc. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 17 ++++++----- ivy/src/main/scala/sbt/CustomPomParser.scala | 17 ++++++----- ivy/src/main/scala/sbt/CustomXmlParser.scala | 11 ++++--- ivy/src/main/scala/sbt/Ivy.scala | 30 ++++++++++---------- ivy/src/main/scala/sbt/IvyActions.scala | 16 +++++------ ivy/src/main/scala/sbt/IvyCache.scala | 13 ++++----- ivy/src/main/scala/sbt/IvyScala.scala | 9 +++--- ivy/src/main/scala/sbt/MakePom.scala | 8 +++--- ivy/src/main/scala/sbt/ProjectResolver.scala | 7 ++--- 9 files changed, 61 insertions(+), 67 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 74c5c119c..b09c168e4 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -5,15 +5,14 @@ package sbt import java.net.URL import java.util.Collections -import org.apache.ivy.{core,plugins} -import core.module.id.ModuleRevisionId -import core.module.descriptor.DependencyDescriptor -import core.resolve.ResolveData -import core.settings.IvySettings -import plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver} -import plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} -import plugins.repository.url.{URLRepository => URLRepo} -import plugins.repository.file.{FileRepository => FileRepo, FileResource} +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.module.descriptor.DependencyDescriptor +import org.apache.ivy.core.resolve.ResolveData +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver} +import org.apache.ivy.plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} +import org.apache.ivy.plugins.repository.url.{URLRepository => URLRepo} +import org.apache.ivy.plugins.repository.file.{FileRepository => FileRepo, FileResource} import java.io.File import org.apache.ivy.util.ChecksumHelper import org.apache.ivy.core.module.descriptor.{Artifact=>IArtifact} diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 871c1f07c..0f7f6c315 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -1,14 +1,13 @@ package sbt - import org.apache.ivy.{core, plugins, util} - import core.module.id.ModuleRevisionId - import core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} - import core.module.descriptor.{DefaultDependencyDescriptor, DependencyDescriptor} - import plugins.parser.{m2, ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} - import m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} - import plugins.repository.Resource - import plugins.namespace.NamespaceTransformer - import util.extendable.ExtendableItem + import org.apache.ivy.core.module.id.ModuleRevisionId + import org.apache.ivy.core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} + import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DependencyDescriptor} + import org.apache.ivy.plugins.parser.{ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} + import org.apache.ivy.plugins.parser.m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} + import org.apache.ivy.plugins.repository.Resource + import org.apache.ivy.plugins.namespace.NamespaceTransformer + import org.apache.ivy.util.extendable.ExtendableItem import java.io.{File, InputStream} import java.net.URL diff --git a/ivy/src/main/scala/sbt/CustomXmlParser.scala b/ivy/src/main/scala/sbt/CustomXmlParser.scala index da44743f6..1264a5231 100644 --- a/ivy/src/main/scala/sbt/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/CustomXmlParser.scala @@ -6,12 +6,11 @@ package sbt import java.io.ByteArrayInputStream import java.net.URL -import org.apache.ivy.{core, plugins} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor} -import core.settings.IvySettings -import plugins.parser.xml.XmlModuleDescriptorParser -import plugins.repository.Resource -import plugins.repository.url.URLResource +import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor} +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser +import org.apache.ivy.plugins.repository.Resource +import org.apache.ivy.plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index a6519c6bc..301dfa51d 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -11,21 +11,21 @@ import java.util.concurrent.Callable import java.util.{Collection, Collections => CS} import CS.singleton -import org.apache.ivy.{core, plugins, util, Ivy} -import core.{IvyPatternHelper, LogOptions} -import core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter} -import core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} -import core.module.descriptor.{OverrideDependencyDescriptorMediator} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} -import core.settings.IvySettings -import plugins.latest.LatestRevisionStrategy -import plugins.matcher.PatternMatcher -import plugins.parser.m2.PomModuleDescriptorParser -import plugins.resolver.{ChainResolver, DependencyResolver} -import util.{Message, MessageLogger} -import util.extendable.ExtendableItem +import org.apache.ivy.Ivy +import org.apache.ivy.core.{IvyPatternHelper, LogOptions} +import org.apache.ivy.core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter} +import org.apache.ivy.core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} +import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} +import org.apache.ivy.core.module.descriptor.{OverrideDependencyDescriptorMediator} +import org.apache.ivy.core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import org.apache.ivy.core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.latest.LatestRevisionStrategy +import org.apache.ivy.plugins.matcher.PatternMatcher +import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorParser +import org.apache.ivy.plugins.resolver.{ChainResolver, DependencyResolver} +import org.apache.ivy.util.{Message, MessageLogger} +import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{NodeSeq, Text} diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 716579e0f..4523fe9ff 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -6,14 +6,14 @@ package sbt import java.io.File import scala.xml.{Node => XNode, NodeSeq} -import org.apache.ivy.{core, plugins, Ivy} -import core.{IvyPatternHelper, LogOptions} -import core.deliver.DeliverOptions -import core.install.InstallOptions -import core.module.descriptor.{Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor} -import core.report.ResolveReport -import core.resolve.ResolveOptions -import plugins.resolver.{BasicResolver, DependencyResolver} +import org.apache.ivy.Ivy +import org.apache.ivy.core.{IvyPatternHelper, LogOptions} +import org.apache.ivy.core.deliver.DeliverOptions +import org.apache.ivy.core.install.InstallOptions +import org.apache.ivy.core.module.descriptor.{Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor} +import org.apache.ivy.core.report.ResolveReport +import org.apache.ivy.core.resolve.ResolveOptions +import org.apache.ivy.plugins.resolver.{BasicResolver, DependencyResolver} final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala index 3ff8432f0..f7a5dbe2e 100644 --- a/ivy/src/main/scala/sbt/IvyCache.scala +++ b/ivy/src/main/scala/sbt/IvyCache.scala @@ -6,13 +6,12 @@ package sbt import java.io.File import java.net.URL -import org.apache.ivy.{core, plugins, util} -import core.cache.{ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager} -import core.module.descriptor.{Artifact => IvyArtifact, DefaultArtifact} -import plugins.repository.file.{FileRepository=>IvyFileRepository, FileResource} -import plugins.repository.{ArtifactResourceResolver, Resource, ResourceDownloader} -import plugins.resolver.util.ResolvedResource -import util.FileUtil +import org.apache.ivy.core.cache.{ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager} +import org.apache.ivy.core.module.descriptor.{Artifact => IvyArtifact, DefaultArtifact} +import org.apache.ivy.plugins.repository.file.{FileRepository=>IvyFileRepository, FileResource} +import org.apache.ivy.plugins.repository.{ArtifactResourceResolver, Resource, ResourceDownloader} +import org.apache.ivy.plugins.resolver.util.ResolvedResource +import org.apache.ivy.util.FileUtil class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index 23b7597ff..fd442c86f 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -6,11 +6,10 @@ package sbt import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.{core, plugins} -import core.module.descriptor.{DefaultExcludeRule, ExcludeRule} -import core.module.descriptor.{DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} -import core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import plugins.matcher.ExactPatternMatcher +import org.apache.ivy.core.module.descriptor.{DefaultExcludeRule, ExcludeRule} +import org.apache.ivy.core.module.descriptor.{DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} +import org.apache.ivy.core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import org.apache.ivy.plugins.matcher.ExactPatternMatcher object ScalaArtifacts { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 16ec28333..22ca8a524 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -13,10 +13,10 @@ import java.io.File import scala.xml.{Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute} import Configurations.Optional -import org.apache.ivy.{core, plugins, Ivy} -import core.settings.IvySettings -import core.module.descriptor.{DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} -import plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} +import org.apache.ivy.Ivy +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.core.module.descriptor.{DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} +import org.apache.ivy.plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} class MakePom(val log: Logger) { diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index 917889db8..e0abaeab1 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -6,14 +6,13 @@ package sbt import java.io.File import java.util.Date - import org.apache.ivy.{core,plugins} - import core.{cache,module, report, resolve,search} + import org.apache.ivy.core.{cache,module, report, resolve,search} import cache.{ArtifactOrigin,RepositoryCacheManager} import search.{ModuleEntry, OrganisationEntry, RevisionEntry} import module.id.ModuleRevisionId import module.descriptor.{Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor} - import plugins.namespace.Namespace - import plugins.resolver.{DependencyResolver,ResolverSettings} + import org.apache.ivy.plugins.namespace.Namespace + import org.apache.ivy.plugins.resolver.{DependencyResolver,ResolverSettings} import report.{ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport} import resolve.{DownloadOptions, ResolveData, ResolvedModuleRevision} From 449e757249aa1ea5591c18beb54168f739a49df5 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 28 May 2014 09:12:55 -0400 Subject: [PATCH 0288/1030] Fix formatting issues and bump to sbt 0.13.5 --- ivy/src/main/scala/sbt/ConvertResolver.scala | 8 ++++---- ivy/src/main/scala/sbt/CustomPomParser.scala | 16 ++++++++-------- ivy/src/main/scala/sbt/CustomXmlParser.scala | 2 +- ivy/src/main/scala/sbt/Ivy.scala | 18 +++++++++--------- ivy/src/main/scala/sbt/IvyActions.scala | 6 +++--- ivy/src/main/scala/sbt/IvyCache.scala | 8 ++++---- ivy/src/main/scala/sbt/IvyScala.scala | 6 +++--- ivy/src/main/scala/sbt/MakePom.scala | 4 ++-- ivy/src/main/scala/sbt/ProjectResolver.scala | 6 +++--- 9 files changed, 37 insertions(+), 37 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index d060322d9..a36d7430c 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -9,10 +9,10 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.plugins.resolver.{BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver} -import org.apache.ivy.plugins.resolver.{AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver} -import org.apache.ivy.plugins.repository.url.{URLRepository => URLRepo} -import org.apache.ivy.plugins.repository.file.{FileRepository => FileRepo, FileResource} +import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver } +import org.apache.ivy.plugins.resolver.{ AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver } +import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } +import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, FileResource } import java.io.File import org.apache.ivy.util.ChecksumHelper import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 6e186695c..5e0deb7c4 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -1,13 +1,13 @@ package sbt - import org.apache.ivy.core.module.id.ModuleRevisionId - import org.apache.ivy.core.module.descriptor.{DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor} - import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DependencyDescriptor} - import org.apache.ivy.plugins.parser.{ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings} - import org.apache.ivy.plugins.parser.m2.{PomModuleDescriptorBuilder, PomModuleDescriptorParser} - import org.apache.ivy.plugins.repository.Resource - import org.apache.ivy.plugins.namespace.NamespaceTransformer - import org.apache.ivy.util.extendable.ExtendableItem +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } +import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DependencyDescriptor } +import org.apache.ivy.plugins.parser.{ ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings } +import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorBuilder, PomModuleDescriptorParser } +import org.apache.ivy.plugins.repository.Resource +import org.apache.ivy.plugins.namespace.NamespaceTransformer +import org.apache.ivy.util.extendable.ExtendableItem import java.io.{ File, InputStream } import java.net.URL diff --git a/ivy/src/main/scala/sbt/CustomXmlParser.scala b/ivy/src/main/scala/sbt/CustomXmlParser.scala index 684caa3ac..c5462070c 100644 --- a/ivy/src/main/scala/sbt/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/CustomXmlParser.scala @@ -6,7 +6,7 @@ package sbt import java.io.ByteArrayInputStream import java.net.URL -import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor} +import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor } import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 441e442d4..7f54fb4b4 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -12,19 +12,19 @@ import java.util.{ Collection, Collections => CS } import CS.singleton import org.apache.ivy.Ivy -import org.apache.ivy.core.{IvyPatternHelper, LogOptions} -import org.apache.ivy.core.cache.{CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter} -import org.apache.ivy.core.module.descriptor.{Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact} -import org.apache.ivy.core.module.descriptor.{DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License} -import org.apache.ivy.core.module.descriptor.{OverrideDependencyDescriptorMediator} -import org.apache.ivy.core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} -import org.apache.ivy.core.resolve.{IvyNode, ResolveData, ResolvedModuleRevision} +import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } +import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } +import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } +import org.apache.ivy.core.module.descriptor.{ OverrideDependencyDescriptorMediator } +import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } +import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision } import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.latest.LatestRevisionStrategy import org.apache.ivy.plugins.matcher.PatternMatcher import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorParser -import org.apache.ivy.plugins.resolver.{ChainResolver, DependencyResolver} -import org.apache.ivy.util.{Message, MessageLogger} +import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver } +import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{ NodeSeq, Text } diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 039c2b86e..c87666373 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -7,13 +7,13 @@ import java.io.File import scala.xml.{ Node => XNode, NodeSeq } import org.apache.ivy.Ivy -import org.apache.ivy.core.{IvyPatternHelper, LogOptions} +import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.core.deliver.DeliverOptions import org.apache.ivy.core.install.InstallOptions -import org.apache.ivy.core.module.descriptor.{Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor} +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor } import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions -import org.apache.ivy.plugins.resolver.{BasicResolver, DependencyResolver} +import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala index 4448bf053..51e02b60c 100644 --- a/ivy/src/main/scala/sbt/IvyCache.scala +++ b/ivy/src/main/scala/sbt/IvyCache.scala @@ -6,10 +6,10 @@ package sbt import java.io.File import java.net.URL -import org.apache.ivy.core.cache.{ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager} -import org.apache.ivy.core.module.descriptor.{Artifact => IvyArtifact, DefaultArtifact} -import org.apache.ivy.plugins.repository.file.{FileRepository=>IvyFileRepository, FileResource} -import org.apache.ivy.plugins.repository.{ArtifactResourceResolver, Resource, ResourceDownloader} +import org.apache.ivy.core.cache.{ ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager } +import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact } +import org.apache.ivy.plugins.repository.file.{ FileRepository => IvyFileRepository, FileResource } +import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, ResourceDownloader } import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index 1ae99c2b0..e2468a81a 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -6,9 +6,9 @@ package sbt import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.core.module.descriptor.{DefaultExcludeRule, ExcludeRule} -import org.apache.ivy.core.module.descriptor.{DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator} -import org.apache.ivy.core.module.id.{ArtifactId,ModuleId, ModuleRevisionId} +import org.apache.ivy.core.module.descriptor.{ DefaultExcludeRule, ExcludeRule } +import org.apache.ivy.core.module.descriptor.{ DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator } +import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher object ScalaArtifacts { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 7e185d12a..be3baba63 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -15,8 +15,8 @@ import Configurations.Optional import org.apache.ivy.Ivy import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.core.module.descriptor.{DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule} -import org.apache.ivy.plugins.resolver.{ChainResolver, DependencyResolver, IBiblioResolver} +import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } +import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } class MakePom(val log: Logger) { @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index 93b9fcd8a..92fa48bfe 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -6,13 +6,13 @@ package sbt import java.io.File import java.util.Date - import org.apache.ivy.core.{cache,module, report, resolve,search} +import org.apache.ivy.core.{ cache, module, report, resolve, search } import cache.{ ArtifactOrigin, RepositoryCacheManager } import search.{ ModuleEntry, OrganisationEntry, RevisionEntry } import module.id.ModuleRevisionId import module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor } - import org.apache.ivy.plugins.namespace.Namespace - import org.apache.ivy.plugins.resolver.{DependencyResolver,ResolverSettings} +import org.apache.ivy.plugins.namespace.Namespace +import org.apache.ivy.plugins.resolver.{ DependencyResolver, ResolverSettings } import report.{ ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport } import resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } From 1c92e42c440f6dbf7a632bce77c3a3469dd0dbe7 Mon Sep 17 00:00:00 2001 From: David Pratt Date: Thu, 5 Jun 2014 18:11:37 -0500 Subject: [PATCH 0289/1030] Add 'scala-jar' to the list of jar artifacts. The CustomPomParser has a hard-coded list of 'blessed' Maven POM packaging types that are actually packaged as jar files, but Ivy incorrectly maps the file extension. This patch allows artifacts published with the 'scala-jar' packaging to be properly resolved and used in an SBT project. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 5e0deb7c4..bcb8a2476 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -37,7 +37,7 @@ object CustomPomParser { private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) // packagings that should be jars, but that Ivy doesn't handle as jars - val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit") + val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) private[this] val TransformedHashKey = "e:sbtTransformHash" From f38cd6d8c3e359927d7fdec5ff298625daf1fdf4 Mon Sep 17 00:00:00 2001 From: David Pratt Date: Sat, 7 Jun 2014 20:58:31 -0500 Subject: [PATCH 0290/1030] Add a unit test for the 'scala-jar' mapping. --- .../test-artifact-1.0.0-SNAPSHOT.jar | Bin 0 -> 2058 bytes .../test-artifact-1.0.0-SNAPSHOT.pom | 15 +++++++ ivy/src/test/scala/CustomPomParserTest.scala | 37 ++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar create mode 100644 ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom create mode 100644 ivy/src/test/scala/CustomPomParserTest.scala diff --git a/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..e02011810ce3f45629cfccac504df582a2624858 GIT binary patch literal 2058 zcmWIWW@h1H0D(u7j=O*vP=XUk`?`iW>U#RQ=?6fSaWFgtD*Ll&_WvB9bTbf(AS?5A z^z(Fc4Gz)sb^Gjl=CqHuuHHpnZ(Xf(XU=a9GPq*=;AxT8*)y6KOIK|P^3c@q($Q?} zSn{H3X-ad*jMtJ!W=nl4vJ_vcHf_nW22m?96}9vwT0hjLEq$gb@mlgF<5Su0NybK} zgSrKlu|HW7HbqSPfJ(*Aik%EF*D-)y2Xqh|umD-f`MGfSW2yjo6QrUfwYUVX4C2k7 z8Haw@FfuSa0AfjGWge+HIr-uFML8*Y$vKI|#km2ey_g*Z))@AmUAMZk^W$F|j!t&* z^Md+K6%ipFM?R+*AK~0=y=kUK-84B7n;(pIQ*Ib{@q5Vcda>%=tap|FD{7ewI^Hs* z>ik%-IPhRngW5D3o$8204f&Hkvy$7KR^Lt5nD?SFVZ|{c;pdaL=zr3_7k=bQ^4x-} zk9ThQY947~UUcR{kMLYKw;taTwJDdbTZK3Coz$Ez>3repWE;Wdm-<5Lt@+&k^tFEo z__#qTiT5?n!pY_D=Dtf*KBBfwLMm7;VMS!K$HyFr*e~u%hW}T*JA9*K3g2bn1pOb;Z@F(7A&NFP<=S%K?U$I|yr*u#Hhi!49b`h6Dv|g`BI<$PvnKv2hOcwiPeeF;En13W= z$=#a%?-IPz)GI}fFS!;Ivi?xS{dxVYEOixu3%nNJe%ATi=lTiG*Bm~6GlCvJVNX4G z+Q3KM_d%A>fp@!$#l9^$`Z+1uCa;V|&EDYO1OF(m&}Z&h95GKSI_iJ9{Rm2At}!|k zzudBMr4|R5`JeUH_0sY54fI$Q^1)Zf`|RT&K0lqn4_aq~4Gh8!wrnsm+Gb=B zR8YnlXkcVu@=yy}Hkn>AzF>TT_ggU!$F~ps554qH>Fa**+30)j{8epFUA>21I$9@v zynXZ-yBdG&GO!Z|mN<+|BFwl8PM{BfK!D+`BZ!8lVuUvA1t~}|2rOw-2a<4YNX06` z1k9ogRMx2-CQvkq?*&;M&lO zMr8M5%iu8E|Nn1fLh>;zyTjaonRP)K9-(<1re>t&2_93>ivyUM91PeB z1emEy8a0?Pyajg|s+rK@0TE)@a|XibDqw`e(+DKQ@EDEACjs89Y#>v(fN(F+%jT>g F9sr{cle_=` literal 0 HcmV?d00001 diff --git a/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom new file mode 100644 index 000000000..7884c5684 --- /dev/null +++ b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom @@ -0,0 +1,15 @@ + + + 4.0.0 + + com.test + test-artifact + 1.0.0-SNAPSHOT + scala-jar + + + UTF-8 + + + diff --git a/ivy/src/test/scala/CustomPomParserTest.scala b/ivy/src/test/scala/CustomPomParserTest.scala new file mode 100644 index 000000000..1bc39a120 --- /dev/null +++ b/ivy/src/test/scala/CustomPomParserTest.scala @@ -0,0 +1,37 @@ +import java.io.File +import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact } +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.resolve.ResolveOptions +import org.specs2.mutable.Specification +import sbt._ +import IO.withTemporaryDirectory + +object CustomPomParserTest extends Specification { + + "CustomPomParser" should { + "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { + val log = ConsoleLogger() + withTemporaryDirectory { cacheDir => + val repoUrl = getClass.getResource("/test-maven-repo") + val local = MavenRepository("Test Repo", repoUrl.toExternalForm) + val paths = new IvyPaths(new File("."), Some(cacheDir)) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, log) + val ivySbt = new IvySbt(conf) + val resolveOpts = new ResolveOptions().setConfs(Array("default")) + val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") + + val resolveReport = ivySbt.withIvy(log) { ivy => + ivy.resolve(mrid, resolveOpts, true) + } + + resolveReport.hasError must beFalse + resolveReport.getArtifacts.size() must beEqualTo(1) + val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) + artifact.getModuleRevisionId must beEqualTo(mrid) + artifact.getExt must beEqualTo("jar") + } + + } + } + +} From 648ab3a8ddcf9240da9950c9585bbeb3b29bf4d3 Mon Sep 17 00:00:00 2001 From: David Pratt Date: Mon, 9 Jun 2014 13:54:20 -0500 Subject: [PATCH 0291/1030] Make jar artifact a 0-byte file. --- .../test-artifact-1.0.0-SNAPSHOT.jar | Bin 2058 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar index e02011810ce3f45629cfccac504df582a2624858..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 GIT binary patch literal 0 HcmV?d00001 literal 2058 zcmWIWW@h1H0D(u7j=O*vP=XUk`?`iW>U#RQ=?6fSaWFgtD*Ll&_WvB9bTbf(AS?5A z^z(Fc4Gz)sb^Gjl=CqHuuHHpnZ(Xf(XU=a9GPq*=;AxT8*)y6KOIK|P^3c@q($Q?} zSn{H3X-ad*jMtJ!W=nl4vJ_vcHf_nW22m?96}9vwT0hjLEq$gb@mlgF<5Su0NybK} zgSrKlu|HW7HbqSPfJ(*Aik%EF*D-)y2Xqh|umD-f`MGfSW2yjo6QrUfwYUVX4C2k7 z8Haw@FfuSa0AfjGWge+HIr-uFML8*Y$vKI|#km2ey_g*Z))@AmUAMZk^W$F|j!t&* z^Md+K6%ipFM?R+*AK~0=y=kUK-84B7n;(pIQ*Ib{@q5Vcda>%=tap|FD{7ewI^Hs* z>ik%-IPhRngW5D3o$8204f&Hkvy$7KR^Lt5nD?SFVZ|{c;pdaL=zr3_7k=bQ^4x-} zk9ThQY947~UUcR{kMLYKw;taTwJDdbTZK3Coz$Ez>3repWE;Wdm-<5Lt@+&k^tFEo z__#qTiT5?n!pY_D=Dtf*KBBfwLMm7;VMS!K$HyFr*e~u%hW}T*JA9*K3g2bn1pOb;Z@F(7A&NFP<=S%K?U$I|yr*u#Hhi!49b`h6Dv|g`BI<$PvnKv2hOcwiPeeF;En13W= z$=#a%?-IPz)GI}fFS!;Ivi?xS{dxVYEOixu3%nNJe%ATi=lTiG*Bm~6GlCvJVNX4G z+Q3KM_d%A>fp@!$#l9^$`Z+1uCa;V|&EDYO1OF(m&}Z&h95GKSI_iJ9{Rm2At}!|k zzudBMr4|R5`JeUH_0sY54fI$Q^1)Zf`|RT&K0lqn4_aq~4Gh8!wrnsm+Gb=B zR8YnlXkcVu@=yy}Hkn>AzF>TT_ggU!$F~ps554qH>Fa**+30)j{8epFUA>21I$9@v zynXZ-yBdG&GO!Z|mN<+|BFwl8PM{BfK!D+`BZ!8lVuUvA1t~}|2rOw-2a<4YNX06` z1k9ogRMx2-CQvkq?*&;M&lO zMr8M5%iu8E|Nn1fLh>;zyTjaonRP)K9-(<1re>t&2_93>ivyUM91PeB z1emEy8a0?Pyajg|s+rK@0TE)@a|XibDqw`e(+DKQ@EDEACjs89Y#>v(fN(F+%jT>g F9sr{cle_=` From d7c7237d2c661f4a6e71856cf9d81da3bd145be2 Mon Sep 17 00:00:00 2001 From: Jacek Laskowski Date: Wed, 25 Jun 2014 00:08:25 +0200 Subject: [PATCH 0292/1030] Typo fixes + removing unnecessary semicolons --- ivy/src/main/scala/sbt/Configuration.scala | 4 ++-- ivy/src/main/scala/sbt/Resolver.scala | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala index db4ada450..58b5073b8 100644 --- a/ivy/src/main/scala/sbt/Configuration.scala +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -24,14 +24,14 @@ object Configurations { case _ => c } - def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend (ext: _*) hide; + def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend (ext: _*) hide def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) lazy val Default = config("default") lazy val Compile = config("compile") lazy val IntegrationTest = config("it") extend (Runtime) - lazy val Provided = config("provided"); + lazy val Provided = config("provided") lazy val Docs = config("docs") lazy val Runtime = config("runtime") extend (Compile) lazy val Test = config("test") extend (Runtime) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index f6250705e..b9b715d0c 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -228,7 +228,7 @@ object Resolver { object sftp extends Define[SftpRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) } - /** A factory to construct an interface to an Ivy filesytem resolver. */ + /** A factory to construct an interface to an Ivy filesystem resolver. */ object file { /** * Constructs a file resolver with the given name. The patterns to use must be explicitly specified From 77aa9ea87e348326639fdb31f672abc995cf6145 Mon Sep 17 00:00:00 2001 From: Henrik Engstrom Date: Thu, 3 Jul 2014 18:57:48 -0400 Subject: [PATCH 0293/1030] Regex now handles versions that contain multiple '-' characters in the version. --- util/cross/src/main/input_sources/CrossVersionUtil.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/util/cross/src/main/input_sources/CrossVersionUtil.scala index d192a2f8b..24310b39c 100644 --- a/util/cross/src/main/input_sources/CrossVersionUtil.scala +++ b/util/cross/src/main/input_sources/CrossVersionUtil.scala @@ -24,7 +24,7 @@ object CrossVersionUtil { val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)([-\w+]*)""".r v match { case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) From f040f80215675fbf6508ecd8505b06fa78fb7931 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Jul 2014 17:49:52 -0400 Subject: [PATCH 0294/1030] Improves unresolved dependencies error by displaying the deps nodes. fixes #1422, #381 --- ivy/src/main/scala/sbt/IvyActions.scala | 30 ++++++++++++++++++--- ivy/src/main/scala/sbt/IvyRetrieve.scala | 34 ++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index c87666373..bdbf5fe1c 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -146,6 +146,17 @@ object IvyActions { withExtra foreach { id => log.warn("\t\t" + id) } log.warn("") } + err.failed foreach { x => + val failedPaths = err.failedPaths(x) + if (!failedPaths.isEmpty) { + log.warn("\n\tNote: Unresolved dependencies path:") + val reverseFailedPaths = (failedPaths.toList map { _.toString }).reverse + log.warn("\t\t" + reverseFailedPaths.head) + reverseFailedPaths.tail foreach { id => + log.warn("\t\t +- " + id) + } + } + } } def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = report.configurations.flatMap { confReport => @@ -209,8 +220,15 @@ object IvyActions { val err = if (resolveReport.hasError) { val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct - val failed = resolveReport.getUnresolvedDependencies.map(node => IvyRetrieve.toModuleID(node.getId)) - Some(new ResolveException(messages, failed)) + val failedPaths = Map(resolveReport.getUnresolvedDependencies map { node => + val m = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve.findPath(node, module.getModuleRevisionId) map { x => + IvyRetrieve.toModuleID(x.getId) + } + m -> path + }: _*) + val failed = failedPaths.keys.toSeq + Some(new ResolveException(messages, failed, failedPaths)) } else None (resolveReport, err) } @@ -269,4 +287,10 @@ object IvyActions { error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) } } -final class ResolveException(val messages: Seq[String], val failed: Seq[ModuleID]) extends RuntimeException(messages.mkString("\n")) +final class ResolveException( + val messages: Seq[String], + val failed: Seq[ModuleID], + val failedPaths: Map[ModuleID, Seq[ModuleID]]) extends RuntimeException(messages.mkString("\n")) { + def this(messages: Seq[String], failed: Seq[ModuleID]) = + this(messages, failed, Map(failed map { m => m -> Nil }: _*)) +} diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index 5d0f3f6ec..e863d6723 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -5,10 +5,10 @@ package sbt import java.io.File import collection.mutable - -import org.apache.ivy.core.{ module, report } +import org.apache.ivy.core.{ module, report, resolve } import module.descriptor.{ Artifact => IvyArtifact } import module.id.ModuleRevisionId +import resolve.IvyNode import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport } object IvyRetrieve { @@ -51,4 +51,34 @@ object IvyRetrieve { new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) + + /** + * Tries to find Ivy graph path the from node to target. + */ + def findPath(target: IvyNode, from: ModuleRevisionId): List[IvyNode] = { + def doFindPath(current: IvyNode, path: List[IvyNode]): List[IvyNode] = { + val callers = current.getAllRealCallers.toList + // Ivy actually returns non-direct callers here. + // that's why we have to calculate all possible paths below and pick the longest path. + val directCallers = callers filter { caller => + val md = caller.getModuleDescriptor + val dd = md.getDependencies.toList find { dd => + (dd.getDependencyRevisionId == current.getId) && + (dd.getParentRevisionId == caller.getModuleRevisionId) + } + dd.isDefined + } + val directCallersRevId = (directCallers map { _.getModuleRevisionId }).distinct + val paths: List[List[IvyNode]] = ((directCallersRevId map { revId => + val node = current.findNode(revId) + if (revId == from) node :: path + else if (node == node.getRoot) Nil + else if (path contains node) path + else doFindPath(node, node :: path) + }) sortBy { _.size }).reverse + paths.headOption getOrElse Nil + } + if (target.getId == from) List(target) + else doFindPath(target, List(target)) + } } From 8d33aa6482ad7e8351f61783381475c5c35f6af9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Jul 2014 02:12:46 -0400 Subject: [PATCH 0295/1030] Consolidated resolution. Fixes #413 This adds a new setting key called updateOptions, which can enable consolidated resolution for update task. The consolidated resolution automatically generates an artificial module descriptor based on the SHA-1 of all external dependencies. This consolidates the Ivy resolution of identical Ivy dependency graph across multiple subprojects. This is how it's enabled: updateOptions := updateOptions.value.withConsolidatedResolution(true) --- ivy/src/main/scala/sbt/Ivy.scala | 37 +++++- ivy/src/main/scala/sbt/IvyActions.scala | 9 ++ .../main/scala/sbt/IvyConfigurations.scala | 29 ++++- ivy/src/main/scala/sbt/ProjectResolver.scala | 6 + ivy/src/main/scala/sbt/UpdateOptions.scala | 27 ++++ .../ivyint/ConsolidatedResolveEngine.scala | 120 ++++++++++++++++++ 6 files changed, 219 insertions(+), 9 deletions(-) create mode 100644 ivy/src/main/scala/sbt/UpdateOptions.scala create mode 100644 ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 7f54fb4b4..78c8e3b99 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -4,6 +4,7 @@ package sbt import Resolver.PluginPattern +import ivyint.{ ConsolidatedResolveEngine, ConsolidatedResolveCache } import java.io.File import java.net.URI @@ -14,12 +15,14 @@ import CS.singleton import org.apache.ivy.Ivy import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } +import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } import org.apache.ivy.core.module.descriptor.{ OverrideDependencyDescriptorMediator } import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } -import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision } +import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision, ResolveEngine } import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.core.sort.SortEngine import org.apache.ivy.plugins.latest.LatestRevisionStrategy import org.apache.ivy.plugins.matcher.PatternMatcher import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorParser @@ -28,6 +31,7 @@ import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{ NodeSeq, Text } +import scala.collection.mutable final class IvySbt(val configuration: IvyConfiguration) { import configuration.baseDirectory @@ -76,7 +80,23 @@ final class IvySbt(val configuration: IvyConfiguration) { } private lazy val ivy: Ivy = { - val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine; override def getLoggerEngine = loggerEngine } + val i = new Ivy() { + private val loggerEngine = new SbtMessageLoggerEngine + override def getLoggerEngine = loggerEngine + override def bind(): Unit = { + val prOpt = Option(getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } + // We inject the deps we need before we can hook our resolve engine. + setSortEngine(new SortEngine(getSettings)) + setEventManager(new EventManager()) + if (configuration.updateOptions.consolidatedResolution) { + setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with ConsolidatedResolveEngine { + val consolidatedResolveCache = IvySbt.consolidatedResolveCache + val projectResolver = prOpt + }) + } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) + super.bind() + } + } i.setSettings(settings) i.bind() i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) @@ -103,6 +123,18 @@ final class IvySbt(val configuration: IvyConfiguration) { } } + /** + * Cleans consolidated resolution cache. + * @param md - module descriptor of the original Ivy graph. + */ + private[sbt] def cleanConsolidatedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = + withIvy(log) { i => + val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } + if (configuration.updateOptions.consolidatedResolution) { + IvySbt.consolidatedResolveCache.clean(md, prOpt) + } + } + final class Module(rawModuleSettings: ModuleSettings) { val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) def owner = IvySbt.this @@ -204,6 +236,7 @@ private object IvySbt { val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" val DefaultChecksums = Seq("sha1", "md5") + private[sbt] val consolidatedResolveCache: ConsolidatedResolveCache = new ConsolidatedResolveCache() def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index bdbf5fe1c..4960c9a2d 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -59,6 +59,15 @@ object IvyActions { iv.getSettings.getRepositoryCacheManagers.foreach(_.clean()) } + /** + * Cleans the consolidated resolution cache, if any. + * This is called by clean. + */ + private[sbt] def cleanConsolidatedResolutionCache(module: IvySbt#Module, log: Logger): Unit = + module.withModule(log) { (ivy, md, default) => + module.owner.cleanConsolidatedResolutionCache(md, log) + } + /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { import configuration.{ allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes } diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index 93025e2d7..b3e1dba1b 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -16,27 +16,42 @@ sealed trait IvyConfiguration { def baseDirectory: File def log: Logger def withBase(newBaseDirectory: File): This + def updateOptions: UpdateOptions } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val resolutionCacheDir: Option[File], val log: Logger) extends IvyConfiguration { - @deprecated("Use the variant that accepts the resolution cache location.", "0.13.0") + val checksums: Seq[String], val resolutionCacheDir: Option[File], val updateOptions: UpdateOptions, + val log: Logger) extends IvyConfiguration { + @deprecated("Use the variant that accepts resolutionCacheDir and updateOptions.", "0.13.0") def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], checksums: Seq[String], log: Logger) = - this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, log) + this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, UpdateOptions(), log) + + @deprecated("Use the variant that accepts updateOptions.", "0.13.6") + def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], + moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], + checksums: Seq[String], resolutionCacheDir: Option[File], log: Logger) = + this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, UpdateOptions(), log) type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, log) + def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, + resolutionCacheDir, updateOptions, log) + def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, + resolutionCacheDir, updateOptions, log) } -final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val log: Logger) extends IvyConfiguration { +final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], + val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration { + @deprecated("Use the variant that accepts updateOptions.", "0.13.6") + def this(baseDirectory: File, uri: URI, lock: Option[xsbti.GlobalLock], extraResolvers: Seq[Resolver], log: Logger) = + this(baseDirectory, uri, lock, extraResolvers, UpdateOptions(), log) + type This = ExternalIvyConfiguration def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, log) } object ExternalIvyConfiguration { - def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, log) + def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, UpdateOptions(), log) } object IvyConfiguration { diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index 92fa48bfe..a51e0abb8 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -34,6 +34,8 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] map get revisionId map constructResult } + private[sbt] def getModuleDescriptor(revisionId: ModuleRevisionId): Option[ModuleDescriptor] = map.get(revisionId) + def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = { val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) @@ -87,3 +89,7 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } } + +object ProjectResolver { + private[sbt] val InterProject = "inter-project" +} diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala new file mode 100644 index 000000000..acea391f7 --- /dev/null +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -0,0 +1,27 @@ +package sbt + +import java.io.File + +/** + * Represents configurable options for update task. + * While UpdateConfiguration is passed into update at runtime, + * UpdateOption is intended to be used while setting up the Ivy object. + * + * See also UpdateConfiguration in IvyActions.scala. + */ +final class UpdateOptions( + /** If set to true, use consolidated resolution. */ + val consolidatedResolution: Boolean) { + + def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = + copy(consolidatedResolution = consolidatedResolution) + + private[sbt] def copy( + consolidatedResolution: Boolean = this.consolidatedResolution): UpdateOptions = + new UpdateOptions(consolidatedResolution) +} + +object UpdateOptions { + def apply(): UpdateOptions = + new UpdateOptions(false) +} diff --git a/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala new file mode 100644 index 000000000..c853791c8 --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala @@ -0,0 +1,120 @@ +package sbt +package ivyint + +import java.io.File +import collection.concurrent +import org.apache.ivy.core +import core.resolve._ +import core.module.id.ModuleRevisionId +import core.report.ResolveReport +import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor } +import core.{ IvyPatternHelper, LogOptions } +import org.apache.ivy.util.Message + +private[sbt] object ConsolidatedResolveCache { + def createID(organization: String, name: String, revision: String) = + ModuleRevisionId.newInstance(organization, name, revision) + def sbtOrgTemp = "org.scala-sbt.temp" +} + +private[sbt] class ConsolidatedResolveCache() { + import ConsolidatedResolveCache._ + val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() + val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() + val directDependencyCache: concurrent.Map[ModuleDescriptor, Vector[DependencyDescriptor]] = concurrent.TrieMap() + + def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { + val mrid0 = md0.getModuleRevisionId + val md1 = if (mrid0.getOrganisation == sbtOrgTemp) md0 + else buildConsolidatedModuleDescriptor(md0, prOpt) + val mrid1 = md1.getModuleRevisionId + resolveReportCache.remove(mrid1) + resolvePropertiesCache.remove(mrid1) + } + + def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = + directDependencyCache.getOrElseUpdate(md0, md0.getDependencies.toVector) + + def buildConsolidatedModuleDescriptor(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): DefaultModuleDescriptor = { + def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] = + prOpt map { + _.getModuleDescriptor(dep.getDependencyRevisionId) match { + case Some(internal) => directDependencies(internal) flatMap expandInternalDeps + case _ => Vector(dep) + } + } getOrElse Vector(dep) + val expanded = directDependencies(md0) flatMap expandInternalDeps + val depStrings = expanded map { dep => + val mrid = dep.getDependencyRevisionId + val confMap = (dep.getModuleConfigurations map { conf => + conf + "->(" + dep.getDependencyConfigurations(conf).mkString(",") + ")" + }) + mrid.toString + ";" + confMap.mkString(";") + } + val depsString = depStrings.distinct.sorted.mkString("\n") + val sha1 = Hash.toHex(Hash(depsString)) + // println("sha1: " + sha1) + val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) + md1 + } +} + +private[sbt] trait ConsolidatedResolveEngine extends ResolveEngine { + import ConsolidatedResolveCache._ + + private[sbt] def consolidatedResolveCache: ConsolidatedResolveCache + private[sbt] def projectResolver: Option[ProjectResolver] + + /** + * Resolve dependencies of a module described by a module descriptor. + */ + override def resolve(md0: ModuleDescriptor, options0: ResolveOptions): ResolveReport = { + val cache = consolidatedResolveCache + val cacheManager = getSettings.getResolutionCacheManager + val md1 = cache.buildConsolidatedModuleDescriptor(md0, projectResolver) + val md1mrid = md1.getModuleRevisionId + + def doWork: (ResolveReport, String) = { + if (options0.getLog != LogOptions.LOG_QUIET) { + Message.info("Consolidating managed dependencies to " + md1mrid.toString + " ...") + } + md1.setLastModified(System.currentTimeMillis) + for { + x <- md0.getConfigurations + } yield md1.addConfiguration(x) + + for { + x <- md0.getDependencies + } yield md1.addDependency(x) + + val options1 = new ResolveOptions(options0) + options1.setOutputReport(false) + val report0 = super.resolve(md1, options1) + val ivyPropertiesInCache1 = cacheManager.getResolvedIvyPropertiesInCache(md1.getResolvedModuleRevisionId) + val prop0 = + if (ivyPropertiesInCache1.exists) IO.read(ivyPropertiesInCache1) + else "" + if (options0.isOutputReport) { + this.outputReport(report0, cacheManager, options0) + } + cache.resolveReportCache(md1mrid) = report0 + cache.resolvePropertiesCache(md1mrid) = prop0 + (report0, prop0) + } + + val (report0, prop0) = (cache.resolveReportCache.get(md1mrid), cache.resolvePropertiesCache.get(md1mrid)) match { + case (Some(report), Some(prop)) => + if (options0.getLog != LogOptions.LOG_QUIET) { + Message.info("Found consolidated dependency " + md1mrid.toString + " ...") + } + (report, prop) + case _ => doWork + } + cacheManager.saveResolvedModuleDescriptor(md0) + if (prop0 != "") { + val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) + IO.write(ivyPropertiesInCache0, prop0) + } + report0 + } +} From 5e6f0c4ff19a04fbf437fa0b99e6f537aa7682cf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 18 Jul 2014 04:50:23 -0400 Subject: [PATCH 0296/1030] Expand ModuleReport into the full Ivy resolution report. #1200 Currently sbt's update task generates UpdateReport from Ivy's resolution report. For each configuration there's ConfigurationReport, which contains just enough information on the resolved module/revision/artifact. Speaking of module, in Ivy module means organization and name, and organization, name, and version is called module revision. In sbt, module revision is called Module. This is relevant because to talk about evictions, we need a terminology for organization and name combo. In any case ConfigurationReport is expanded to have `details` field, which contains Seq[ModuleDetailReport], which represents organization and name combo plus all the modules just like Ivy's resolution report XML. Furthermore, ModuleReport is expanded to include licenses, eviction, callers, etc. --- ivy/src/main/scala/sbt/ConflictWarning.scala | 5 + ivy/src/main/scala/sbt/IvyRetrieve.scala | 108 ++++++++++++++-- ivy/src/main/scala/sbt/UpdateReport.scala | 124 ++++++++++++++++--- 3 files changed, 206 insertions(+), 31 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 7c5c9a918..6e6b8a37d 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -2,6 +2,11 @@ package sbt import DependencyFilter._ +/** + * Provide warnings for cross version conflicts. + * A library foo_2.10 and foo_2.11 can potentially be both included on the + * library dependency graph by mistake, but it won't be caught by eviction. + */ final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) { @deprecated("`filter` is no longer used", "0.13.0") val filter: ModuleFilter = (_: ModuleID) => false diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index e863d6723..5998f2a22 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -4,35 +4,121 @@ package sbt import java.io.File +import java.{ util => ju } import collection.mutable +import java.net.URL import org.apache.ivy.core.{ module, report, resolve } -import module.descriptor.{ Artifact => IvyArtifact } -import module.id.ModuleRevisionId -import resolve.IvyNode +import module.descriptor.{ Artifact => IvyArtifact, License => IvyLicense } +import module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport } +import resolve.{ IvyNode, IvyNodeCallers } +import IvyNodeCallers.{ Caller => IvyCaller } object IvyRetrieve { def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = report.getConfigurations map report.getConfigurationReport def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] = - for (revId <- confReport.getModuleRevisionIds.toArray collect { case revId: ModuleRevisionId => revId }) yield artifactReports(toModuleID(revId), confReport getDownloadReports revId) + for { + revId <- confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } + } yield moduleRevisionDetail(confReport, confReport.getDependency(revId)) + @deprecated("Internal only. No longer in use.", "0.13.6") def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = + { + val (resolved, missing) = artifacts(mid, artReport) + ModuleReport(mid, resolved, missing) + } + + private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Seq[(Artifact, File)], Seq[Artifact]) = { val missing = new mutable.ListBuffer[Artifact] val resolved = new mutable.ListBuffer[(Artifact, File)] for (r <- artReport) { - val file = r.getLocalFile + val fileOpt = Option(r.getLocalFile) val art = toArtifact(r.getArtifact) - if (file eq null) - missing += art - else - resolved += ((art, file)) + fileOpt match { + case Some(file) => resolved += ((art, file)) + case None => missing += art + } } - new ModuleReport(mid, resolved.toSeq, missing.toSeq) + (resolved.toSeq, missing.toSeq) } + // We need this because current module report used as part of UpdateReport/ConfigurationReport contains + // only the revolved modules. + // Sometimes the entire module can be excluded via rules etc. + private[sbt] def details(confReport: ConfigurationResolveReport): Seq[ModuleDetailReport] = { + val dependencies = confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } + val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId } + def moduleDetail(mid: IvyModuleId): ModuleDetailReport = { + val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } + new ModuleDetailReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) }) + } + moduleIds map { moduleDetail } + } + + private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = { + def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] = + Map(ea.entrySet.toArray collect { + case entry: ju.Map.Entry[_, _] => (entry.getKey.toString, entry.getValue.toString) + }: _*) + def toCaller(caller: IvyCaller): Caller = { + val m = toModuleID(caller.getModuleRevisionId) + val callerConfigurations = caller.getCallerConfigurations.toArray.toVector + val extraAttributes = toExtraAttributes(caller.getDependencyDescriptor.getExtraAttributes) + new Caller(m, callerConfigurations, extraAttributes) + } + val revId = dep.getResolvedId + val moduleId = toModuleID(revId) + val branch = Some(revId.getBranch) + val (status, publicationDate, resolver, artifactResolver) = dep.isLoaded match { + case true => + (Some(dep.getDescriptor.getStatus), + Some(new ju.Date(dep.getPublication)), + Some(dep.getModuleRevision.getResolver.getName), + Some(dep.getModuleRevision.getArtifactResolver.getName)) + case _ => (None, None, None, None) + } + val (evicted, evictedData, evictedReason) = dep.isEvicted(confReport.getConfiguration) match { + case true => + val ed = dep.getEvictedData(confReport.getConfiguration) + (true, + Some(Option(ed.getConflictManager) map { _.toString } getOrElse { "transitive" }), + Option(ed.getDetail)) + case _ => (false, None, None) + } + val problem = dep.hasProblem match { + case true => Some(dep.getProblem.getMessage) + case _ => None + } + val mdOpt = for { + mr <- Option(dep.getModuleRevision) + md <- Option(mr.getDescriptor) + } yield md + val homepage = mdOpt match { + case Some(md) => + Option(md.getHomePage) + case _ => None + } + val extraAttributes: Map[String, String] = toExtraAttributes(mdOpt match { + case Some(md) => md.getExtraAttributes + case _ => dep.getResolvedId.getExtraAttributes + }) + val isDefault = Option(dep.getDescriptor) map { _.isDefault } + val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList + val licenses: Seq[(String, URL)] = mdOpt match { + case Some(md) => md.getLicenses.toArray.toVector collect { case lic: IvyLicense => (lic.getName, new URL(lic.getUrl)) } + case _ => Nil + } + val callers = dep.getCallers(confReport.getConfiguration).toArray.toVector map { toCaller } + val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) + + new ModuleReport(moduleId, resolved, missing, status, publicationDate, resolver, artifactResolver, + evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, + configurations, licenses, callers) + } + def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = confReport.getEvictedNodes.map(node => toModuleID(node.getId)) @@ -50,7 +136,7 @@ object IvyRetrieve { def updateStats(report: ResolveReport): UpdateStats = new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), evicted(confReport)) + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), details(confReport), evicted(confReport)) /** * Tries to find Ivy graph path the from node to target. diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 71d58390b..39ad7357b 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -4,6 +4,8 @@ package sbt import java.io.File +import java.net.URL +import java.{ util => ju } /** * Provides information about dependency resolution. @@ -37,9 +39,18 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con /** * Provides information about resolution of a single configuration. * @param configuration the configuration this report is for. - * @param modules a seqeuence containing one report for each module resolved for this configuration. + * @param modules a sequence containing one report for each module resolved for this configuration. + * @param details a sequence containing one report for each org/name, which may or may not be part of the final resolution. + * @param evicted a sequence of evicted modules */ -final class ConfigurationReport(val configuration: String, val modules: Seq[ModuleReport], val evicted: Seq[ModuleID]) { +final class ConfigurationReport( + val configuration: String, + val modules: Seq[ModuleReport], + val details: Seq[ModuleDetailReport], + val evicted: Seq[ModuleID]) { + // def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = + // this(configuration, modules, Nil, evicted) + override def toString = "\t" + configuration + ":\n" + modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString /** @@ -50,25 +61,94 @@ final class ConfigurationReport(val configuration: String, val modules: Seq[Modu private[this] def addConfiguration(mod: ModuleID): ModuleID = if (mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, evicted) + new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details, evicted) +} + +/** + * In sbt's terminology, "module" consists of organization, name, and version. + * In Ivy's, "module" means just organization and name, and the one including version numbers + * are called revisions. + */ +final class ModuleDetailReport( + val organization: String, + val name: String, + val modules: Seq[ModuleReport]) { + override def toString: String = + { s"$organization:$name" } } /** * Provides information about the resolution of a module. * This information is in the context of a specific configuration. * @param module the `ModuleID` this report is for. - * @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. This File may be in the + * @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. + * @param missingArtifacts the missing artifacts for this module. */ -final class ModuleReport(val module: ModuleID, val artifacts: Seq[(Artifact, File)], val missingArtifacts: Seq[Artifact]) { - override def toString = - { - val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) - "\t\t" + module + ": " + - (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" - } +final class ModuleReport( + val module: ModuleID, + val artifacts: Seq[(Artifact, File)], + val missingArtifacts: Seq[Artifact], + val status: Option[String], + val publicationDate: Option[ju.Date], + val resolver: Option[String], + val artifactResolver: Option[String], + val evicted: Boolean, + val evictedData: Option[String], + val evictedReason: Option[String], + val problem: Option[String], + val homepage: Option[String], + val extraAttributes: Map[String, String], + val isDefault: Option[Boolean], + val branch: Option[String], + val configurations: Seq[String], + val licenses: Seq[(String, URL)], + val callers: Seq[Caller]) { + + override def toString = { + val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + s"\t\t$module: " + + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" + } def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = - new ModuleReport(module, artifacts.map { case (art, file) => (art, f(module, art, file)) }, missingArtifacts) + copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) + + private[sbt] def copy( + module: ModuleID = module, + artifacts: Seq[(Artifact, File)] = artifacts, + missingArtifacts: Seq[Artifact] = missingArtifacts, + status: Option[String] = status, + publicationDate: Option[ju.Date] = publicationDate, + resolver: Option[String] = resolver, + artifactResolver: Option[String] = artifactResolver, + evicted: Boolean = evicted, + evictedData: Option[String] = evictedData, + evictedReason: Option[String] = evictedReason, + problem: Option[String] = problem, + homepage: Option[String] = homepage, + extraAttributes: Map[String, String] = extraAttributes, + isDefault: Option[Boolean] = isDefault, + branch: Option[String] = branch, + configurations: Seq[String] = configurations, + licenses: Seq[(String, URL)] = licenses, + callers: Seq[Caller] = callers): ModuleReport = + new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, + evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } + +object ModuleReport { + def apply(module: ModuleID, artifacts: Seq[(Artifact, File)], missingArtifacts: Seq[Artifact]): ModuleReport = + new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, + false, None, None, None, None, Map(), None, None, Nil, Nil, Nil) +} + +final class Caller( + val caller: ModuleID, + val callerConfigurations: Seq[String], + val callerExtraAttributes: Map[String, String]) { + override def toString: String = + s"$caller" +} + object UpdateReport { implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) @@ -101,15 +181,18 @@ object UpdateReport { /** Constructs a new report that only contains files matching the specified filter.*/ def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => - import modReport._ - val newArtifacts = artifacts filter { case (art, file) => f(configuration, module, art) } - val newMissing = missingArtifacts filter { art => f(configuration, module, art) } - new ModuleReport(module, newArtifacts, newMissing) + modReport.copy( + artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, + missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } + ) } def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) - new ModuleReport(modReport.module, newArtifacts, Nil) + modReport.copy( + artifacts = f(configuration, modReport.module, modReport.artifacts), + missingArtifacts = Nil + ) } def toSeq: Seq[(String, ModuleID, Artifact, File)] = @@ -120,8 +203,9 @@ object UpdateReport { def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => - import modReport._ - new ModuleReport(module, artifacts, (missingArtifacts ++ f(module)).distinct) + modReport.copy( + missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct + ) } def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = @@ -129,7 +213,7 @@ object UpdateReport { val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, evicted) + new ConfigurationReport(configuration, newModules, details, evicted) } new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } From 05b97b400744b0a7c1b309ea5e3121485c26f7ea Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 18 Jul 2014 06:17:37 -0400 Subject: [PATCH 0297/1030] Implemented general eviction warning. #1200 a> update [info] Updating {file:/foo/}a... [info] Resolving org.fusesource.jansi#jansi;1.4 ... [info] Done updating. [warn] Some dependencies were evicted: [warn] * org.scala-lang:scala-library (2.10.1) -> 2.10.3 --- ivy/src/main/scala/sbt/EvictionWarning.scala | 44 ++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 ivy/src/main/scala/sbt/EvictionWarning.scala diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala new file mode 100644 index 000000000..4d3baec98 --- /dev/null +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -0,0 +1,44 @@ +package sbt + +import collection.mutable + +final class EvictionWarningOptions( + val configurations: Seq[String], + val level: Level.Value) { +} +object EvictionWarningOptions { + def apply(): EvictionWarningOptions = + new EvictionWarningOptions(Vector("compile"), Level.Warn) +} + +object EvictionWarning { + def apply(options: EvictionWarningOptions, report: UpdateReport, log: Logger): Unit = { + val evictions = buildEvictions(options, report) + processEvictions(evictions, log) + } + + private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[ModuleDetailReport] = { + val buffer: mutable.ListBuffer[ModuleDetailReport] = mutable.ListBuffer() + val confs = report.configurations filter { x => options.configurations contains x.configuration } + confs flatMap { confReport => + confReport.details map { detail => + if ((detail.modules exists { _.evicted }) && + !(buffer exists { x => (x.organization == detail.organization) && (x.name == detail.name) })) { + buffer += detail + } + } + } + buffer.toList.toVector + } + + private[sbt] def processEvictions(evictions: Seq[ModuleDetailReport], log: Logger): Unit = { + if (!evictions.isEmpty) { + log.warn("Some dependencies were evicted:") + evictions foreach { detail => + val revs = detail.modules filter { _.evicted } map { _.module.revision } + val winner = (detail.modules filterNot { _.evicted } map { _.module.revision }).headOption map { " -> " + _ } getOrElse "" + log.warn(s"\t* ${detail.organization}:${detail.name} (${revs.mkString(", ")})$winner") + } + } + } +} From 71e7e12b9945fe532c14b3a899c17ecbda9be8e6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 18 Jul 2014 16:27:11 -0400 Subject: [PATCH 0298/1030] Fixing NullPointerError caused by reading String from Ivy directly --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 10 ++--- ivy/src/main/scala/sbt/UpdateReport.scala | 47 +++++++++++++++++++---- 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index 5998f2a22..e9dba98ee 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -71,13 +71,13 @@ object IvyRetrieve { } val revId = dep.getResolvedId val moduleId = toModuleID(revId) - val branch = Some(revId.getBranch) + val branch = Option(revId.getBranch) val (status, publicationDate, resolver, artifactResolver) = dep.isLoaded match { case true => - (Some(dep.getDescriptor.getStatus), + (Option(dep.getDescriptor.getStatus), Some(new ju.Date(dep.getPublication)), - Some(dep.getModuleRevision.getResolver.getName), - Some(dep.getModuleRevision.getArtifactResolver.getName)) + Option(dep.getModuleRevision.getResolver.getName), + Option(dep.getModuleRevision.getArtifactResolver.getName)) case _ => (None, None, None, None) } val (evicted, evictedData, evictedReason) = dep.isEvicted(confReport.getConfiguration) match { @@ -89,7 +89,7 @@ object IvyRetrieve { case _ => (false, None, None) } val problem = dep.hasProblem match { - case true => Some(dep.getProblem.getMessage) + case true => Option(dep.getProblem.getMessage) case _ => None } val mdOpt = for { diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 39ad7357b..f8c2804d5 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -48,10 +48,12 @@ final class ConfigurationReport( val modules: Seq[ModuleReport], val details: Seq[ModuleDetailReport], val evicted: Seq[ModuleID]) { - // def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = - // this(configuration, modules, Nil, evicted) + def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = + this(configuration, modules, Nil, evicted) - override def toString = "\t" + configuration + ":\n" + modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString + override def toString = s"\t$configuration:\n" + + (if (details.isEmpty) modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString + else details.mkString) /** * All resolved modules for this configuration. @@ -73,8 +75,10 @@ final class ModuleDetailReport( val organization: String, val name: String, val modules: Seq[ModuleReport]) { - override def toString: String = - { s"$organization:$name" } + override def toString: String = { + val details = modules map { _.detailReport } + s"\t$organization:$name\n${details.mkString}\n" + } } /** @@ -104,11 +108,40 @@ final class ModuleReport( val licenses: Seq[(String, URL)], val callers: Seq[Caller]) { - override def toString = { - val arts = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + override def toString: String = { s"\t\t$module: " + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" } + private[sbt] def detailReport: String = + s"\t\t- ${module.revision}\n" + + (if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) + + reportStr("status", status) + + reportStr("publicationDate", publicationDate map { _.toString }) + + reportStr("resolver", resolver) + + reportStr("artifactResolver", artifactResolver) + + reportStr("evicted", Some(evicted.toString)) + + reportStr("evictedData", evictedData) + + reportStr("evictedReason", evictedReason) + + reportStr("problem", problem) + + reportStr("homepage", homepage) + + reportStr("textraAttributes", + if (extraAttributes.isEmpty) None + else { Some(extraAttributes.toString) }) + + reportStr("isDefault", isDefault map { _.toString }) + + reportStr("branch", branch) + + reportStr("configurations", + if (configurations.isEmpty) None + else { Some(configurations.mkString(", ")) }) + + reportStr("licenses", + if (licenses.isEmpty) None + else { Some(licenses.mkString(", ")) }) + + reportStr("callers", + if (callers.isEmpty) None + else { Some(callers.mkString(", ")) }) + private[sbt] def reportStr(key: String, value: Option[String]): String = + value map { x => s"\t\t\t$key: $x\n" } getOrElse "" + def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) From 3fe8f41a69ecae8e39a4f04f11cccd8db29a9a78 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 27 Jul 2014 12:01:11 -0400 Subject: [PATCH 0299/1030] Fixing more NullPointerError by wrapping license URL with Option --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 9 ++++++--- ivy/src/main/scala/sbt/UpdateReport.scala | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index e9dba98ee..b3bf04563 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -107,9 +107,12 @@ object IvyRetrieve { }) val isDefault = Option(dep.getDescriptor) map { _.isDefault } val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList - val licenses: Seq[(String, URL)] = mdOpt match { - case Some(md) => md.getLicenses.toArray.toVector collect { case lic: IvyLicense => (lic.getName, new URL(lic.getUrl)) } - case _ => Nil + val licenses: Seq[(String, Option[String])] = mdOpt match { + case Some(md) => md.getLicenses.toArray.toVector collect { + case lic: IvyLicense => + (lic.getName, Option(lic.getUrl)) + } + case _ => Nil } val callers = dep.getCallers(confReport.getConfiguration).toArray.toVector map { toCaller } val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index f8c2804d5..41ea4fd80 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -105,7 +105,7 @@ final class ModuleReport( val isDefault: Option[Boolean], val branch: Option[String], val configurations: Seq[String], - val licenses: Seq[(String, URL)], + val licenses: Seq[(String, Option[String])], val callers: Seq[Caller]) { private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) @@ -162,7 +162,7 @@ final class ModuleReport( isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Seq[String] = configurations, - licenses: Seq[(String, URL)] = licenses, + licenses: Seq[(String, Option[String])] = licenses, callers: Seq[Caller] = callers): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) From 439f8498b67abc21e1e2adad9c0550e57d65e74c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 27 Jul 2014 12:14:30 -0400 Subject: [PATCH 0300/1030] pseudo-case class VersionNumber VersionNumber is a pseudo-case class that represents any form of version number. The unapply extractor can parse String into three sequences that makes up VersionNumber. VersionNumberCompatibility trait uses two VersionNumber instances to evaluate binary compatibility between them. Two implementations SemVer and SecondSegment are provided. --- ivy/src/main/scala/sbt/VersionNumber.scala | 147 +++++++++++++++++++++ ivy/src/test/scala/VersionNumberSpec.scala | 122 +++++++++++++++++ 2 files changed, 269 insertions(+) create mode 100644 ivy/src/main/scala/sbt/VersionNumber.scala create mode 100644 ivy/src/test/scala/VersionNumberSpec.scala diff --git a/ivy/src/main/scala/sbt/VersionNumber.scala b/ivy/src/main/scala/sbt/VersionNumber.scala new file mode 100644 index 000000000..7db8c8fef --- /dev/null +++ b/ivy/src/main/scala/sbt/VersionNumber.scala @@ -0,0 +1,147 @@ +package sbt + +final class VersionNumber private[sbt] ( + val numbers: Seq[Long], + val tags: Seq[String], + val extras: Seq[String]) { + def _1: Option[Long] = get(0) + def _2: Option[Long] = get(1) + def _3: Option[Long] = get(2) + def _4: Option[Long] = get(3) + def get(idx: Int): Option[Long] = + if (size <= idx) None + else Some(numbers(idx)) + def size: Int = numbers.size + + private[this] val versionStr: String = + numbers.mkString(".") + + (tags match { + case Seq() => "" + case ts => "-" + ts.mkString("-") + }) + + extras.mkString("") + override def toString: String = versionStr + override def hashCode: Int = + numbers.hashCode * 41 * 41 + + tags.hashCode * 41 + + extras.hashCode + override def equals(o: Any): Boolean = + o match { + case v: VersionNumber => (this.numbers == v.numbers) && (this.tags == v.tags) && (this.extras == v.extras) + case _ => false + } +} + +object VersionNumber { + /** + * @param numbers numbers delimited by a dot. + * @param tags string prefixed by a dash. + * @param any other strings at the end. + */ + def apply(numbers: Seq[Long], tags: Seq[String], extras: Seq[String]): VersionNumber = + new VersionNumber(numbers, tags, extras) + def apply(v: String): VersionNumber = + unapply(v) match { + case Some((ns, ts, es)) => VersionNumber(ns, ts, es) + case _ => sys.error(s"Invalid version number: $v") + } + + def unapply(v: VersionNumber): Option[(Seq[Long], Seq[String], Seq[String])] = + Some((v.numbers, v.tags, v.extras)) + + def unapply(v: String): Option[(Seq[Long], Seq[String], Seq[String])] = { + def splitDot(s: String): Vector[Long] = + Option(s) match { + case Some(x) => x.split('.').toVector.filterNot(_ == "").map(_.toLong) + case _ => Vector() + } + def splitDash(s: String): Vector[String] = + Option(s) match { + case Some(x) => x.split('-').toVector.filterNot(_ == "") + case _ => Vector() + } + def splitPlus(s: String): Vector[String] = + Option(s) match { + case Some(x) => x.split('+').toVector.filterNot(_ == "").map("+" + _) + case _ => Vector() + } + val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+)*)((?:\+.+)*)""".r + val NonSpaceString = """(\S+)""".r + v match { + case TaggedVersion(m, ns, ts, es) => Some((Vector(m.toLong) ++ splitDot(ns), splitDash(ts), splitPlus(es))) + case "" => None + case NonSpaceString(s) => Some((Vector(), Vector(), Vector(s))) + case _ => None + } + } + + /** + * Strict. Checks everythig. + */ + object Strict extends VersionNumberCompatibility { + def name: String = "Strict" + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = v1 == v2 + } + + /** + * Semantic versioning. See http://semver.org/spec/v2.0.0.html + */ + object SemVer extends VersionNumberCompatibility { + def name: String = "Semantic Versioning" + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = + doIsCompat(v1, v2) || doIsCompat(v2, v1) + private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = + (v1, v2) match { + case (v1, v2) if (v1.size >= 2) && (v2.size >= 2) => // A normal version number MUST take the form X.Y.Z + (v1._1.get, v1._2.get, v1._3.getOrElse(0), v1.tags, v2._1.get, v2._2.get, v2._3.getOrElse(0), v2.tags) match { + case (0L, _, _, _, 0L, _, _, _) => + // Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable. + equalsIgnoreExtra(v1, v2) + case (_, 0, 0, ts1, _, 0, 0, ts2) if (!ts1.isEmpty) || (!ts2.isEmpty) => + // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers + equalsIgnoreExtra(v1, v2) + case (x1, _, _, _, x2, _, _, _) => + // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. + // Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced + x1 == x2 + case _ => equalsIgnoreExtra(v1, v2) + } + case _ => false + } + // Build metadata SHOULD be ignored when determining version precedence. + private[this] def equalsIgnoreExtra(v1: VersionNumber, v2: VersionNumber): Boolean = + (v1.numbers == v2.numbers) && (v1.tags == v2.tags) + } + + /* A variant of SemVar that seems to be common among the Scala libraries. + * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. + * Also API comatibility is expected even when the first segment is zero. + */ + object SecondSegment extends VersionNumberCompatibility { + def name: String = "Second Segment Variant" + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = + doIsCompat(v1, v2) || doIsCompat(v2, v1) + private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = + (v1, v2) match { + case (v1, v2) if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z + (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { + case (x1, y1, 0, ts1, x2, y2, 0, ts2) if (!ts1.isEmpty) || (!ts2.isEmpty) => + // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers + equalsIgnoreExtra(v1, v2) + case (x1, y1, _, _, x2, y2, _, _) => + // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible changes are introduced. + (x1 == x2) && (y1 == y2) + case _ => equalsIgnoreExtra(v1, v2) + } + case _ => false + } + // Build metadata SHOULD be ignored when determining version precedence. + private[this] def equalsIgnoreExtra(v1: VersionNumber, v2: VersionNumber): Boolean = + (v1.numbers == v2.numbers) && (v1.tags == v2.tags) + } +} + +trait VersionNumberCompatibility { + def name: String + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean +} diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/ivy/src/test/scala/VersionNumberSpec.scala new file mode 100644 index 000000000..7b836050f --- /dev/null +++ b/ivy/src/test/scala/VersionNumberSpec.scala @@ -0,0 +1,122 @@ +package sbt + +import org.specs2._ + +class VersionNumberSpec extends Specification { + def is = s2""" + + This is a specification to check the version number parsing. + + 1 should + ${beParsedAs("1", Seq(1), Seq(), Seq())} + ${breakDownTo("1", Some(1))} + + 1.0 should + ${beParsedAs("1.0", Seq(1, 0), Seq(), Seq())} + ${breakDownTo("1.0", Some(1), Some(0))} + + 1.0.0 should + ${beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq())} + ${breakDownTo("1.0.0", Some(1), Some(0), Some(0))} + + ${beSemVerCompatWith("1.0.0", "1.0.1")} + ${beSemVerCompatWith("1.0.0", "1.1.1")} + ${notBeSemVerCompatWith("1.0.0", "2.0.0")} + ${notBeSemVerCompatWith("1.0.0", "1.0.0-M1")} + + ${beSecSegCompatWith("1.0.0", "1.0.1")} + ${notBeSecSegCompatWith("1.0.0", "1.1.1")} + ${notBeSecSegCompatWith("1.0.0", "2.0.0")} + ${notBeSecSegCompatWith("1.0.0", "1.0.0-M1")} + + 1.0.0.0 should + ${beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq())} + ${breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0))} + + 0.12.0 should + ${beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq())} + ${breakDownTo("0.12.0", Some(0), Some(12), Some(0))} + + ${notBeSemVerCompatWith("0.12.0", "0.12.0-RC1")} + ${notBeSemVerCompatWith("0.12.0", "0.12.1")} + ${notBeSemVerCompatWith("0.12.0", "0.12.1-M1")} + + ${notBeSecSegCompatWith("0.12.0", "0.12.0-RC1")} + ${beSecSegCompatWith("0.12.0", "0.12.1")} + ${beSecSegCompatWith("0.12.0", "0.12.1-M1")} + + 0.1.0-SNAPSHOT should + ${beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())} + + ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} + ${notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0")} + ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001")} + + ${beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} + ${notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0")} + ${beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001")} + + 0.1.0-M1 should + ${beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq())} + + 0.1.0-RC1 should + ${beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq())} + + 0.1.0-MSERVER-1 should + ${beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())} + + 2.10.4-20140115-000117-b3a-sources should + ${beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())} + + ${beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} + + ${notBeSecSegCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} + + 20140115000117-b3a-sources should + ${beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq())} + + 1.0.0-alpha+001+002 should + ${beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))} + + non.space.!?string should + ${beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string"))} + + space !?string should + ${beParsedAsError("space !?string")} + + blank string should + ${beParsedAsError("")} + """ + + def beParsedAs(s: String, ns: Seq[Long], ts: Seq[String], es: Seq[String]) = + s match { + case VersionNumber(ns1, ts1, es1) if (ns1 == ns && ts1 == ts && es1 == es) => + (VersionNumber(ns, ts, es).toString must_== s) and + (VersionNumber(ns, ts, es) == VersionNumber(ns, ts, es)) + case VersionNumber(ns1, ts1, es1) => + sys.error(s"$ns1, $ts1, $es1") + } + def breakDownTo(s: String, major: Option[Long], minor: Option[Long] = None, + patch: Option[Long] = None, buildNumber: Option[Long] = None) = + s match { + case VersionNumber(ns, ts, es) => + val v = VersionNumber(ns, ts, es) + (v._1 must_== major) and + (v._2 must_== minor) and + (v._3 must_== patch) and + (v._4 must_== buildNumber) + } + def beParsedAsError(s: String) = + s match { + case VersionNumber(ns1, ts1, es1) => failure + case _ => success + } + def beSemVerCompatWith(v1: String, v2: String) = + VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true + def notBeSemVerCompatWith(v1: String, v2: String) = + VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false + def beSecSegCompatWith(v1: String, v2: String) = + VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true + def notBeSecSegCompatWith(v1: String, v2: String) = + VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false +} From 2b8fa35b8da57f1ff9d3439c37881a7e07d06964 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 27 Jul 2014 12:26:12 -0400 Subject: [PATCH 0301/1030] Implements eviction warning stories. #1200 This implements all stories from https://github.com/sbt/sbt/wiki/User-Stories%3A-Conflict-Warning. When scalaVersion is no longer effective an eviction warning will display. Scala version was updated by one of library dependencies: * org.scala-lang:scala-library:2.10.2 -> 2.10.3 When there're suspected incompatibility in directly depended Java libraries, eviction warnings will display. There may be incompatibilities among your library dependencies. Here are some of the libraries that were evicted: * commons-io:commons-io:1.4 -> 2.4 When there's suspected incompatiblity in directly depended Scala libraries, eviction warnings will display. There may be incompatibilities among your library dependencies. Here are some of the libraries that were evicted: * com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 This also adds 'evicted' task, which displays more detailed eviction warnings. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 188 +++++++++++++-- ivy/src/test/scala/BaseIvySpecification.scala | 51 ++++ ivy/src/test/scala/EvictionWarningSpec.scala | 224 ++++++++++++++++++ 3 files changed, 447 insertions(+), 16 deletions(-) create mode 100644 ivy/src/test/scala/BaseIvySpecification.scala create mode 100644 ivy/src/test/scala/EvictionWarningSpec.scala diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 4d3baec98..bacebdee3 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -1,25 +1,120 @@ package sbt import collection.mutable +import Configurations.Compile -final class EvictionWarningOptions( - val configurations: Seq[String], - val level: Level.Value) { +final class EvictionWarningOptions private[sbt] ( + val configurations: Seq[Configuration], + val warnScalaVersionEviction: Boolean, + val warnDirectEvictions: Boolean, + val warnTransitiveEvictions: Boolean, + val showCallers: Boolean, + val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { + private[sbt] def configStrings = configurations map { _.name } + + def withConfigurations(configurations: Seq[Configuration]): EvictionWarningOptions = + copy(configurations = configurations) + def withWarnScalaVersionEviction(warnScalaVersionEviction: Boolean): EvictionWarningOptions = + copy(warnScalaVersionEviction = warnScalaVersionEviction) + def withWarnDirectEvictions(warnDirectEvictions: Boolean): EvictionWarningOptions = + copy(warnDirectEvictions = warnDirectEvictions) + def withWarnTransitiveEvictions(warnTransitiveEvictions: Boolean): EvictionWarningOptions = + copy(warnTransitiveEvictions = warnTransitiveEvictions) + def withShowCallers(showCallers: Boolean): EvictionWarningOptions = + copy(showCallers = showCallers) + def withGuessCompatible(guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]): EvictionWarningOptions = + copy(guessCompatible = guessCompatible) + + private[sbt] def copy(configurations: Seq[Configuration] = configurations, + warnScalaVersionEviction: Boolean = warnScalaVersionEviction, + warnDirectEvictions: Boolean = warnDirectEvictions, + warnTransitiveEvictions: Boolean = warnTransitiveEvictions, + showCallers: Boolean = showCallers, + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible): EvictionWarningOptions = + new EvictionWarningOptions(configurations = configurations, + warnScalaVersionEviction = warnScalaVersionEviction, + warnDirectEvictions = warnDirectEvictions, + warnTransitiveEvictions = warnTransitiveEvictions, + showCallers = showCallers, + guessCompatible = guessCompatible) } + object EvictionWarningOptions { - def apply(): EvictionWarningOptions = - new EvictionWarningOptions(Vector("compile"), Level.Warn) + def default: EvictionWarningOptions = + new EvictionWarningOptions(Vector(Compile), true, true, false, false, defaultGuess) + def full: EvictionWarningOptions = + new EvictionWarningOptions(Vector(Compile), true, true, true, true, defaultGuess) + + lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = + guessSecondSegment orElse guessSemVer orElse guessFalse + lazy val guessSecondSegment: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + case (m1, Some(m2), Some(ivyScala)) if m2.name.endsWith("_" + ivyScala.scalaFullVersion) || m2.name.endsWith("_" + ivyScala.scalaBinaryVersion) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.SecondSegment.isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + lazy val guessSemVer: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + case (m1, Some(m2), _) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.SemVer.isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + lazy val guessFalse: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + case (_, _, _) => false + } +} + +final class EvictionPair private[sbt] ( + val organization: String, + val name: String, + val winner: Option[ModuleReport], + val evicteds: Seq[ModuleReport], + val includesDirect: Boolean, + val showCallers: Boolean) { + override def toString: String = + EvictionPair.evictionPairLines.showLines(this).mkString +} + +object EvictionPair { + implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { a: EvictionPair => + val revs = a.evicteds map { _.module.revision } + val revsStr = if (revs.size <= 1) revs.mkString else "(" + revs.mkString(", ") + ")" + val winnerRev = (a.winner map { r => + val callers: String = + if (a.showCallers) + r.callers match { + case Seq() => "" + case cs => (cs map { _.caller.toString }).mkString(" (caller: ", ", ", ")") + } + else "" + r.module.revision + callers + }).headOption map { " -> " + _ } getOrElse "" + Seq(s"\t* ${a.organization}:${a.name}:${revsStr}$winnerRev") + } +} + +final class EvictionWarning private[sbt] ( + val options: EvictionWarningOptions, + val scalaEvictions: Seq[EvictionPair], + val directEvictions: Seq[EvictionPair], + val transitiveEvictions: Seq[EvictionPair], + val allEvictions: Seq[EvictionPair]) { + def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions } object EvictionWarning { - def apply(options: EvictionWarningOptions, report: UpdateReport, log: Logger): Unit = { + def apply(module: IvySbt#Module, options: EvictionWarningOptions, report: UpdateReport, log: Logger): EvictionWarning = { val evictions = buildEvictions(options, report) - processEvictions(evictions, log) + processEvictions(module, options, evictions) } private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[ModuleDetailReport] = { val buffer: mutable.ListBuffer[ModuleDetailReport] = mutable.ListBuffer() - val confs = report.configurations filter { x => options.configurations contains x.configuration } + val confs = report.configurations filter { x => options.configStrings contains x.configuration } confs flatMap { confReport => confReport.details map { detail => if ((detail.modules exists { _.evicted }) && @@ -31,14 +126,75 @@ object EvictionWarning { buffer.toList.toVector } - private[sbt] def processEvictions(evictions: Seq[ModuleDetailReport], log: Logger): Unit = { - if (!evictions.isEmpty) { - log.warn("Some dependencies were evicted:") - evictions foreach { detail => - val revs = detail.modules filter { _.evicted } map { _.module.revision } - val winner = (detail.modules filterNot { _.evicted } map { _.module.revision }).headOption map { " -> " + _ } getOrElse "" - log.warn(s"\t* ${detail.organization}:${detail.name} (${revs.mkString(", ")})$winner") - } + private[sbt] def isScalaArtifact(module: IvySbt#Module, organization: String, name: String): Boolean = + module.moduleSettings.ivyScala match { + case Some(s) => + organization == s.scalaOrganization && + (name == "scala-library") || (name == "scala-compiler") + case _ => false } + + private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[ModuleDetailReport]): EvictionWarning = { + val directDependencies = module.moduleSettings match { + case x: InlineConfiguration => x.dependencies + case _ => Seq() + } + val pairs = reports map { detail => + val evicteds = detail.modules filter { _.evicted } + val winner = (detail.modules filterNot { _.evicted }).headOption + val includesDirect: Boolean = + options.warnDirectEvictions && + (directDependencies exists { dep => + (detail.organization == dep.organization) && (detail.name == dep.name) + }) + new EvictionPair(detail.organization, detail.name, winner, evicteds, includesDirect, options.showCallers) + } + val scalaEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() + val directEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() + val transitiveEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() + def guessCompatible(p: EvictionPair): Boolean = + p.evicteds forall { r => + options.guessCompatible(r.module, p.winner map { _.module }, module.moduleSettings.ivyScala) + } + pairs foreach { + case p if isScalaArtifact(module, p.organization, p.name) => + (module.moduleSettings.ivyScala, p.winner) match { + case (Some(s), Some(winner)) if ((s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction) => + scalaEvictions += p + case _ => + } + case p if p.includesDirect => + if (!guessCompatible(p) && options.warnDirectEvictions) { + directEvictions += p + } + case p => + if (!guessCompatible(p) && options.warnTransitiveEvictions) { + transitiveEvictions += p + } + } + new EvictionWarning(options, scalaEvictions.toList, + directEvictions.toList, transitiveEvictions.toList, pairs) + } + + implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => + import ShowLines._ + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + if (!a.scalaEvictions.isEmpty) { + out += "Scala version was updated by one of library dependencies:" + out ++= (a.scalaEvictions flatMap { _.lines }) + } + + if (!a.directEvictions.isEmpty || !a.transitiveEvictions.isEmpty) { + out += "There may be incompatibilities among your library dependencies." + out += "Here are some of the libraries that were evicted:" + out ++= (a.directEvictions flatMap { _.lines }) + out ++= (a.transitiveEvictions flatMap { _.lines }) + } + + if (!a.allEvictions.isEmpty && !a.reportedEvictions.isEmpty && !a.options.showCallers) { + out += "Run 'evicted' to see detailed eviction warnings" + } + + out.toList } } diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala new file mode 100644 index 000000000..e754903fe --- /dev/null +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -0,0 +1,51 @@ +package sbt + +import Path._, Configurations._ +import java.io.File +import org.specs2._ +import cross.CrossVersionUtil + +trait BaseIvySpecification extends Specification { + def currentBase: File = new File(".") + def currentTarget: File = currentBase / "target" / "ivyhome" + def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) + lazy val ivySbt = new IvySbt(mkIvyConfiguration) + lazy val log = Logger.Null + def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String]): IvySbt#Module = { + val ivyScala = scalaFullVersion map { fv => + new IvyScala( + scalaFullVersion = fv, + scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), + configurations = Nil, + checkExplicit = true, + filterImplicit = false, + overrideScalaVersion = false) + } + + val moduleSetting: ModuleSettings = InlineConfiguration( + module = moduleId, + moduleInfo = ModuleInfo("foo"), + dependencies = deps, + configurations = Seq(Compile, Test, Runtime), + ivyScala = ivyScala) + new ivySbt.Module(moduleSetting) + } + + def mkIvyConfiguration: IvyConfiguration = { + val paths = new IvyPaths(currentBase, Some(currentTarget)) + val rs = Seq(DefaultMavenRepository) + val other = Nil + val moduleConfs = Seq(ModuleConfiguration("*", DefaultMavenRepository)) + val off = false + val check = Nil + val resCacheDir = currentTarget / "resolution-cache" + val uo = UpdateOptions() + new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) + } + + def ivyUpdate(module: IvySbt#Module) = { + // IO.delete(currentTarget) + val config = new UpdateConfiguration(None, false, UpdateLogging.Full) + IvyActions.update(module, config, log) + } +} diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/EvictionWarningSpec.scala new file mode 100644 index 000000000..171d60bd5 --- /dev/null +++ b/ivy/src/test/scala/EvictionWarningSpec.scala @@ -0,0 +1,224 @@ +package sbt + +import org.specs2._ + +class EvictionWarningSpec extends BaseIvySpecification { + def is = s2""" + + This is a specification to check the eviction warnings + + Eviction of scala-library whose scalaVersion should + be detected $scalaVersionWarn1 + not be detected if it's diabled $scalaVersionWarn2 + print out message about the eviction $scalaVersionWarn3 + print out message about the eviction with callers $scalaVersionWarn4 + + Including two (suspect) binary incompatible Java libraries to + direct dependencies should + be detected as eviction $javaLibWarn1 + not be detected if it's disabled $javaLibWarn2 + print out message about the eviction $javaLibWarn3 + print out message about the eviction with callers $javaLibWarn4 + + Including two (suspect) binary compatible Java libraries to + direct dependencies should + not be detected as eviction $javaLibNoWarn1 + print out message about the eviction $javaLibNoWarn2 + + Including two (suspect) transitively binary incompatible Java libraries to + direct dependencies should + be not detected as eviction $javaLibTransitiveWarn1 + be detected if it's enabled $javaLibTransitiveWarn2 + print out message about the eviction if it's enabled $javaLibTransitiveWarn3 + + Including two (suspect) binary incompatible Scala libraries to + direct dependencies should + be detected as eviction $scalaLibWarn1 + print out message about the eviction $scalaLibWarn2 + + Including two (suspect) binary compatible Scala libraries to + direct dependencies should + not be detected as eviction $scalaLibNoWarn1 + print out message about the eviction $scalaLibNoWarn2 + + Including two (suspect) transitively binary incompatible Scala libraries to + direct dependencies should + be not detected as eviction $scalaLibTransitiveWarn1 + be detected if it's enabled $scalaLibTransitiveWarn2 + print out message about the eviction if it's enabled $scalaLibTransitiveWarn3 + """ + + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary + def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary + def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4", Some("compile")) cross CrossVersion.binary + def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2", Some("compile")) + def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3", Some("compile")) + def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4", Some("compile")) + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) + def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4", Some("compile")) + def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4", Some("compile")) + def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0", Some("compile")) // uses commons-io 2.4 + def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0", Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + + def defaultOptions = EvictionWarningOptions.default + + import ShowLines._ + + def scalaVersionDeps = Seq(scala2102, akkaActor230) + + def scalaVersionWarn1 = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).scalaEvictions must have size (1) + } + + def scalaVersionWarn2 = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions must have size (0) + } + + def scalaVersionWarn3 = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).lines must_== + List("Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", + "Run 'evicted' to see detailed eviction warnings") + } + + def scalaVersionWarn4 = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines must_== + List("Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)") + } + + def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) + + def javaLibWarn1 = { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (1) + } + + def javaLibWarn2 = { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions must have size (0) + } + + def javaLibWarn3 = { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).lines must_== + List("There may be incompatibilities among your library dependencies.", + "Here are some of the libraries that were evicted:", + "\t* commons-io:commons-io:1.4 -> 2.4", + "Run 'evicted' to see detailed eviction warnings") + } + + def javaLibWarn4 = { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines must_== + List("There may be incompatibilities among your library dependencies.", + "Here are some of the libraries that were evicted:", + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)") + } + + def javaLibNoWarn1 = { + val deps = Seq(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + } + + def javaLibNoWarn2 = { + val deps = Seq(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).lines must_== Nil + } + + def javaLibTransitiveDeps = Seq(unfilteredUploads080, bnfparser10) + + def javaLibTransitiveWarn1 = { + val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + } + + def javaLibTransitiveWarn2 = { + val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions must have size (1) + } + + def javaLibTransitiveWarn3 = { + val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines must_== + List("There may be incompatibilities among your library dependencies.", + "Here are some of the libraries that were evicted:", + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)") + } + + def scalaLibWarn1 = { + val deps = Seq(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (1) + } + + def scalaLibWarn2 = { + val deps = Seq(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).lines must_== + List("There may be incompatibilities among your library dependencies.", + "Here are some of the libraries that were evicted:", + "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4", + "Run 'evicted' to see detailed eviction warnings") + } + + def scalaLibNoWarn1 = { + val deps = Seq(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + } + + def scalaLibNoWarn2 = { + val deps = Seq(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).lines must_== Nil + } + + def scalaLibTransitiveDeps = Seq(scala2104, bananaSesame04, akkaRemote234) + + def scalaLibTransitiveWarn1 = { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + } + + def scalaLibTransitiveWarn2 = { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions must have size (1) + } + + def scalaLibTransitiveWarn3 = { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines must_== + List("There may be incompatibilities among your library dependencies.", + "Here are some of the libraries that were evicted:", + "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)") + } +} From f4cae232bb6016a5945433988be69c1673c4ba51 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 28 Jul 2014 13:25:54 -0400 Subject: [PATCH 0302/1030] Improve doc on ModuleDetailReport per @jsuereth --- ivy/src/main/scala/sbt/UpdateReport.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 41ea4fd80..f26f3fc10 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -47,6 +47,7 @@ final class ConfigurationReport( val configuration: String, val modules: Seq[ModuleReport], val details: Seq[ModuleDetailReport], + @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = this(configuration, modules, Nil, evicted) @@ -67,9 +68,15 @@ final class ConfigurationReport( } /** + * ModuleDetailReport represents an organization+name entry in Ivy resolution report. * In sbt's terminology, "module" consists of organization, name, and version. * In Ivy's, "module" means just organization and name, and the one including version numbers * are called revisions. + * + * A sequence of ModuleDetailReport called details is newly added to ConfigurationReport, replacing evicted. + * (Note old evicted was just a seq of ModuleIDs). + * ModuleDetailReport groups the ModuleReport of both winners and evicted reports by their organization and name, + * which can be used to calculate detailed evction warning etc. */ final class ModuleDetailReport( val organization: String, From 5bcff4c5c9180b62419d5915b6149ee35e86942b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 29 Jul 2014 22:03:02 -0400 Subject: [PATCH 0303/1030] scalariform formatting --- ivy/src/main/scala/sbt/UpdateReport.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index f26f3fc10..2adc13931 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -47,8 +47,7 @@ final class ConfigurationReport( val configuration: String, val modules: Seq[ModuleReport], val details: Seq[ModuleDetailReport], - @deprecated("Use details instead to get better eviction info.", "0.13.6") - val evicted: Seq[ModuleID]) { + @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = this(configuration, modules, Nil, evicted) From 78def4d4e34efd2f7cf335f84a6e2eebc3c30c59 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 1 Aug 2014 17:23:51 -0400 Subject: [PATCH 0304/1030] Fixes NullPointerException during update. Fixes #1484 --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 33 ++++++++++++++++-------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index b3bf04563..b83b924a9 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -58,6 +58,13 @@ object IvyRetrieve { moduleIds map { moduleDetail } } + private[sbt] def nonEmptyString(s: String): Option[String] = + s match { + case null => None + case x if x.trim == "" => None + case x => Some(x.trim) + } + private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = { def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] = Map(ea.entrySet.toArray collect { @@ -71,25 +78,29 @@ object IvyRetrieve { } val revId = dep.getResolvedId val moduleId = toModuleID(revId) - val branch = Option(revId.getBranch) + val branch = nonEmptyString(revId.getBranch) val (status, publicationDate, resolver, artifactResolver) = dep.isLoaded match { case true => - (Option(dep.getDescriptor.getStatus), + (nonEmptyString(dep.getDescriptor.getStatus), Some(new ju.Date(dep.getPublication)), - Option(dep.getModuleRevision.getResolver.getName), - Option(dep.getModuleRevision.getArtifactResolver.getName)) + nonEmptyString(dep.getModuleRevision.getResolver.getName), + nonEmptyString(dep.getModuleRevision.getArtifactResolver.getName)) case _ => (None, None, None, None) } val (evicted, evictedData, evictedReason) = dep.isEvicted(confReport.getConfiguration) match { case true => - val ed = dep.getEvictedData(confReport.getConfiguration) - (true, - Some(Option(ed.getConflictManager) map { _.toString } getOrElse { "transitive" }), - Option(ed.getDetail)) + val edOpt = Option(dep.getEvictedData(confReport.getConfiguration)) + edOpt match { + case Some(ed) => + (true, + nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { "transitive" }), + nonEmptyString(ed.getDetail)) + case None => (true, None, None) + } case _ => (false, None, None) } val problem = dep.hasProblem match { - case true => Option(dep.getProblem.getMessage) + case true => nonEmptyString(dep.getProblem.getMessage) case _ => None } val mdOpt = for { @@ -98,7 +109,7 @@ object IvyRetrieve { } yield md val homepage = mdOpt match { case Some(md) => - Option(md.getHomePage) + nonEmptyString(md.getHomePage) case _ => None } val extraAttributes: Map[String, String] = toExtraAttributes(mdOpt match { @@ -110,7 +121,7 @@ object IvyRetrieve { val licenses: Seq[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toArray.toVector collect { case lic: IvyLicense => - (lic.getName, Option(lic.getUrl)) + (lic.getName, nonEmptyString(lic.getUrl)) } case _ => Nil } From 44241ce97ccc941d2aeaebadcb6224f44fd21e4c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 2 Aug 2014 06:15:28 -0400 Subject: [PATCH 0305/1030] Unresolved dependency warning includes source position. Fixes #528 Unresolved dependency warning is moved to UnresolvedDependencyWarning class including the fail path that was added in #1467. To display the source position, I need to access the State, so I had to move the error processing out of IvyActions and add UnresolvedDependencyWarning, which is aware of State. --- ivy/src/main/scala/sbt/IvyActions.scala | 39 ++++++++++--------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 4960c9a2d..646293b0e 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -130,43 +130,36 @@ object IvyActions { * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ + @deprecated("Use updateEither instead.", "0.13.6") def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = + updateEither(module, configuration, log) match { + case Right(r) => r + case Left(e) => throw e + } + + /** + * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. + * 'updateConfig' configures the actual resolution and retrieval process. + */ + def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): Either[ResolveException, UpdateReport] = module.withModule(log) { case (ivy, md, default) => val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { case Some(x) if !configuration.missingOk => processUnresolved(x, log) - throw x + Left(x) case _ => val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) configuration.retrieve match { - case Some(rConf) => retrieve(ivy, uReport, rConf) - case None => uReport + case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case None => Right(uReport) } } } - - def processUnresolved(err: ResolveException, log: Logger) { - val withExtra = err.failed.filter(!_.extraDependencyAttributes.isEmpty) - if (!withExtra.isEmpty) { - log.warn("\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes.") - withExtra foreach { id => log.warn("\t\t" + id) } - log.warn("") - } - err.failed foreach { x => - val failedPaths = err.failedPaths(x) - if (!failedPaths.isEmpty) { - log.warn("\n\tNote: Unresolved dependencies path:") - val reverseFailedPaths = (failedPaths.toList map { _.toString }).reverse - log.warn("\t\t" + reverseFailedPaths.head) - reverseFailedPaths.tail foreach { id => - log.warn("\t\t +- " + id) - } - } - } - } + @deprecated("No longer used.", "0.13.6") + def processUnresolved(err: ResolveException, log: Logger): Unit = () def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = report.configurations.flatMap { confReport => val evicted = confReport.evicted.filter(moduleFilter) From 4be04bf894f2ebac68322b4ed1c3a530ee0f1961 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 3 Aug 2014 02:26:50 -0400 Subject: [PATCH 0306/1030] Adds UnresolvedWarningConfiguration that caches ModuleID -> SourcePosition mapping. UnresolvedWarning is moved back to IvyActions.scala where it belongs. The mapping between ModuleID and SourcePosition is passed in as UnresolvedWarningConfiguration. This is calculated once in Defaults using State and is cached to filesystem. --- ivy/src/main/scala/sbt/IvyActions.scala | 76 +++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 646293b0e..988809fb0 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -5,6 +5,7 @@ package sbt import java.io.File import scala.xml.{ Node => XNode, NodeSeq } +import collection.mutable import org.apache.ivy.Ivy import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } @@ -29,6 +30,14 @@ final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, config final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) +final class UnresolvedWarningConfiguration private[sbt] ( + val modulePositions: Seq[(ModuleID, SourcePosition)]) +object UnresolvedWarningConfiguration { + def apply(): UnresolvedWarningConfiguration = apply(Seq()) + def apply(modulePositions: Seq[(ModuleID, SourcePosition)]): UnresolvedWarningConfiguration = + new UnresolvedWarningConfiguration(modulePositions) +} + /** * Configures logging during an 'update'. `level` determines the amount of other information logged. * `Full` is the default and logs the most. @@ -132,23 +141,24 @@ object IvyActions { */ @deprecated("Use updateEither instead.", "0.13.6") def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = - updateEither(module, configuration, log) match { + updateEither(module, configuration, UnresolvedWarningConfiguration(), log) match { case Right(r) => r - case Left(e) => throw e + case Left(w) => + throw w.resolveException } /** * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): Either[ResolveException, UpdateReport] = + def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, log: Logger): Either[UnresolvedWarning, UpdateReport] = module.withModule(log) { case (ivy, md, default) => val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { case Some(x) if !configuration.missingOk => - processUnresolved(x, log) - Left(x) + Left(UnresolvedWarning(x, uwconfig)) case _ => val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) @@ -296,3 +306,59 @@ final class ResolveException( def this(messages: Seq[String], failed: Seq[ModuleID]) = this(messages, failed, Map(failed map { m => m -> Nil }: _*)) } +/** + * Represents unresolved dependency warning, which displays reconstructed dependency tree + * along with source position of each node. + */ +final class UnresolvedWarning private[sbt] ( + val resolveException: ResolveException, + val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]]) +object UnresolvedWarning { + private[sbt] def apply(err: ResolveException, config: UnresolvedWarningConfiguration): UnresolvedWarning = { + def modulePosition(m0: ModuleID): Option[SourcePosition] = + config.modulePositions.find { + case (m, p) => + (m.organization == m0.organization) && + (m0.name startsWith m.name) && + (m.revision == m0.revision) + } map { + case (m, p) => p + } + val failedPaths = err.failed map { x: ModuleID => + err.failedPaths(x).toList.reverse map { id => + (id, modulePosition(id)) + } + } + apply(err, failedPaths) + } + private[sbt] def apply(err: ResolveException, failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]]): UnresolvedWarning = + new UnresolvedWarning(err, failedPaths) + private[sbt] def sourcePosStr(posOpt: Option[SourcePosition]): String = + posOpt match { + case Some(LinePosition(path, start)) => s" ($path#L$start)" + case Some(RangePosition(path, LineRange(start, end))) => s" ($path#L$start-$end)" + case _ => "" + } + implicit val unresolvedWarningLines: ShowLines[UnresolvedWarning] = ShowLines { a => + val withExtra = a.resolveException.failed.filter(!_.extraDependencyAttributes.isEmpty) + val buffer = mutable.ListBuffer[String]() + if (!withExtra.isEmpty) { + buffer += "\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes." + withExtra foreach { id => buffer += "\t\t" + id } + } + if (!a.failedPaths.isEmpty) { + buffer += "\n\tNote: Unresolved dependencies path:" + a.failedPaths foreach { path => + if (!path.isEmpty) { + val head = path.head + buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) + path.tail foreach { + case (m, pos) => + buffer += "\t\t +- " + m.toString + sourcePosStr(pos) + } + } + } + } + buffer.toList + } +} From 89049a58dea3dd4baa48fb166c3784290c0f5aa7 Mon Sep 17 00:00:00 2001 From: Evgeny Goldin Date: Wed, 6 Aug 2014 01:43:19 +0200 Subject: [PATCH 0307/1030] JCenter and BintrayMavenRepository resolvers added --- ivy/src/main/scala/sbt/Resolver.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index b9b715d0c..c70ded17b 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -20,6 +20,10 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver { override def toString = name + ": " + root } +sealed class JCenter(isSecure: Boolean = false) extends MavenRepository("jcenter", s"http${if (isSecure) "s" else ""}://jcenter.bintray.com/") + +sealed class BintrayMavenRepository(subject: String, repo: String, isSecure: Boolean = false) extends MavenRepository(s"bintray$subject/$repo/", s"http${if (isSecure) "s" else ""}://dl.bintray.com/$subject/$repo/") + final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) @@ -135,6 +139,7 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern import Resolver._ +object JCenter extends JCenter(false) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JavaNet1Repository extends JavaNet1Repository From 8ecc9edbea1cf855b75393451d00b8ed29edea90 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 7 Aug 2014 15:43:13 -0400 Subject: [PATCH 0308/1030] Moves JCenter and Bintray repo into object Resolver. #1405 This is more consistent with other hardcoded repos like Sonatype. Also hardcoding everything to https. --- ivy/src/main/scala/sbt/Resolver.scala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index c70ded17b..b9201a55d 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -20,10 +20,6 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver { override def toString = name + ": " + root } -sealed class JCenter(isSecure: Boolean = false) extends MavenRepository("jcenter", s"http${if (isSecure) "s" else ""}://jcenter.bintray.com/") - -sealed class BintrayMavenRepository(subject: String, repo: String, isSecure: Boolean = false) extends MavenRepository(s"bintray$subject/$repo/", s"http${if (isSecure) "s" else ""}://dl.bintray.com/$subject/$repo/") - final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) @@ -139,9 +135,9 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern import Resolver._ -object JCenter extends JCenter(false) object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) +object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) object JavaNet1Repository extends JavaNet1Repository sealed trait JavaNet1Repository extends Resolver { def name = "java.net Maven1 Repository" @@ -151,6 +147,10 @@ object Resolver { val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + val JavaNet2RepositoryName = "java.net Maven2 Repository" + val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" + val JCenterRepositoryName = "jcenter" + val JCenterRepositoryRoot = "https://jcenter.bintray.com/" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" @@ -160,13 +160,12 @@ object Resolver { private[sbt] val ScalaToolsReleases = new MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) private[sbt] val ScalaToolsSnapshots = new MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) - val JavaNet2RepositoryName = "java.net Maven2 Repository" - val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" - def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + def bintrayRepo(owner: String, repo: String) = new MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") + def jcenterRepo = JCenterRepository /** Add the local and Maven Central repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = From 302362fad4053fca4d6832996a768d4de046a18b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 8 Aug 2014 00:53:09 -0400 Subject: [PATCH 0309/1030] Adds `dependencyPositions` task to explicitly track dependency positions. --- ivy/src/main/scala/sbt/IvyActions.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 988809fb0..4d69ae2c7 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,10 +31,10 @@ final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclu final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) final class UnresolvedWarningConfiguration private[sbt] ( - val modulePositions: Seq[(ModuleID, SourcePosition)]) + val modulePositions: Map[ModuleID, SourcePosition]) object UnresolvedWarningConfiguration { - def apply(): UnresolvedWarningConfiguration = apply(Seq()) - def apply(modulePositions: Seq[(ModuleID, SourcePosition)]): UnresolvedWarningConfiguration = + def apply(): UnresolvedWarningConfiguration = apply(Map()) + def apply(modulePositions: Map[ModuleID, SourcePosition]): UnresolvedWarningConfiguration = new UnresolvedWarningConfiguration(modulePositions) } From 16eb7b28fd1e751a8cbd86e7794fb2f9a70f3cea Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Sun, 3 Aug 2014 09:11:56 +0100 Subject: [PATCH 0310/1030] Use HTTPS for downloading artifacts from Maven Central Sonatype have enabled HTTPS access for Maven Central: http://central.sonatype.org/articles/2014/Aug/03/https-support-launching-now/ Note that the Ivy class IBiblioResolver contains the old http url (ie DEFAULT_M2_ROOT="http://repo1.maven.org/maven2/"): http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/plugins/resolver/IBiblioResolver.java?revision=1557968&view=markup#l72 --- ivy/src/main/scala/sbt/Resolver.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index b9201a55d..b82738598 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import java.net.URL import scala.xml.NodeSeq -import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } +import org.apache.ivy.plugins.resolver.DependencyResolver sealed trait Resolver { def name: String @@ -135,7 +135,7 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern import Resolver._ -object DefaultMavenRepository extends MavenRepository("public", IBiblioResolver.DEFAULT_M2_ROOT) +object DefaultMavenRepository extends MavenRepository("public", DefaultMavenRepositoryRoot) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) object JavaNet1Repository extends JavaNet1Repository @@ -151,6 +151,7 @@ object Resolver { val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" val JCenterRepositoryName = "jcenter" val JCenterRepositoryRoot = "https://jcenter.bintray.com/" + val DefaultMavenRepositoryRoot = "https://repo1.maven.org/maven2/" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" From 9e245b3fc3253ef6b7d80c43e278fd59e137a825 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 7 Aug 2014 13:57:04 -0400 Subject: [PATCH 0311/1030] Adds sbt.repository.secure (default: true) #1494 --- ivy/src/main/scala/sbt/Resolver.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index b82738598..52fbf0fb8 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -135,7 +135,7 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern import Resolver._ -object DefaultMavenRepository extends MavenRepository("public", DefaultMavenRepositoryRoot) +object DefaultMavenRepository extends MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) object JavaNet1Repository extends JavaNet1Repository @@ -144,6 +144,8 @@ sealed trait JavaNet1Repository extends Resolver { } object Resolver { + private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true + val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" @@ -152,6 +154,7 @@ object Resolver { val JCenterRepositoryName = "jcenter" val JCenterRepositoryRoot = "https://jcenter.bintray.com/" val DefaultMavenRepositoryRoot = "https://repo1.maven.org/maven2/" + private[sbt] def centralRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo1.maven.org/maven2/" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" From 1185e5b5dd0de531f819b3675def247f88c8dca1 Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Fri, 8 Aug 2014 10:33:36 +0100 Subject: [PATCH 0312/1030] Fix pom-export of Maven Central repository Commit a1e26ca6 broke the `make-pom` & `pom-advanced` dependency-management tests by replacing one reference to `IBiblioResolver.DEFAULT_M2_ROOT` in `Resolver`, but not the other reference in `MakePom`: https://travis-ci.org/sbt/sbt/jobs/31939788#L2517-L2519 ...the secure url was no longer recognised as the default Maven Repository root, so was erroneously exported. --- ivy/src/main/scala/sbt/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index be3baba63..ee238371c 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -307,7 +307,7 @@ class MakePom(val log: Logger) { val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { - case m: IBiblioResolver if m.isM2compatible && m.getRoot != IBiblioResolver.DEFAULT_M2_ROOT => + case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => MavenRepository(m.getName, m.getRoot) :: Nil case _ => Nil } From 8e682691c2bc820640fd14ceea14b33779a2351b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Aug 2014 18:56:58 -0400 Subject: [PATCH 0313/1030] Fixes #1514, #321. Fixes -SNAPSHOT issue by re-implemeting ChainResolver. Adds `lastestSnapshots` flag to `updateOptions`, which controls the behavior of the chained resolver. Up until 0.13.6, sbt was picking the first `-SNAPSHOT` revision it found along the chain. When is enabled (default: ), it will look into all resolvers on the chain, and compare them using the publish date. The tradeoff is probably a longer resolution time if you have many remote repositories on the build or you live away from the severs. So here's how to disable it: updateOptions := updateOptions.value.withLatestSnapshots(false) Ivy by default uses latest-revision as the latest strategy. This strategy I don't think takes in account for the possibility that a changing revision may exist in multiple repositories/resolvers with having identical version number like 0.1.0-SNAPSHOT. The implementation is a bit hacky, but I think it attacks the core of this problem. --- ivy/src/main/scala/sbt/Ivy.scala | 213 ++++++++++++++++++++- ivy/src/main/scala/sbt/UpdateOptions.scala | 13 +- 2 files changed, 213 insertions(+), 13 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 78c8e3b99..1d6f6269e 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -8,12 +8,13 @@ import ivyint.{ ConsolidatedResolveEngine, ConsolidatedResolveCache } import java.io.File import java.net.URI +import java.text.ParseException import java.util.concurrent.Callable -import java.util.{ Collection, Collections => CS } +import java.util.{ Collection, Collections => CS, Date } import CS.singleton import org.apache.ivy.Ivy -import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } +import org.apache.ivy.core.{ IvyPatternHelper, LogOptions, IvyContext } import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } @@ -23,11 +24,15 @@ import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision, ResolveEngine } import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.sort.SortEngine -import org.apache.ivy.plugins.latest.LatestRevisionStrategy +import org.apache.ivy.plugins.latest.{ LatestStrategy, LatestRevisionStrategy, ArtifactInfo } import org.apache.ivy.plugins.matcher.PatternMatcher import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorParser -import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver } -import org.apache.ivy.util.{ Message, MessageLogger } +import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, BasicResolver } +import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } +import org.apache.ivy.plugins.version.ExactVersionMatcher +import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => IFileRepository } +import org.apache.ivy.plugins.repository.url.URLResource +import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{ NodeSeq, Text } @@ -73,9 +78,16 @@ final class IvySbt(val configuration: IvyConfiguration) { is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) - IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.log) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.updateOptions, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) } + // is.addVersionMatcher(new ExactVersionMatcher { + // override def isDynamic(askedMrid: ModuleRevisionId): Boolean = { + // askedMrid.getRevision endsWith "-SNAPSHOT" + // } + // override def accept(askedMrid: ModuleRevisionId, foundMrid: ModuleRevisionId): Boolean = + // askedMrid.getRevision == foundMrid.getRevision + // }) is } private lazy val ivy: Ivy = @@ -253,10 +265,10 @@ private object IvySbt { * Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, log: Logger) { + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, updateOptions: UpdateOptions, log: Logger) { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") - val chain = resolverChain(name, rs, localOnly, settings, log) + val chain = resolverChain(name, rs, localOnly, settings, updateOptions, log) settings.addResolver(chain) chain } @@ -264,7 +276,11 @@ private object IvySbt { val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } + private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean = + mrid.getRevision endsWith "-SNAPSHOT" def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = + resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) + def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = { val newDefault = new ChainResolver { // Technically, this should be applied to module configurations. @@ -285,8 +301,185 @@ private object IvySbt { { if (data.getOptions.getLog != LogOptions.LOG_QUIET) Message.info("Resolving " + dd.getDependencyRevisionId + " ...") - val gd = super.getDependency(dd, data) - resetArtifactResolver(gd) + val gd = doGetDependency(dd, data) + val mod = resetArtifactResolver(gd) + mod + } + // Modified implementation of ChainResolver#getDependency. + // When the dependency is changing, it will check all resolvers on the chain + // regardless of what the "latest strategy" is set, and look for the published date + // or the module descriptor to sort them. + // This implementation also skips resolution if "return first" is set to true, + // and if a previously resolved or cached revision has been found. + def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = + { + val useLatest = (dd.isChanging || (isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots + if (useLatest) { + Message.verbose(s"${getName} is changing. Checking all resolvers on the chain") + } + val data = new ResolveData(data0, doValidate(data0)) + val resolved = Option(data.getCurrentResolvedModuleRevision) + val resolvedOrCached = + resolved orElse { + Message.verbose(getName + ": Checking cache for: " + dd) + Option(findModuleInCache(dd, data, true)) map { mr => + Message.verbose(getName + ": module revision found in cache: " + mr.getId) + forcedRevision(mr) + } + } + var temp: Option[ResolvedModuleRevision] = + if (useLatest) None + else resolvedOrCached + val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + val results = resolvers map { x => + // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers + if (isReturnFirst && temp.isDefined && !useLatest) Right(None) + else { + val resolver = x + val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) + try { + val previouslyResolved = temp + // if the module qualifies as changing, then resolve all resolvers + if (useLatest) data.setCurrentResolvedModuleRevision(None.orNull) + else data.setCurrentResolvedModuleRevision(temp.orNull) + temp = Option(resolver.getDependency(dd, data)) + val retval = Right( + if (temp eq previouslyResolved) None + else if (useLatest) temp map { x => + (reparseModuleDescriptor(dd, data, resolver, x), resolver) + } + else temp map { x => (forcedRevision(x), resolver) } + ) + retval + } catch { + case ex: Exception => + Message.verbose("problem occurred while resolving " + dd + " with " + resolver + + ": " + IvyStringUtils.getStackTrace(ex)) + Left(ex) + } finally { + oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) } + checkInterrupted + } + } + } + val errors = results collect { case Left(e) => e } + val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } + val sorted = + if (useLatest) (foundRevisions.sortBy { + case (rmr, _) => + rmr.getDescriptor.getPublicationDate.getTime + }).reverse.headOption map { + case (rmr, resolver) => + // Now that we know the real latest revision, let's force Ivy to use it + val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) + artifactOpt match { + case None => throw new RuntimeException("\t" + resolver.getName + + ": no ivy file nor artifact found for " + rmr) + case Some(artifactRef) => + val systemMd = toSystem(rmr.getDescriptor) + getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, + toSystem(dd), systemMd.getAllArtifacts().head, None.orNull, getCacheOptions(data)) + } + rmr + } + else foundRevisions.reverse.headOption map { _._1 } + val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached + mrOpt match { + case None if errors.size == 1 => + errors.head match { + case e: RuntimeException => throw e + case e: ParseException => throw e + case e: Throwable => throw new RuntimeException(e.toString, e) + } + case None if errors.size > 1 => + val err = (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") + throw new RuntimeException(s"several problems occurred while resolving $dd:$err") + case _ => + if (resolved == mrOpt) resolved.orNull + else (mrOpt map { resolvedRevision }).orNull + } + } + // Ivy seem to not want to use the module descriptor found at the latest resolver + private[this] def reparseModuleDescriptor(dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, rmr: ResolvedModuleRevision): ResolvedModuleRevision = + Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile => + ivyFile.getResource match { + case r: FileResource => + try { + val parser = rmr.getDescriptor.getParser + val md = parser.parseDescriptor(settings, r.getFile.toURL, r, false) + Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true)) + } catch { + case _: ParseException => None + } + case _ => None + } + } getOrElse rmr + /** Ported from BasicResolver#findFirstAirfactRef. */ + private[this] def findFirstArtifactRef(md: ModuleDescriptor, dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver): Option[ResolvedResource] = + { + def artifactRef(artifact: IArtifact, date: Date): Option[ResolvedResource] = + resolver match { + case resolver: BasicResolver => + IvyContext.getContext.set(resolver.getName + ".artifact", artifact) + try { + Option(resolver.doFindArtifactRef(artifact, date)) orElse { + Option(artifact.getUrl) map { url => + Message.verbose("\tusing url for " + artifact + ": " + url) + val resource = + if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath())) + else new URLResource(url) + new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) + } + } + } finally { + IvyContext.getContext.set(resolver.getName + ".artifact", null) + } + case _ => + None + } + val artifactRefs = md.getConfigurations.toVector flatMap { conf => + md.getArtifacts(conf.getName).toVector flatMap { af => + artifactRef(af, data.getDate).toVector + } + } + artifactRefs.headOption + } + /** Ported from ChainResolver#forcedRevision. */ + private[this] def forcedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = + new ResolvedModuleRevision(rmr.getResolver, rmr.getArtifactResolver, rmr.getDescriptor, rmr.getReport, true) + /** Ported from ChainResolver#resolvedRevision. */ + private[this] def resolvedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = + if (isDual) new ResolvedModuleRevision(rmr.getResolver, this, rmr.getDescriptor, rmr.getReport, rmr.isForce) + else rmr + /** Ported from ChainResolver#setLatestIfRequired. */ + private[this] def setLatestIfRequired(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + latestStrategyName(resolver) match { + case Some(latestName) if latestName != "default" => + val oldLatest = latestStrategy(resolver) + doSetLatestStrategy(resolver, latest) + oldLatest + case _ => None + } + /** Ported from ChainResolver#getLatestStrategyName. */ + private[this] def latestStrategyName(resolver: DependencyResolver): Option[String] = + resolver match { + case r: HasLatestStrategy => Some(r.getLatest) + case _ => None + } + /** Ported from ChainResolver#getLatest. */ + private[this] def latestStrategy(resolver: DependencyResolver): Option[LatestStrategy] = + resolver match { + case r: HasLatestStrategy => Some(r.getLatestStrategy) + case _ => None + } + /** Ported from ChainResolver#setLatest. */ + private[this] def doSetLatestStrategy(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + resolver match { + case r: HasLatestStrategy => + val oldLatest = latestStrategy(resolver) + r.setLatestStrategy(latest.orNull) + oldLatest + case _ => None } } newDefault.setName(name) diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index acea391f7..dd4c83f47 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -9,19 +9,26 @@ import java.io.File * * See also UpdateConfiguration in IvyActions.scala. */ -final class UpdateOptions( +final class UpdateOptions private[sbt] ( + /** If set to true, check all resolvers for snapshots. */ + val latestSnapshots: Boolean, /** If set to true, use consolidated resolution. */ val consolidatedResolution: Boolean) { + def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = + copy(latestSnapshots = latestSnapshots) def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = copy(consolidatedResolution = consolidatedResolution) private[sbt] def copy( + latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution): UpdateOptions = - new UpdateOptions(consolidatedResolution) + new UpdateOptions(latestSnapshots, consolidatedResolution) } object UpdateOptions { def apply(): UpdateOptions = - new UpdateOptions(false) + new UpdateOptions( + latestSnapshots = true, + consolidatedResolution = false) } From 333eb706b08b2e2ee2b597532cdfb5d4d43a066b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 11 Aug 2014 12:45:14 -0400 Subject: [PATCH 0314/1030] Special treatment for a special resolver: inter-project --- ivy/src/main/scala/sbt/Ivy.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 1d6f6269e..b146366bf 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -373,6 +373,7 @@ private object IvySbt { // Now that we know the real latest revision, let's force Ivy to use it val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { + case None if resolver.getName == "inter-project" => // do nothing case None => throw new RuntimeException("\t" + resolver.getName + ": no ivy file nor artifact found for " + rmr) case Some(artifactRef) => From ad2ac6198fb8f7add2277f4e73de7320401b6cb4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 11 Aug 2014 22:49:48 -0400 Subject: [PATCH 0315/1030] Using iterators --- ivy/src/main/scala/sbt/Ivy.scala | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index b146366bf..b8908200f 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -81,13 +81,6 @@ final class IvySbt(val configuration: IvyConfiguration) { IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.updateOptions, configuration.log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) } - // is.addVersionMatcher(new ExactVersionMatcher { - // override def isDynamic(askedMrid: ModuleRevisionId): Boolean = { - // askedMrid.getRevision endsWith "-SNAPSHOT" - // } - // override def accept(askedMrid: ModuleRevisionId, foundMrid: ModuleRevisionId): Boolean = - // askedMrid.getRevision == foundMrid.getRevision - // }) is } private lazy val ivy: Ivy = @@ -438,12 +431,13 @@ private object IvySbt { case _ => None } - val artifactRefs = md.getConfigurations.toVector flatMap { conf => - md.getArtifacts(conf.getName).toVector flatMap { af => - artifactRef(af, data.getDate).toVector + val artifactRefs = md.getConfigurations.toIterator flatMap { conf => + md.getArtifacts(conf.getName).toIterator flatMap { af => + artifactRef(af, data.getDate).toIterator } } - artifactRefs.headOption + if (artifactRefs.hasNext) Some(artifactRefs.next) + else None } /** Ported from ChainResolver#forcedRevision. */ private[this] def forcedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = From 1e3f31df16f4b5a284b068359442c5860708fd98 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 15 Aug 2014 01:57:21 -0400 Subject: [PATCH 0316/1030] ModuleDetailReport => OrganizationArtifactReport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ModuleDetailReport hasn’t been released yet, so this rename is safe. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 6 +++--- ivy/src/main/scala/sbt/IvyRetrieve.scala | 10 +++++----- ivy/src/main/scala/sbt/UpdateReport.scala | 14 +++++++++----- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index bacebdee3..da121e0fa 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -112,8 +112,8 @@ object EvictionWarning { processEvictions(module, options, evictions) } - private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[ModuleDetailReport] = { - val buffer: mutable.ListBuffer[ModuleDetailReport] = mutable.ListBuffer() + private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[OrganizationArtifactReport] = { + val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() val confs = report.configurations filter { x => options.configStrings contains x.configuration } confs flatMap { confReport => confReport.details map { detail => @@ -134,7 +134,7 @@ object EvictionWarning { case _ => false } - private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[ModuleDetailReport]): EvictionWarning = { + private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { val directDependencies = module.moduleSettings match { case x: InlineConfiguration => x.dependencies case _ => Seq() diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index b83b924a9..ed252e43b 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -48,14 +48,14 @@ object IvyRetrieve { // We need this because current module report used as part of UpdateReport/ConfigurationReport contains // only the revolved modules. // Sometimes the entire module can be excluded via rules etc. - private[sbt] def details(confReport: ConfigurationResolveReport): Seq[ModuleDetailReport] = { + private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Seq[OrganizationArtifactReport] = { val dependencies = confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId } - def moduleDetail(mid: IvyModuleId): ModuleDetailReport = { + def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } - new ModuleDetailReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) }) + OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) }) } - moduleIds map { moduleDetail } + moduleIds map { organizationArtifact } } private[sbt] def nonEmptyString(s: String): Option[String] = @@ -150,7 +150,7 @@ object IvyRetrieve { def updateStats(report: ResolveReport): UpdateStats = new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), details(confReport), evicted(confReport)) + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport), evicted(confReport)) /** * Tries to find Ivy graph path the from node to target. diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 2adc13931..d32bbe9a9 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -46,7 +46,7 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con final class ConfigurationReport( val configuration: String, val modules: Seq[ModuleReport], - val details: Seq[ModuleDetailReport], + val details: Seq[OrganizationArtifactReport], @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = this(configuration, modules, Nil, evicted) @@ -67,17 +67,17 @@ final class ConfigurationReport( } /** - * ModuleDetailReport represents an organization+name entry in Ivy resolution report. + * OrganizationArtifactReport represents an organization+name entry in Ivy resolution report. * In sbt's terminology, "module" consists of organization, name, and version. * In Ivy's, "module" means just organization and name, and the one including version numbers * are called revisions. * - * A sequence of ModuleDetailReport called details is newly added to ConfigurationReport, replacing evicted. + * A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted. * (Note old evicted was just a seq of ModuleIDs). - * ModuleDetailReport groups the ModuleReport of both winners and evicted reports by their organization and name, + * OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name, * which can be used to calculate detailed evction warning etc. */ -final class ModuleDetailReport( +final class OrganizationArtifactReport private[sbt] ( val organization: String, val name: String, val modules: Seq[ModuleReport]) { @@ -86,6 +86,10 @@ final class ModuleDetailReport( s"\t$organization:$name\n${details.mkString}\n" } } +object OrganizationArtifactReport { + def apply(organization: String, name: String, modules: Seq[ModuleReport]): OrganizationArtifactReport = + new OrganizationArtifactReport(organization, name, modules) +} /** * Provides information about the resolution of a module. From 74c6c18a4c520bb07c4f41720bb4df75bccc7378 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 15 Aug 2014 02:57:17 -0400 Subject: [PATCH 0317/1030] Fixes #1484. Fixes another variant of update NPE Ivy gives an array that contains null for caller configurations. sbinary barfs when it sees null. Curiously two of the sbt plugins that hit this bug happens to be from Typesafe: addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.2") addSbtPlugin("com.typesafe.sbt" % "sbt-native-packager" % "0.7.3") --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 9 ++++++--- ivy/src/main/scala/sbt/UpdateReport.scala | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index ed252e43b..5f07963bd 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -68,11 +68,14 @@ object IvyRetrieve { private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = { def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] = Map(ea.entrySet.toArray collect { - case entry: ju.Map.Entry[_, _] => (entry.getKey.toString, entry.getValue.toString) + case entry: ju.Map.Entry[_, _] if nonEmptyString(entry.getKey.toString).isDefined && nonEmptyString(entry.getValue.toString).isDefined => + (entry.getKey.toString, entry.getValue.toString) }: _*) def toCaller(caller: IvyCaller): Caller = { val m = toModuleID(caller.getModuleRevisionId) - val callerConfigurations = caller.getCallerConfigurations.toArray.toVector + val callerConfigurations = caller.getCallerConfigurations.toArray.toVector collect { + case x if nonEmptyString(x).isDefined => x + } val extraAttributes = toExtraAttributes(caller.getDependencyDescriptor.getExtraAttributes) new Caller(m, callerConfigurations, extraAttributes) } @@ -120,7 +123,7 @@ object IvyRetrieve { val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList val licenses: Seq[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toArray.toVector collect { - case lic: IvyLicense => + case lic: IvyLicense if Option(lic.getName).isDefined => (lic.getName, nonEmptyString(lic.getUrl)) } case _ => Nil diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index d32bbe9a9..7e04d5135 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -123,7 +123,7 @@ final class ModuleReport( s"\t\t$module: " + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" } - private[sbt] def detailReport: String = + def detailReport: String = s"\t\t- ${module.revision}\n" + (if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) + reportStr("status", status) + From 697a28771e7c327fd0aa6c6a4cb3340037b0ab9e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 16 Aug 2014 22:38:35 -0400 Subject: [PATCH 0318/1030] Fixes #1275. Fixes pom dynamic revision conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ivy and pom uses slightly different notation for version range and dynamic revision. This change fixes the dynamic revisions involving “+”. First, when a revision like “1.1+” is found, it will now be treated as “1.+”. Next, when it finds a revision like “1+” is found, it will be treated as “+”. The conversion of “+” is hardcoded to be “[0,)”. --- ivy/src/main/scala/sbt/MakePom.scala | 31 ++++++++------ ivy/src/test/scala/MakePomSpec.scala | 60 ++++++++++++++++++++++++++++ ivy/src/test/scala/MakePomTest.scala | 28 ------------- 3 files changed, 78 insertions(+), 41 deletions(-) create mode 100644 ivy/src/test/scala/MakePomSpec.scala delete mode 100644 ivy/src/test/scala/MakePomTest.scala diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index ee238371c..b49711b19 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -196,6 +196,7 @@ class MakePom(val log: Logger) { } + /** Converts Ivy revision ranges to that of Maven POM */ def makeDependencyVersion(revision: String): String = { def plusRange(s: String, shift: Int = 0) = { def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 @@ -209,20 +210,24 @@ class MakePom(val log: Logger) { } val startSym = Set(']', '[', '(') val stopSym = Set(']', '[', ')') + val PlusPattern = """(.+)(\.\d*\+)""".r try { - if (revision endsWith ".+") { - plusRange(revision.substring(0, revision.length - 2)) - } else if (revision endsWith "+") { - val base = revision.take(revision.length - 1) - // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so - // we assume version ranges never go beyond 5 siginificant digits. - (0 to 5).map(plusRange(base, _)).mkString(",") - } else if (startSym(revision(0)) && stopSym(revision(revision.length - 1))) { - val start = revision(0) - val stop = revision(revision.length - 1) - val mid = revision.substring(1, revision.length - 1) - (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) - } else revision + revision match { + case PlusPattern(base, tail) => plusRange(base) + // There's no direct translation for a dynamic revision like "1+". + // This is likely the build user misunderstanding the meaning of "+", + // which means pick the latest in the version segment. + // So if someone wanted (1.0 <= x), then it should be "[1.0)" or "1.+". + // Technically speaking, "1+" should convert to "LATEST", + // but that seems to be deprecated now, so picking the minimum version "0". + case rev if rev endsWith "+" => "[0,)" + case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => + val start = rev(0) + val stop = rev(rev.length - 1) + val mid = rev.substring(1, rev.length - 1) + (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + case _ => revision + } } catch { case e: NumberFormatException => // TODO - if the version doesn't meet our expectations, maybe we just issue a hard diff --git a/ivy/src/test/scala/MakePomSpec.scala b/ivy/src/test/scala/MakePomSpec.scala new file mode 100644 index 000000000..55fba326f --- /dev/null +++ b/ivy/src/test/scala/MakePomSpec.scala @@ -0,0 +1,60 @@ +package sbt + +import java.io.File +import org.specs2._ + +// http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html +// http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html +class MakePomSpec extends Specification { + def is = s2""" + + This is a specification to check the Ivy revision number conversion to pom. + + 1.0 should + ${convertTo("1.0", "1.0")} + + [1.0,2.0] should + ${convertTo("[1.0,2.0]", "[1.0,2.0]")} + + [1.0,2.0[ should + ${convertTo("[1.0,2.0[", "[1.0,2.0)")} + + ]1.0,2.0] should + ${convertTo("]1.0,2.0]", "(1.0,2.0]")} + + ]1.0,2.0[ should + ${convertTo("]1.0,2.0[", "(1.0,2.0)")} + + [1.0,) should + ${convertTo("[1.0,)", "[1.0,)")} + + ]1.0,) should + ${convertTo("]1.0,)", "(1.0,)")} + + (,2.0] should + ${convertTo("(,2.0]", "(,2.0]")} + + (,2.0[ should + ${convertTo("(,2.0[", "(,2.0)")} + + 1.+ should + ${convertTo("1.+", "[1,2)")} + + 1.2.3.4.+ should + ${convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)")} + + 12.31.42.+ should + ${convertTo("12.31.42.+", "[12.31.42,12.31.43)")} + + 1.1+ should + ${convertTo("1.1+", "[1,2)")} + + 1+ should + ${convertTo("1+", "[0,)")} + """ + + val mp = new MakePom(ConsoleLogger()) + def convertTo(s: String, expected: String) = + mp.makeDependencyVersion(s) must_== expected +} + diff --git a/ivy/src/test/scala/MakePomTest.scala b/ivy/src/test/scala/MakePomTest.scala deleted file mode 100644 index c96d2102e..000000000 --- a/ivy/src/test/scala/MakePomTest.scala +++ /dev/null @@ -1,28 +0,0 @@ -package sbt - -import java.io.File -import org.specs2._ -import mutable.Specification - -object MakePomTest extends Specification { - val mp = new MakePom(ConsoleLogger()) - import mp.{ makeDependencyVersion => v } - "MakePom makeDependencyVersion" should { - "Handle .+ in versions" in { - v("1.+") must_== "[1,2)" - v("1.2.3.4.+") must_== "[1.2.3.4,1.2.3.5)" - v("12.31.42.+") must_== "[12.31.42,12.31.43)" - } - /* TODO - do we care about this case? - * 1+ --> [1,2),[10,20),[100,200),[1000,2000),[10000,20000),[100000,200000) - */ - "Handle ]* bracket in version ranges" in { - v("]1,3]") must_== "(1,3]" - v("]1.1,1.3]") must_== "(1.1,1.3]" - } - "Handle *[ bracket in version ranges" in { - v("[1,3[") must_== "[1,3)" - v("[1.1,1.3[") must_== "[1.1,1.3)" - } - } -} From cc02bcef87e0cbe1680bdf003bd7a3b1483f5580 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 17 Aug 2014 23:18:32 -0400 Subject: [PATCH 0319/1030] Fixes #1439. Fixes metabuild downloading unused Scala 2.10.2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Scala instance is added to the Ivy graph via autoLibraryDependency. For metabuilds, scala-library is scoped under “provided” configuration, which does not seem to evict modules on “compiled” configuration. This commit turns overrideScalaVersion flag to true for the metabuilds, so override rules are added for the following modules: - scala-library - scala-compiler - scala-reflect --- ivy/src/main/scala/sbt/IvyScala.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index e2468a81a..b4299906f 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -16,6 +16,7 @@ object ScalaArtifacts { val Organization = ScalaOrganization val LibraryID = ScalaLibraryID val CompilerID = ScalaCompilerID + val ReflectID = "scala-reflect" def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( @@ -47,6 +48,7 @@ private object IvyScala { def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) { overrideVersion(module, Organization, LibraryID, version) overrideVersion(module, Organization, CompilerID, version) + overrideVersion(module, Organization, ReflectID, version) } def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String) { val id = new ModuleId(org, name) From 676e95eaeec6ca952b94a32734064bcf9f1c63f8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 18 Aug 2014 00:54:19 -0400 Subject: [PATCH 0320/1030] Fixes #1201. Display instruction to overrideScalaVersion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit scala-library is currently treated as just one of the library modules. This means that it’s at the mercy of eviction if some other library uses newer version of scala-library. This commit displays a instruction on how to force scalaVersion if warnScalaVersionEviction flag is true on EvictionWarningOptions. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 5 ++++- ivy/src/test/scala/EvictionWarningSpec.scala | 6 +++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index da121e0fa..c40860081 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -2,6 +2,7 @@ package sbt import collection.mutable import Configurations.Compile +import ScalaArtifacts.{ LibraryID, CompilerID } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], @@ -130,7 +131,7 @@ object EvictionWarning { module.moduleSettings.ivyScala match { case Some(s) => organization == s.scalaOrganization && - (name == "scala-library") || (name == "scala-compiler") + (name == LibraryID) || (name == CompilerID) case _ => false } @@ -182,6 +183,8 @@ object EvictionWarning { if (!a.scalaEvictions.isEmpty) { out += "Scala version was updated by one of library dependencies:" out ++= (a.scalaEvictions flatMap { _.lines }) + out += "To force scalaVersion, add the following:" + out += "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" } if (!a.directEvictions.isEmpty || !a.transitiveEvictions.isEmpty) { diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/EvictionWarningSpec.scala index 171d60bd5..0e1e3dd2c 100644 --- a/ivy/src/test/scala/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/EvictionWarningSpec.scala @@ -86,6 +86,8 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions, report, log).lines must_== List("Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", + "To force scalaVersion, add the following:", + "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", "Run 'evicted' to see detailed eviction warnings") } @@ -94,7 +96,9 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines must_== List("Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)") + "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", + "To force scalaVersion, add the following:", + "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }") } def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) From 92214f739ac617ea471ceffac51c431d480c19d2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Aug 2014 03:54:32 -0400 Subject: [PATCH 0321/1030] Based on Ivy's behavior, bringing back approximation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I assumed 1.1+ should be treated as 1.+, but it seems like Ivy treats it more as “any version that starts with 1.1” including 1.10. Josh’s original implementation approximates this by making ranges for multiple digits, 1.1~1.2, 1.10~1.20, etc. --- ivy/src/main/scala/sbt/MakePom.scala | 20 +++++++++++--------- ivy/src/test/scala/MakePomSpec.scala | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index b49711b19..e05221b43 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -210,17 +210,19 @@ class MakePom(val log: Logger) { } val startSym = Set(']', '[', '(') val stopSym = Set(']', '[', ')') - val PlusPattern = """(.+)(\.\d*\+)""".r + val DotPlusPattern = """(.+)\.\+""".r + val DotNumPlusPattern = """(.+)\.(\d+)\+""".r + val NumPlusPattern = """(\d+)\+""".r + val maxDigit = 5 try { revision match { - case PlusPattern(base, tail) => plusRange(base) - // There's no direct translation for a dynamic revision like "1+". - // This is likely the build user misunderstanding the meaning of "+", - // which means pick the latest in the version segment. - // So if someone wanted (1.0 <= x), then it should be "[1.0)" or "1.+". - // Technically speaking, "1+" should convert to "LATEST", - // but that seems to be deprecated now, so picking the minimum version "0". - case rev if rev endsWith "+" => "[0,)" + case "+" => "[0,)" + case DotPlusPattern(base) => plusRange(base) + // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so + // we assume version ranges never go beyond 5 siginificant digits. + case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") + case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") + case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => val start = rev(0) val stop = rev(rev.length - 1) diff --git a/ivy/src/test/scala/MakePomSpec.scala b/ivy/src/test/scala/MakePomSpec.scala index 55fba326f..3310ed62b 100644 --- a/ivy/src/test/scala/MakePomSpec.scala +++ b/ivy/src/test/scala/MakePomSpec.scala @@ -47,14 +47,27 @@ class MakePomSpec extends Specification { ${convertTo("12.31.42.+", "[12.31.42,12.31.43)")} 1.1+ should - ${convertTo("1.1+", "[1,2)")} + ${convertTo("1.1+", "[1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)")} 1+ should - ${convertTo("1+", "[0,)")} + ${convertTo("1+", "[1,2),[10,20),[100,200),[1000,2000),[10000,20000)")} + + + should + ${convertTo("+", "[0,)")} + + foo+ should + ${beParsedAsError("foo+")} """ val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String) = mp.makeDependencyVersion(s) must_== expected + def beParsedAsError(s: String) = + try { + mp.makeDependencyVersion(s) + failure + } catch { + case e: Throwable => success + } } From 1566058227f3967d97f1c69d5c4f21bcf70138de Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Aug 2014 20:00:10 -0400 Subject: [PATCH 0322/1030] Deprecate JavaNet1Repository. #1541 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I don’t think there’s an alternative for java.net Maven 1 repository. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 2 ++ ivy/src/main/scala/sbt/Resolver.scala | 2 ++ 2 files changed, 4 insertions(+) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index a36d7430c..8097ae5b9 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -112,6 +112,8 @@ private object ConvertResolver { resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns resolver } + // TODO: HTTP repository is no longer recommended. #1541 + // Remove `JavaNet1Repository` when we bump up the API. case r: JavaNet1Repository => { // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 52fbf0fb8..9c98fc0fa 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -138,7 +138,9 @@ import Resolver._ object DefaultMavenRepository extends MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) +@deprecated("HTTP repository is no longer recommended.", "0.13.6") object JavaNet1Repository extends JavaNet1Repository +@deprecated("HTTP repository is no longer recommended.", "0.13.6") sealed trait JavaNet1Repository extends Resolver { def name = "java.net Maven1 Repository" } From d86e6ccd2608866f1163c7b845d9ba2d2055e41a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Aug 2014 20:13:51 -0400 Subject: [PATCH 0323/1030] Fixes #1549. Use HTTPS for Java.net Maven 2 repository --- ivy/src/main/scala/sbt/Resolver.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 9c98fc0fa..b0971950c 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -152,11 +152,16 @@ object Resolver { val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" val JavaNet2RepositoryName = "java.net Maven2 Repository" - val JavaNet2RepositoryRoot = "http://download.java.net/maven/2" + val JavaNet2RepositoryRoot = javanet2RepositoryRoot(useSecureResolvers) val JCenterRepositoryName = "jcenter" val JCenterRepositoryRoot = "https://jcenter.bintray.com/" val DefaultMavenRepositoryRoot = "https://repo1.maven.org/maven2/" + // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def centralRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo1.maven.org/maven2/" + // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. + private[sbt] def javanet2RepositoryRoot(secure: Boolean) = + if (secure) "https://maven.java.net/content/repositories/public/" + else "http://download.java.net/maven/2" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" From 090e3a64680aed8c8a5dd47589b5f7be244cf0e6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Aug 2014 20:27:23 -0400 Subject: [PATCH 0324/1030] #1541. Use HTTPS for Typesafe repository --- ivy/src/main/scala/sbt/Resolver.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index b0971950c..4ff1f10f0 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -148,7 +148,7 @@ sealed trait JavaNet1Repository extends Resolver { object Resolver { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true - val TypesafeRepositoryRoot = "http://repo.typesafe.com/typesafe" + val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" val JavaNet2RepositoryName = "java.net Maven2 Repository" @@ -162,6 +162,8 @@ object Resolver { private[sbt] def javanet2RepositoryRoot(secure: Boolean) = if (secure) "https://maven.java.net/content/repositories/public/" else "http://download.java.net/maven/2" + // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. + private[sbt] def typesafeRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" From 97110b6c9d8f4268036f55abef56e17446608f6a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Aug 2014 20:36:28 -0400 Subject: [PATCH 0325/1030] #1541. Use HTTPS for sbt plugin repository --- ivy/src/main/scala/sbt/Resolver.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 4ff1f10f0..87257fc87 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -149,7 +149,7 @@ object Resolver { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) - val SbtPluginRepositoryRoot = "http://repo.scala-sbt.org/scalasbt" + val SbtPluginRepositoryRoot = sbtPluginRepositoryRoot(useSecureResolvers) val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = javanet2RepositoryRoot(useSecureResolvers) @@ -164,7 +164,9 @@ object Resolver { else "http://download.java.net/maven/2" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def typesafeRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" - + // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. + private[sbt] def sbtPluginRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" + // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" From 751305ab95b5d35ab1589ffda689aea65f074896 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 4 Sep 2014 01:15:58 +0200 Subject: [PATCH 0326/1030] Allow the "-bin" Scala version suffix to specify a bincompat version There is sometimes the need to use a test version of Scala that is intended to be binary compatible with a standard release version. At this time, due to the particular logic implemented within sbt, a non-numeric suffix will never have the same binaryScalaVersion of a release version ending in ".0", like for instance "2.11.0". This commit allows developers to use as suffix any string that begins with "-bin", for instance "2.11.0-bin-compat-test-1". Such a suffix will have a binaryScalaVersion of "2.11", being therefore considered binary compatible with release versions. --- util/cross/src/main/input_sources/CrossVersionUtil.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/util/cross/src/main/input_sources/CrossVersionUtil.scala index 24310b39c..6a63c9139 100644 --- a/util/cross/src/main/input_sources/CrossVersionUtil.scala +++ b/util/cross/src/main/input_sources/CrossVersionUtil.scala @@ -39,9 +39,11 @@ object CrossVersionUtil private[${{cross.package0}}] def scalaApiVersion(v: String): Option[(Int, Int)] = { val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val BinCompatV = """(\d+)\.(\d+)\.(\d+)-bin(-.*)?""".r val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r v match { case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) case _ => None } From cd9205cffeccb4e22f3adde45b27175e4c398090 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 5 Sep 2014 09:21:22 -0400 Subject: [PATCH 0327/1030] Split out inter-project resolver into its own Chain. Fixes #1565 * Create two chains if we have inter-project resolver - One which ensures inter-project deps are always taken - One which will look in all "other" repositories for dependencies and will use the "most up-to-date" -SNAPSHOT strategy. * No additional tests, as this would simple break every multi-project test if it were wrong. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 2 +- ivy/src/main/scala/sbt/Ivy.scala | 230 ++---------------- ivy/src/main/scala/sbt/Resolver.scala | 2 +- .../scala/sbt/ivyint/SbtChainResolver.scala | 230 ++++++++++++++++++ 4 files changed, 249 insertions(+), 215 deletions(-) create mode 100644 ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 8097ae5b9..70a0530e1 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -17,7 +17,7 @@ import java.io.File import org.apache.ivy.util.ChecksumHelper import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } -private object ConvertResolver { +private[sbt] object ConvertResolver { /** * This class contains all the reflective lookups used in the * checksum-friendly URL publishing shim. diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index b8908200f..55a596bbc 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -236,7 +236,7 @@ final class IvySbt(val configuration: IvyConfiguration) { } } -private object IvySbt { +private[sbt] object IvySbt { val DefaultIvyConfigFilename = "ivysettings.xml" val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" @@ -273,219 +273,23 @@ private object IvySbt { mrid.getRevision endsWith "-SNAPSHOT" def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) - def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = - { - val newDefault = new ChainResolver { - // Technically, this should be applied to module configurations. - // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). - // It would be better to get proper support into Ivy. - // A workaround is to configure the ModuleConfiguration resolver to be a ChainResolver. - // - // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. - // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" - // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly - // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive. - // - // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the - // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. - override def locate(artifact: IArtifact) = if (hasImplicitClassifier(artifact)) null else super.locate(artifact) + def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = { + def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, log)) + val (projectResolvers, rest) = resolvers.partition(_.name == "inter-project") + if (projectResolvers.isEmpty) new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) + else { + // Here we set up a "first repo wins" chain resolver + val delegate = new ivyint.SbtChainResolver(name + "-delegate", mapResolvers(rest), settings, updateOptions, log) + val prs = mapResolvers(projectResolvers) + // Here we construct a chain resolver which will FORCE looking at the project resolver first. + new ivyint.SbtChainResolver(name, + prs :+ delegate, + settings, + UpdateOptions().withLatestSnapshots(false), + log) - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = - { - if (data.getOptions.getLog != LogOptions.LOG_QUIET) - Message.info("Resolving " + dd.getDependencyRevisionId + " ...") - val gd = doGetDependency(dd, data) - val mod = resetArtifactResolver(gd) - mod - } - // Modified implementation of ChainResolver#getDependency. - // When the dependency is changing, it will check all resolvers on the chain - // regardless of what the "latest strategy" is set, and look for the published date - // or the module descriptor to sort them. - // This implementation also skips resolution if "return first" is set to true, - // and if a previously resolved or cached revision has been found. - def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = - { - val useLatest = (dd.isChanging || (isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots - if (useLatest) { - Message.verbose(s"${getName} is changing. Checking all resolvers on the chain") - } - val data = new ResolveData(data0, doValidate(data0)) - val resolved = Option(data.getCurrentResolvedModuleRevision) - val resolvedOrCached = - resolved orElse { - Message.verbose(getName + ": Checking cache for: " + dd) - Option(findModuleInCache(dd, data, true)) map { mr => - Message.verbose(getName + ": module revision found in cache: " + mr.getId) - forcedRevision(mr) - } - } - var temp: Option[ResolvedModuleRevision] = - if (useLatest) None - else resolvedOrCached - val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } - val results = resolvers map { x => - // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers - if (isReturnFirst && temp.isDefined && !useLatest) Right(None) - else { - val resolver = x - val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) - try { - val previouslyResolved = temp - // if the module qualifies as changing, then resolve all resolvers - if (useLatest) data.setCurrentResolvedModuleRevision(None.orNull) - else data.setCurrentResolvedModuleRevision(temp.orNull) - temp = Option(resolver.getDependency(dd, data)) - val retval = Right( - if (temp eq previouslyResolved) None - else if (useLatest) temp map { x => - (reparseModuleDescriptor(dd, data, resolver, x), resolver) - } - else temp map { x => (forcedRevision(x), resolver) } - ) - retval - } catch { - case ex: Exception => - Message.verbose("problem occurred while resolving " + dd + " with " + resolver - + ": " + IvyStringUtils.getStackTrace(ex)) - Left(ex) - } finally { - oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) } - checkInterrupted - } - } - } - val errors = results collect { case Left(e) => e } - val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } - val sorted = - if (useLatest) (foundRevisions.sortBy { - case (rmr, _) => - rmr.getDescriptor.getPublicationDate.getTime - }).reverse.headOption map { - case (rmr, resolver) => - // Now that we know the real latest revision, let's force Ivy to use it - val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) - artifactOpt match { - case None if resolver.getName == "inter-project" => // do nothing - case None => throw new RuntimeException("\t" + resolver.getName - + ": no ivy file nor artifact found for " + rmr) - case Some(artifactRef) => - val systemMd = toSystem(rmr.getDescriptor) - getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, - toSystem(dd), systemMd.getAllArtifacts().head, None.orNull, getCacheOptions(data)) - } - rmr - } - else foundRevisions.reverse.headOption map { _._1 } - val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached - mrOpt match { - case None if errors.size == 1 => - errors.head match { - case e: RuntimeException => throw e - case e: ParseException => throw e - case e: Throwable => throw new RuntimeException(e.toString, e) - } - case None if errors.size > 1 => - val err = (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") - throw new RuntimeException(s"several problems occurred while resolving $dd:$err") - case _ => - if (resolved == mrOpt) resolved.orNull - else (mrOpt map { resolvedRevision }).orNull - } - } - // Ivy seem to not want to use the module descriptor found at the latest resolver - private[this] def reparseModuleDescriptor(dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, rmr: ResolvedModuleRevision): ResolvedModuleRevision = - Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile => - ivyFile.getResource match { - case r: FileResource => - try { - val parser = rmr.getDescriptor.getParser - val md = parser.parseDescriptor(settings, r.getFile.toURL, r, false) - Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true)) - } catch { - case _: ParseException => None - } - case _ => None - } - } getOrElse rmr - /** Ported from BasicResolver#findFirstAirfactRef. */ - private[this] def findFirstArtifactRef(md: ModuleDescriptor, dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver): Option[ResolvedResource] = - { - def artifactRef(artifact: IArtifact, date: Date): Option[ResolvedResource] = - resolver match { - case resolver: BasicResolver => - IvyContext.getContext.set(resolver.getName + ".artifact", artifact) - try { - Option(resolver.doFindArtifactRef(artifact, date)) orElse { - Option(artifact.getUrl) map { url => - Message.verbose("\tusing url for " + artifact + ": " + url) - val resource = - if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath())) - else new URLResource(url) - new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) - } - } - } finally { - IvyContext.getContext.set(resolver.getName + ".artifact", null) - } - case _ => - None - } - val artifactRefs = md.getConfigurations.toIterator flatMap { conf => - md.getArtifacts(conf.getName).toIterator flatMap { af => - artifactRef(af, data.getDate).toIterator - } - } - if (artifactRefs.hasNext) Some(artifactRefs.next) - else None - } - /** Ported from ChainResolver#forcedRevision. */ - private[this] def forcedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = - new ResolvedModuleRevision(rmr.getResolver, rmr.getArtifactResolver, rmr.getDescriptor, rmr.getReport, true) - /** Ported from ChainResolver#resolvedRevision. */ - private[this] def resolvedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = - if (isDual) new ResolvedModuleRevision(rmr.getResolver, this, rmr.getDescriptor, rmr.getReport, rmr.isForce) - else rmr - /** Ported from ChainResolver#setLatestIfRequired. */ - private[this] def setLatestIfRequired(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = - latestStrategyName(resolver) match { - case Some(latestName) if latestName != "default" => - val oldLatest = latestStrategy(resolver) - doSetLatestStrategy(resolver, latest) - oldLatest - case _ => None - } - /** Ported from ChainResolver#getLatestStrategyName. */ - private[this] def latestStrategyName(resolver: DependencyResolver): Option[String] = - resolver match { - case r: HasLatestStrategy => Some(r.getLatest) - case _ => None - } - /** Ported from ChainResolver#getLatest. */ - private[this] def latestStrategy(resolver: DependencyResolver): Option[LatestStrategy] = - resolver match { - case r: HasLatestStrategy => Some(r.getLatestStrategy) - case _ => None - } - /** Ported from ChainResolver#setLatest. */ - private[this] def doSetLatestStrategy(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = - resolver match { - case r: HasLatestStrategy => - val oldLatest = latestStrategy(resolver) - r.setLatestStrategy(latest.orNull) - oldLatest - case _ => None - } - } - newDefault.setName(name) - newDefault.setReturnFirst(true) - newDefault.setCheckmodified(false) - for (sbtResolver <- resolvers) { - log.debug("\t" + sbtResolver) - newDefault.add(ConvertResolver(sbtResolver, settings, log)) - } - newDefault } + } def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger) { for (r <- resolvers) { log.debug("\t" + r) @@ -528,7 +332,7 @@ private object IvySbt { // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver // This also fixes #760, which occurs when metadata exists in a repository, but the artifact doesn't. - private[this] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = + private[sbt] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = if (resolved eq null) null else { diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 87257fc87..3678adadb 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -166,7 +166,7 @@ object Resolver { private[sbt] def typesafeRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def sbtPluginRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" - + // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala new file mode 100644 index 000000000..685431124 --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -0,0 +1,230 @@ +package sbt +package ivyint + +import java.io.File +import java.text.ParseException +import java.util.Date + +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.core.{ IvyContext, LogOptions } +import org.apache.ivy.core.module.descriptor.{ ModuleDescriptor, DependencyDescriptor, Artifact => IArtifact } +import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } +import org.apache.ivy.plugins.latest.LatestStrategy +import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } +import org.apache.ivy.plugins.repository.url.URLResource +import org.apache.ivy.plugins.resolver.{ ChainResolver, BasicResolver, DependencyResolver } +import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } +import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } + +class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], settings: IvySettings, updateOptions: UpdateOptions, log: Logger) extends ChainResolver { + // TODO - We need to special case the project resolver so it always "wins" when resolving with inter-project dependencies. + + // Initialize ourselves. + setName(name) + setReturnFirst(true) + setCheckmodified(false) + // Here we append all the resolvers we were passed *AND* look for + // a project resolver, which we will special-case. + resolvers.foreach(add) + + // Technically, this should be applied to module configurations. + // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). + // It would be better to get proper support into Ivy. + // A workaround is to configure the ModuleConfiguration resolver to be a ChainResolver. + // + // This method is only used by the pom parsing code in Ivy to find artifacts it doesn't know about. + // In particular, a) it looks up source and javadoc classifiers b) it looks up a main artifact for packaging="pom" + // sbt now provides the update-classifiers or requires explicitly specifying classifiers explicitly + // Providing a main artifact for packaging="pom" does not seem to be correct and the lookup can be expensive. + // + // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the + // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. + override def locate(artifact: IArtifact) = if (IvySbt.hasImplicitClassifier(artifact)) null else super.locate(artifact) + + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = + { + if (data.getOptions.getLog != LogOptions.LOG_QUIET) + Message.info("Resolving " + dd.getDependencyRevisionId + " ...") + val gd = doGetDependency(dd, data) + val mod = IvySbt.resetArtifactResolver(gd) + mod + } + // Modified implementation of ChainResolver#getDependency. + // When the dependency is changing, it will check all resolvers on the chain + // regardless of what the "latest strategy" is set, and look for the published date + // or the module descriptor to sort them. + // This implementation also skips resolution if "return first" is set to true, + // and if a previously resolved or cached revision has been found. + def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = + { + val useLatest = (dd.isChanging || (IvySbt.isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots + if (useLatest) { + Message.verbose(s"${getName} is changing. Checking all resolvers on the chain") + } + val data = new ResolveData(data0, doValidate(data0)) + val resolved = Option(data.getCurrentResolvedModuleRevision) + val resolvedOrCached = + resolved orElse { + Message.verbose(getName + ": Checking cache for: " + dd) + Option(findModuleInCache(dd, data, true)) map { mr => + Message.verbose(getName + ": module revision found in cache: " + mr.getId) + forcedRevision(mr) + } + } + var temp: Option[ResolvedModuleRevision] = + if (useLatest) None + else resolvedOrCached + val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + val results = resolvers map { x => + // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers + if (isReturnFirst && temp.isDefined && !useLatest) Right(None) + else { + val resolver = x + val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) + try { + val previouslyResolved = temp + // if the module qualifies as changing, then resolve all resolvers + if (useLatest) data.setCurrentResolvedModuleRevision(None.orNull) + else data.setCurrentResolvedModuleRevision(temp.orNull) + temp = Option(resolver.getDependency(dd, data)) + val retval = Right( + if (temp eq previouslyResolved) None + else if (useLatest) temp map { x => + (reparseModuleDescriptor(dd, data, resolver, x), resolver) + } + else temp map { x => (forcedRevision(x), resolver) } + ) + retval + } catch { + case ex: Exception => + Message.verbose("problem occurred while resolving " + dd + " with " + resolver + + ": " + IvyStringUtils.getStackTrace(ex)) + Left(ex) + } finally { + oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) } + checkInterrupted + } + } + } + val errors = results collect { case Left(e) => e } + val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } + val sorted = + if (useLatest) (foundRevisions.sortBy { + case (rmr, _) => + rmr.getDescriptor.getPublicationDate.getTime + }).reverse.headOption map { + case (rmr, resolver) => + // Now that we know the real latest revision, let's force Ivy to use it + val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) + artifactOpt match { + case None if resolver.getName == "inter-project" => // do nothing + case None => throw new RuntimeException("\t" + resolver.getName + + ": no ivy file nor artifact found for " + rmr) + case Some(artifactRef) => + val systemMd = toSystem(rmr.getDescriptor) + getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, + toSystem(dd), systemMd.getAllArtifacts().head, None.orNull, getCacheOptions(data)) + } + rmr + } + else foundRevisions.reverse.headOption map { _._1 } + val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached + mrOpt match { + case None if errors.size == 1 => + errors.head match { + case e: RuntimeException => throw e + case e: ParseException => throw e + case e: Throwable => throw new RuntimeException(e.toString, e) + } + case None if errors.size > 1 => + val err = (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") + throw new RuntimeException(s"several problems occurred while resolving $dd:$err") + case _ => + if (resolved == mrOpt) resolved.orNull + else (mrOpt map { resolvedRevision }).orNull + } + } + // Ivy seem to not want to use the module descriptor found at the latest resolver + private[this] def reparseModuleDescriptor(dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, rmr: ResolvedModuleRevision): ResolvedModuleRevision = + Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile => + ivyFile.getResource match { + case r: FileResource => + try { + val parser = rmr.getDescriptor.getParser + val md = parser.parseDescriptor(settings, r.getFile.toURL, r, false) + Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true)) + } catch { + case _: ParseException => None + } + case _ => None + } + } getOrElse rmr + /** Ported from BasicResolver#findFirstAirfactRef. */ + private[this] def findFirstArtifactRef(md: ModuleDescriptor, dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver): Option[ResolvedResource] = + { + def artifactRef(artifact: IArtifact, date: Date): Option[ResolvedResource] = + resolver match { + case resolver: BasicResolver => + IvyContext.getContext.set(resolver.getName + ".artifact", artifact) + try { + Option(resolver.doFindArtifactRef(artifact, date)) orElse { + Option(artifact.getUrl) map { url => + Message.verbose("\tusing url for " + artifact + ": " + url) + val resource = + if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath())) + else new URLResource(url) + new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) + } + } + } finally { + IvyContext.getContext.set(resolver.getName + ".artifact", null) + } + case _ => + None + } + val artifactRefs = md.getConfigurations.toIterator flatMap { conf => + md.getArtifacts(conf.getName).toIterator flatMap { af => + artifactRef(af, data.getDate).toIterator + } + } + if (artifactRefs.hasNext) Some(artifactRefs.next) + else None + } + /** Ported from ChainResolver#forcedRevision. */ + private[this] def forcedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = + new ResolvedModuleRevision(rmr.getResolver, rmr.getArtifactResolver, rmr.getDescriptor, rmr.getReport, true) + /** Ported from ChainResolver#resolvedRevision. */ + private[this] def resolvedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = + if (isDual) new ResolvedModuleRevision(rmr.getResolver, this, rmr.getDescriptor, rmr.getReport, rmr.isForce) + else rmr + /** Ported from ChainResolver#setLatestIfRequired. */ + private[this] def setLatestIfRequired(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + latestStrategyName(resolver) match { + case Some(latestName) if latestName != "default" => + val oldLatest = latestStrategy(resolver) + doSetLatestStrategy(resolver, latest) + oldLatest + case _ => None + } + /** Ported from ChainResolver#getLatestStrategyName. */ + private[this] def latestStrategyName(resolver: DependencyResolver): Option[String] = + resolver match { + case r: HasLatestStrategy => Some(r.getLatest) + case _ => None + } + /** Ported from ChainResolver#getLatest. */ + private[this] def latestStrategy(resolver: DependencyResolver): Option[LatestStrategy] = + resolver match { + case r: HasLatestStrategy => Some(r.getLatestStrategy) + case _ => None + } + /** Ported from ChainResolver#setLatest. */ + private[this] def doSetLatestStrategy(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + resolver match { + case r: HasLatestStrategy => + val oldLatest = latestStrategy(resolver) + r.setLatestStrategy(latest.orNull) + oldLatest + case _ => None + } +} \ No newline at end of file From e1130eabbc29cf448c14d1a60d728bfca8f1020a Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 9 Sep 2014 17:45:02 -0400 Subject: [PATCH 0328/1030] Fix Maven configuration mappings in Ivy. It turns out there was a very subtle, and evil, issue sitting the Ivy/maven configuration, and it related to dependency mapping. A mapping of `foo->bar(*)` means that the local configuration `foo` depends on the remote configuration `bar`, if it exists, or *ALL CONFIGURATIONS* if `bar` does not exist. Since the default Ivy configuration mapping was using the random `master` configuration, which AFAICT is NEVER specified, just an assumed default, this would cause leaks between maven + ivy projects. i.e. if a maven POM depends on a module denoted by an ivy.xml file, then you'd wind up accidentally bleeding ALL the ivy module's configurations into the maven module's configurations. This fix works around the issue, by assuming that if there is no `master` configuration, than the maven default of `compile` is intended. As sbt forces generated `ivy.xml` files to abide by maven conventions, this works in all of our test cases. The only scenario where it wouldn't work is those who have custom ivy.xml files *and* have pom.xml files which rely on those custom ivy.xml files, a very unlikely situation where the workaround is: "define a master configuration". Includes a test demonstrating the issue. --- .../ivy/plugins/parser/m2/EvilHackery.scala | 93 +++++++++++++++++++ ivy/src/main/scala/sbt/CustomPomParser.scala | 6 +- 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala new file mode 100644 index 000000000..f76637404 --- /dev/null +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala @@ -0,0 +1,93 @@ +package org.apache.ivy.plugins.parser.m2 + +import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; + +/** + * Helper evil hackery method to ensure Maven configurations + Ivy i + */ +object EvilHackery { + + val REPLACEMENT_MAVEN_MAPPINGS = { + // Here we copy paste from Ivy + val REPLACEMENT_MAPPINGS = new java.util.HashMap[String, PomModuleDescriptorBuilder.ConfMapper] + + REPLACEMENT_MAPPINGS.put("compile", new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + // NOTE - This is the problematic piece we're dropping. EVIL!!!! + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("compile", "compile(*)") + // NOTE - This is the problematic piece we're dropping, as `master` is not special cased. + dd.addDependencyConfiguration("compile", "master(compile)") + dd.addDependencyConfiguration("runtime", "runtime(*)") + } + } + }) + + REPLACEMENT_MAPPINGS.put("provided", new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + dd.addDependencyConfiguration("optional", "provided(*)") + dd.addDependencyConfiguration("optional", "runtime(*)") + // Remove evil hackery + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("provided", "compile(*)") + dd.addDependencyConfiguration("provided", "provided(*)") + dd.addDependencyConfiguration("provided", "runtime(*)") + // Remove evil hackery + dd.addDependencyConfiguration("provided", "master(compile)") + } + } + }) + + REPLACEMENT_MAPPINGS.put("runtime", new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + dd.addDependencyConfiguration("optional", "provided(*)") + // Remove evil hackery + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("runtime", "compile(*)") + dd.addDependencyConfiguration("runtime", "runtime(*)") + // Remove evil hackery + dd.addDependencyConfiguration("runtime", "master(compile)") + } + } + }) + + REPLACEMENT_MAPPINGS.put("test", new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + dd.addDependencyConfiguration("test", "runtime(*)") + // Remove evil hackery + dd.addDependencyConfiguration("test", "master(compile)") + } + }) + + REPLACEMENT_MAPPINGS.put("system", new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + // Hacked + dd.addDependencyConfiguration("system", "master(compile)") + } + }) + + REPLACEMENT_MAPPINGS + } + + def init(): Unit = { + // SUPER EVIL INITIALIZATION + try { + val map = PomModuleDescriptorBuilder.MAVEN2_CONF_MAPPING.asInstanceOf[java.util.Map[String, PomModuleDescriptorBuilder.ConfMapper]] + map.clear() + map.putAll(REPLACEMENT_MAVEN_MAPPINGS) + } catch { + case e: Exception => + // TODO - Log that Ivy may not be configured correctly and you could have maven/ivy issues. + throw new RuntimeException("FAILURE to install Ivy maven hooks. Your ivy-maven interaction may suffer resolution errors", e) + } + } +} \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index bcb8a2476..e19f01a9c 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -4,7 +4,7 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DependencyDescriptor } import org.apache.ivy.plugins.parser.{ ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings } -import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorBuilder, PomModuleDescriptorParser } +import org.apache.ivy.plugins.parser.m2.{ EvilHackery, PomModuleDescriptorBuilder, PomModuleDescriptorParser } import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.namespace.NamespaceTransformer import org.apache.ivy.util.extendable.ExtendableItem @@ -27,6 +27,10 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) } object CustomPomParser { + + // Evil hackery to override the default maven pom mappings. + EvilHackery.init() + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ val InfoKeyPrefix = "info." val ApiURLKey = "info.apiURL" From bff6d7adfa4c70ff2f4b26999178d3f68283894a Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 10 Sep 2014 07:56:19 -0400 Subject: [PATCH 0329/1030] Fixes from review, better names and internal code documentation. --- ...> ReplaceMavenConfigurationMappings.scala} | 44 ++++++++++++++----- ivy/src/main/scala/sbt/CustomPomParser.scala | 4 +- 2 files changed, 34 insertions(+), 14 deletions(-) rename ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/{EvilHackery.scala => ReplaceMavenConfigurationMappings.scala} (55%) diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala similarity index 55% rename from ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala rename to ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index f76637404..68a9dad40 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/EvilHackery.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -3,42 +3,62 @@ package org.apache.ivy.plugins.parser.m2 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; /** - * Helper evil hackery method to ensure Maven configurations + Ivy i + * It turns out there was a very subtle, and evil, issue sitting the Ivy/maven configuration, and it + * related to dependency mapping. A mapping of `foo->bar(*)` means that the local configuration + * `foo` depends on the remote configuration `bar`, if it exists, or *ALL CONFIGURATIONS* if `bar` + * does not exist. Since the default Ivy configuration mapping was using the random `master` + * configuration, which AFAICT is NEVER specified, just an assumed default, this would cause leaks + * between maven + ivy projects. + * + * i.e. if a maven POM depends on a module denoted by an ivy.xml file, then you'd wind up accidentally + * bleeding ALL the ivy module's configurations into the maven module's configurations. + * + * This fix works around the issue, by assuming that if there is no `master` configuration, than the + * maven default of `compile` is intended. As sbt forces generated `ivy.xml` files to abide by + * maven conventions, this works in all of our test cases. The only scenario where it wouldn't work + * is those who have custom ivy.xml files *and* have pom.xml files which rely on those custom ivy.xml files, + * a very unlikely situation where the workaround is: "define a master configuration". + * + * Also see: http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html + * and: http://svn.apache.org/repos/asf/ant/ivy/core/tags/2.3.0/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java + * + * */ -object EvilHackery { +object ReplaceMavenConfigurationMappings { val REPLACEMENT_MAVEN_MAPPINGS = { // Here we copy paste from Ivy val REPLACEMENT_MAPPINGS = new java.util.HashMap[String, PomModuleDescriptorBuilder.ConfMapper] + // NOTE - This code is copied from org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder + // except with altered default configurations... REPLACEMENT_MAPPINGS.put("compile", new PomModuleDescriptorBuilder.ConfMapper { def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") - // NOTE - This is the problematic piece we're dropping. EVIL!!!! + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("optional", "master(compile)") } else { dd.addDependencyConfiguration("compile", "compile(*)") - // NOTE - This is the problematic piece we're dropping, as `master` is not special cased. + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("compile", "master(compile)") dd.addDependencyConfiguration("runtime", "runtime(*)") } } }) - REPLACEMENT_MAPPINGS.put("provided", new PomModuleDescriptorBuilder.ConfMapper { def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") dd.addDependencyConfiguration("optional", "provided(*)") dd.addDependencyConfiguration("optional", "runtime(*)") - // Remove evil hackery + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("optional", "master(compile)") } else { dd.addDependencyConfiguration("provided", "compile(*)") dd.addDependencyConfiguration("provided", "provided(*)") dd.addDependencyConfiguration("provided", "runtime(*)") - // Remove evil hackery + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("provided", "master(compile)") } } @@ -49,12 +69,12 @@ object EvilHackery { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") dd.addDependencyConfiguration("optional", "provided(*)") - // Remove evil hackery + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("optional", "master(compile)") } else { dd.addDependencyConfiguration("runtime", "compile(*)") dd.addDependencyConfiguration("runtime", "runtime(*)") - // Remove evil hackery + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("runtime", "master(compile)") } } @@ -63,14 +83,14 @@ object EvilHackery { REPLACEMENT_MAPPINGS.put("test", new PomModuleDescriptorBuilder.ConfMapper { def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { dd.addDependencyConfiguration("test", "runtime(*)") - // Remove evil hackery + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("test", "master(compile)") } }) REPLACEMENT_MAPPINGS.put("system", new PomModuleDescriptorBuilder.ConfMapper { def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { - // Hacked + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("system", "master(compile)") } }) @@ -79,7 +99,7 @@ object EvilHackery { } def init(): Unit = { - // SUPER EVIL INITIALIZATION + // Here we mutate a static final field, because we have to AND because it's evil. try { val map = PomModuleDescriptorBuilder.MAVEN2_CONF_MAPPING.asInstanceOf[java.util.Map[String, PomModuleDescriptorBuilder.ConfMapper]] map.clear() diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index e19f01a9c..7bc878b2b 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -4,7 +4,7 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DependencyDescriptor } import org.apache.ivy.plugins.parser.{ ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings } -import org.apache.ivy.plugins.parser.m2.{ EvilHackery, PomModuleDescriptorBuilder, PomModuleDescriptorParser } +import org.apache.ivy.plugins.parser.m2.{ ReplaceMavenConfigurationMappings, PomModuleDescriptorBuilder, PomModuleDescriptorParser } import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.namespace.NamespaceTransformer import org.apache.ivy.util.extendable.ExtendableItem @@ -29,7 +29,7 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module object CustomPomParser { // Evil hackery to override the default maven pom mappings. - EvilHackery.init() + ReplaceMavenConfigurationMappings.init() /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ val InfoKeyPrefix = "info." From ac83ec98f214cf76a7db0e16b576aa5be53cd666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-R=C3=A9mi=20Desjardins?= Date: Wed, 10 Sep 2014 20:18:28 -0700 Subject: [PATCH 0330/1030] Add developers keySetting The motivation for this is mainly to avoid having to define a pomExtra to publish to Maven central --- ivy/src/main/scala/sbt/IvyInterface.scala | 4 +++- ivy/src/main/scala/sbt/MakePom.scala | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 05720e6aa..3e63c4871 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -10,7 +10,7 @@ import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ -final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) { +final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) @@ -20,6 +20,8 @@ final case class ModuleInfo(nameFormal: String, description: String = "", homepa /** Basic SCM information for a project module */ final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) +final case class Developer(id: String, name: String, email: String, url: URL) + /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ final case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index e05221b43..eba0cd94d 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -42,6 +42,7 @@ class MakePom(val log: Logger) { { makeStartYear(moduleInfo) } { makeOrganization(moduleInfo) } { makeScmInfo(moduleInfo) } + { makeDeveloperInfo(moduleInfo) } { extra } { val deps = depsInConfs(module, configurations) @@ -100,6 +101,21 @@ class MakePom(val log: Logger) { case _ => NodeSeq.Empty } } + def makeDeveloperInfo(moduleInfo: ModuleInfo): NodeSeq = + { + if (moduleInfo.developers.nonEmpty) { + + moduleInfo.developers.map{ developer: Developer => + + { developer.id } + { developer.name } + { developer.email } + { developer.url } + + } + + } else NodeSeq.Empty + } def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) From ad0775708711654b39b762ed11180854b243ad91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-R=C3=A9mi=20Desjardins?= Date: Thu, 11 Sep 2014 09:36:37 -0700 Subject: [PATCH 0331/1030] Add constructor to avoid binary compatibility issues --- ivy/src/main/scala/sbt/IvyInterface.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 3e63c4871..3a3d77cf1 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -11,6 +11,8 @@ import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { + def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) = + new ModuleInfo(nameFormal = nameFormal, description = description, homepage = homepage, startYear = startYear, licenses = licenses, organizationName = organizationName, organizationHomepage = organizationHomepage, scmInfo = scmInfo, developers = Seq()) def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) From cf48063f2f77ddd8ba46ce480da653c331785279 Mon Sep 17 00:00:00 2001 From: Brian Topping Date: Mon, 15 Sep 2014 10:48:47 -0400 Subject: [PATCH 0332/1030] Untested PR for #485. Unable to test because unable to build --- ivy/src/main/scala/sbt/Resolver.scala | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 3678adadb..91368abfc 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -5,7 +5,7 @@ package sbt import java.io.File import java.net.URL -import scala.xml.NodeSeq +import scala.xml.{ XML, NodeSeq } import org.apache.ivy.plugins.resolver.DependencyResolver sealed trait Resolver { @@ -300,8 +300,19 @@ object Resolver { def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - - private[this] def mavenLocalDir = new File(Path.userHome, ".m2/repository/") + private[this] def mavenLocalDir: File = + { + val homeConfig = XML.loadFile(new File(Path.userHome, ".m2/settings.xml")) + homeConfig \ "settings" \ "localRepository" match { + case scala.xml.Text(x) => new File(x) + case _ => + val globalConfig = XML.loadFile(new File(Path.fileProperty("M2_HOME"), "conf/settings.xml")) + globalConfig \ "settings" \ "localRepository" match { + case scala.xml.Text(x) => new File(x) + case _ => new File(Path.userHome, ".m2/repository/") + } + } + } def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) def defaultLocal = defaultUserFileRepository("local") From e81e8596b77ea27e64d8d5e56908ffcaf6c82812 Mon Sep 17 00:00:00 2001 From: Brian Topping Date: Mon, 15 Sep 2014 10:48:47 -0400 Subject: [PATCH 0333/1030] Tested PR for #485. Had a hard time squashing this, maybe because I did a merge in between. Sorry about that! --- ivy/src/main/scala/sbt/Resolver.scala | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 91368abfc..9ba5d56ce 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -300,18 +300,19 @@ object Resolver { def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - private[this] def mavenLocalDir: File = - { - val homeConfig = XML.loadFile(new File(Path.userHome, ".m2/settings.xml")) - homeConfig \ "settings" \ "localRepository" match { - case scala.xml.Text(x) => new File(x) - case _ => - val globalConfig = XML.loadFile(new File(Path.fileProperty("M2_HOME"), "conf/settings.xml")) - globalConfig \ "settings" \ "localRepository" match { - case scala.xml.Text(x) => new File(x) - case _ => new File(Path.userHome, ".m2/repository/") - } + private[this] def mavenLocalDir: File = { + def loadHomeFromSettings(f: () => File): Option[File] = + try { + XML.loadFile(f()) \ "settings" \ "localRepository" match { + case scala.xml.Text(loc) => Some(new File(loc)) + case _ => None + } + } catch { + case _: Throwable => None } + loadHomeFromSettings(() => new File(Path.userHome, ".m2/settings.xml")) orElse + loadHomeFromSettings(() => new File(Path.fileProperty("M2_HOME"), "conf/settings.xml")) getOrElse + new File(Path.userHome, ".m2/repository") } def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) From 29cf4ef814b11f5c015ae681032bccf493b838d5 Mon Sep 17 00:00:00 2001 From: Jean-Remi Desjardins Date: Mon, 15 Sep 2014 22:38:44 -0700 Subject: [PATCH 0334/1030] Change additional constructor to what it should probably be I am at a total loss for why this is not compiling. --- ivy/src/main/scala/sbt/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 3a3d77cf1..2f3258793 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -12,7 +12,7 @@ import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) = - new ModuleInfo(nameFormal = nameFormal, description = description, homepage = homepage, startYear = startYear, licenses = licenses, organizationName = organizationName, organizationHomepage = organizationHomepage, scmInfo = scmInfo, developers = Seq()) + this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq()) def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) From 577496b1b609c4d756b8efb448d46b26953d65df Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 16 Sep 2014 00:03:36 -0400 Subject: [PATCH 0335/1030] Expose Ivy's circular dependency check via UpdateOptions --- .../scala/sbt/CircularDependencyLevel.scala | 27 +++++++++++++++++++ ivy/src/main/scala/sbt/Ivy.scala | 1 + ivy/src/main/scala/sbt/UpdateOptions.scala | 10 ++++++- 3 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 ivy/src/main/scala/sbt/CircularDependencyLevel.scala diff --git a/ivy/src/main/scala/sbt/CircularDependencyLevel.scala b/ivy/src/main/scala/sbt/CircularDependencyLevel.scala new file mode 100644 index 000000000..3c2f62bc6 --- /dev/null +++ b/ivy/src/main/scala/sbt/CircularDependencyLevel.scala @@ -0,0 +1,27 @@ +package sbt + +import org.apache.ivy.plugins.circular.{ CircularDependencyStrategy, WarnCircularDependencyStrategy, IgnoreCircularDependencyStrategy, ErrorCircularDependencyStrategy } + +/** + * Wrapper around circular dependency strategy. + */ +sealed trait CircularDependencyLevel { + private[sbt] def ivyStrategy: CircularDependencyStrategy + private[sbt] def name: String + override def toString: String = name +} + +object CircularDependencyLevel { + val Warn: CircularDependencyLevel = new CircularDependencyLevel { + def ivyStrategy: CircularDependencyStrategy = WarnCircularDependencyStrategy.getInstance + def name: String = "warn" + } + val Ignore: CircularDependencyLevel = new CircularDependencyLevel { + def ivyStrategy: CircularDependencyStrategy = IgnoreCircularDependencyStrategy.getInstance + def name: String = "ignore" + } + val Error: CircularDependencyLevel = new CircularDependencyLevel { + def ivyStrategy: CircularDependencyStrategy = ErrorCircularDependencyStrategy.getInstance + def name: String = "error" + } +} diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 55a596bbc..cc39ab42e 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -69,6 +69,7 @@ final class IvySbt(val configuration: IvyConfiguration) { { val is = new IvySettings is.setBaseDir(baseDirectory) + is.setCircularDependencyStrategy(configuration.updateOptions.circularDependencyLevel.ivyStrategy) CustomPomParser.registerDefault configuration match { case e: ExternalIvyConfiguration => diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index dd4c83f47..d3bf28bfc 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -10,25 +10,33 @@ import java.io.File * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( + /** If set to CircularDependencyLevel.Error, halt the dependency resolution. */ + val circularDependencyLevel: CircularDependencyLevel, /** If set to true, check all resolvers for snapshots. */ val latestSnapshots: Boolean, /** If set to true, use consolidated resolution. */ val consolidatedResolution: Boolean) { + def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = + copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = copy(consolidatedResolution = consolidatedResolution) private[sbt] def copy( + circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution): UpdateOptions = - new UpdateOptions(latestSnapshots, consolidatedResolution) + new UpdateOptions(circularDependencyLevel, + latestSnapshots, + consolidatedResolution) } object UpdateOptions { def apply(): UpdateOptions = new UpdateOptions( + circularDependencyLevel = CircularDependencyLevel.Warn, latestSnapshots = true, consolidatedResolution = false) } From 53e4bce5e34fa5523500d899fbc73f1fb80a4203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-R=C3=A9mi=20Desjardins?= Date: Tue, 16 Sep 2014 09:26:43 -0700 Subject: [PATCH 0336/1030] Fix obtuse compilation error --- ivy/src/main/scala/sbt/IvyInterface.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index 3a3d77cf1..c5d4db1ea 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -11,8 +11,8 @@ import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { - def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) = - new ModuleInfo(nameFormal = nameFormal, description = description, homepage = homepage, startYear = startYear, licenses = licenses, organizationName = organizationName, organizationHomepage = organizationHomepage, scmInfo = scmInfo, developers = Seq()) + def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) = + this(nameFormal = nameFormal, description = description, homepage = homepage, startYear = startYear, licenses = licenses, organizationName = organizationName, organizationHomepage = organizationHomepage, scmInfo = scmInfo, developers = Seq()) def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) From 7edf77bc2800ab23e771734ed21839971bfd3498 Mon Sep 17 00:00:00 2001 From: Brian Topping Date: Wed, 17 Sep 2014 15:24:33 -0400 Subject: [PATCH 0337/1030] Additional updates, should be clean now. --- ivy/src/main/scala/sbt/Resolver.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 9ba5d56ce..f7318fb5a 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -5,7 +5,7 @@ package sbt import java.io.File import java.net.URL -import scala.xml.{ XML, NodeSeq } +import scala.xml.{ Text, NodeSeq, Elem, XML } import org.apache.ivy.plugins.resolver.DependencyResolver sealed trait Resolver { @@ -303,17 +303,19 @@ object Resolver { private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { - XML.loadFile(f()) \ "settings" \ "localRepository" match { - case scala.xml.Text(loc) => Some(new File(loc)) - case _ => None + val file = XML.loadFile(f()) + (file \ "localRepository").text match { + case "" => None + case e @ _ => Some(new File(e)) } } catch { - case _: Throwable => None + // Occurs inside File constructor when property or environment variable does not exist + case _: NullPointerException => None } loadHomeFromSettings(() => new File(Path.userHome, ".m2/settings.xml")) orElse - loadHomeFromSettings(() => new File(Path.fileProperty("M2_HOME"), "conf/settings.xml")) getOrElse + loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse new File(Path.userHome, ".m2/repository") - } + } def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) def defaultLocal = defaultUserFileRepository("local") From db04fa53bef58c8bc85fc773b5b732b972aa4d9e Mon Sep 17 00:00:00 2001 From: Brian Topping Date: Mon, 22 Sep 2014 10:56:10 -0400 Subject: [PATCH 0338/1030] Add warning for bad XML parse of settings file --- ivy/src/main/scala/sbt/Resolver.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index f7318fb5a..b0a45f949 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -7,6 +7,7 @@ import java.io.File import java.net.URL import scala.xml.{ Text, NodeSeq, Elem, XML } import org.apache.ivy.plugins.resolver.DependencyResolver +import org.xml.sax.SAXParseException sealed trait Resolver { def name: String @@ -311,6 +312,7 @@ object Resolver { } catch { // Occurs inside File constructor when property or environment variable does not exist case _: NullPointerException => None + case e: SAXParseException => System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); None } loadHomeFromSettings(() => new File(Path.userHome, ".m2/settings.xml")) orElse loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse From 704d8238491e99954e9676e43874a24a6ab2aeff Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 24 Sep 2014 14:37:26 -0400 Subject: [PATCH 0339/1030] Fix URL resolver so that we can push Maven artifacts to local maven repositories. * Hook "LocalIfFile" repository to also handle publishing * Add test to ensure mavne publishign works. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 35 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 70a0530e1..35cfb669f 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -9,12 +9,13 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, TransferEvent } import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver } import org.apache.ivy.plugins.resolver.{ AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver } import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, FileResource } -import java.io.File -import org.apache.ivy.util.ChecksumHelper +import java.io.{ IOException, File } +import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } private[sbt] object ConvertResolver { @@ -216,6 +217,7 @@ private[sbt] object ConvertResolver { */ private[this] final class LocalIfFileRepo extends URLRepo { private[this] val repo = new WarnOnOverwriteFileRepo() + private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { val url = new URL(source) if (url.getProtocol == IO.FileScheme) @@ -223,6 +225,35 @@ private[sbt] object ConvertResolver { else super.getResource(source) } + + override def put(source: File, destination: String, overwrite: Boolean): Unit = { + val url = new URL(destination) + if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) + else { + // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler + val resource = getResource(destination) + if (!overwrite && resource.exists()) { + throw new IOException("destination file exists and overwrite == false"); + } + fireTransferInitiated(resource, TransferEvent.REQUEST_PUT); + try { + var totalLength = source.length + if (totalLength > 0) { + progress.setTotalLength(totalLength); + } + FileUtil.copy(source, new java.io.File(url.toURI), progress) + } catch { + case ex: IOException => + fireTransferError(ex) + throw ex + case ex: RuntimeException => + fireTransferError(ex) + throw ex + } finally { + progress.setTotalLength(null); + } + } + } } private[this] final class WarnOnOverwriteFileRepo extends FileRepo() { From 7e100a0fe0cd8c95f970186e693abe7dfbd3067f Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 24 Sep 2014 14:41:32 -0400 Subject: [PATCH 0340/1030] Add workaround (and warning message) for when ChainResolver gets a null publication date while we investigate other issues. * Attempt to set publication date to last modified time, if the stars align * Issue warning about undefined resolution behavior otherwise * Add scripted test which exercises the NPE issue in resolving -SNAPSHOTs. * Commit scalariform style edit in Act.scala * After parsing and transforming the pom, check for pub date. * If we don't have a pub date, try to grab lastModified from the URL * If we can't do anything, issue a warning about the problem artifact. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 3 ++- .../scala/sbt/ivyint/SbtChainResolver.scala | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 7bc878b2b..202216700 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -54,7 +54,8 @@ object CustomPomParser { lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) def defaultTransform(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - if (transformedByThisVersion(md)) md else defaultTransformImpl(parser, md) + if (transformedByThisVersion(md)) md + else defaultTransformImpl(parser, md) private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = { diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 685431124..9a2b483aa 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -7,7 +7,7 @@ import java.util.Date import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.{ IvyContext, LogOptions } -import org.apache.ivy.core.module.descriptor.{ ModuleDescriptor, DependencyDescriptor, Artifact => IArtifact } +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultModuleDescriptor, DefaultDependencyDescriptor, ModuleDescriptor, DependencyDescriptor } import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } import org.apache.ivy.plugins.latest.LatestStrategy import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } @@ -94,6 +94,23 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting } else temp map { x => (forcedRevision(x), resolver) } ) + retval match { + case Right(Some((rmr, _))) => + rmr.getDescriptor.getPublicationDate match { + case null => + val ivf = resolver.findIvyFileRef(dd, data) + val lmd = new java.util.Date(ivf.getLastModified) + rmr.getDescriptor match { + case dmd: DefaultModuleDescriptor => + Message.info(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + dmd.setPublicationDate(lmd) + case _ => + Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + } + case _ => // All other cases ok + } + case _ => + } retval } catch { case ex: Exception => @@ -111,7 +128,10 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting val sorted = if (useLatest) (foundRevisions.sortBy { case (rmr, _) => - rmr.getDescriptor.getPublicationDate.getTime + rmr.getDescriptor.getPublicationDate match { + case null => 0L + case d => d.getTime + } }).reverse.headOption map { case (rmr, resolver) => // Now that we know the real latest revision, let's force Ivy to use it From 51f48a8993456dc4cb52a638af689200157ed303 Mon Sep 17 00:00:00 2001 From: Tejas Mandke Date: Wed, 24 Sep 2014 19:33:18 -0700 Subject: [PATCH 0341/1030] propagate pattern descriptorOptional and skipConsistencyCheck --- ivy/src/main/scala/sbt/Resolver.scala | 2 +- ivy/src/test/scala/ResolverTest.scala | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 ivy/src/test/scala/ResolverTest.scala diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index b0a45f949..01db05ea1 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -285,7 +285,7 @@ object Resolver { private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = { def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) - Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible) + Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible, basePatterns.descriptorOptional, basePatterns.skipConsistencyCheck) } private[sbt] def resolvePattern(base: String, pattern: String): String = { diff --git a/ivy/src/test/scala/ResolverTest.scala b/ivy/src/test/scala/ResolverTest.scala new file mode 100644 index 000000000..64c6ab777 --- /dev/null +++ b/ivy/src/test/scala/ResolverTest.scala @@ -0,0 +1,24 @@ +import java.net.URL + +import org.specs2.mutable.Specification +import sbt._ + +object ResolverTest extends Specification { + + "Resolver" should { + "url" should { + "propagate pattern descriptorOptional and skipConsistencyCheck." in { + val pats = Seq("[orgPath]") + val patsExpected = Seq("http://foo.com/test/[orgPath]") + val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns + + patterns.ivyPatterns must equalTo(patsExpected) + patterns.artifactPatterns must equalTo(patsExpected) + patterns.isMavenCompatible must beFalse + patterns.skipConsistencyCheck must beTrue + patterns.descriptorOptional must beTrue + } + } + } + +} From 8166c8aa5df7e355ff8d2fe1fb5f682eb0c7d13d Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 25 Sep 2014 08:08:26 -0400 Subject: [PATCH 0342/1030] Fix NPE in ChainrResolver when there is no ivy file for a dependency. --- ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 9a2b483aa..f7dad987d 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -98,10 +98,13 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting case Right(Some((rmr, _))) => rmr.getDescriptor.getPublicationDate match { case null => - val ivf = resolver.findIvyFileRef(dd, data) - val lmd = new java.util.Date(ivf.getLastModified) - rmr.getDescriptor match { - case dmd: DefaultModuleDescriptor => + (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { + case (null, _) => + // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file + if (dd.isChanging) + Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + case (ivf, dmd: DefaultModuleDescriptor) => + val lmd = new java.util.Date(ivf.getLastModified) Message.info(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") dmd.setPublicationDate(lmd) case _ => From 855f1f0c33e615e0f1bf2e240f5a8b506db34a5f Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 29 Sep 2014 14:09:35 -0400 Subject: [PATCH 0343/1030] Reduce the noise when resolving maven artifacts. --- ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index f7dad987d..bd748527e 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -105,7 +105,7 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") case (ivf, dmd: DefaultModuleDescriptor) => val lmd = new java.util.Date(ivf.getLastModified) - Message.info(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") dmd.setPublicationDate(lmd) case _ => Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") From 07b696b395145280318560dc7d62e778703a925f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Sep 2014 17:33:37 -0400 Subject: [PATCH 0344/1030] Implemented cached resolution (minigraph caching) --- ivy/src/main/scala/sbt/Ivy.scala | 24 +- ivy/src/main/scala/sbt/IvyActions.scala | 29 +- ivy/src/main/scala/sbt/IvyRetrieve.scala | 24 +- ivy/src/main/scala/sbt/LogicalClock.scala | 16 + ivy/src/main/scala/sbt/UpdateOptions.scala | 20 +- ivy/src/main/scala/sbt/UpdateReport.scala | 5 +- .../CachedResolutionResolveEngine.scala | 411 ++++++++++++++++++ .../ivyint/ConsolidatedResolveEngine.scala | 120 ----- ivy/src/test/scala/BaseIvySpecification.scala | 26 +- ivy/src/test/scala/CachedResolutionSpec.scala | 51 +++ 10 files changed, 562 insertions(+), 164 deletions(-) create mode 100644 ivy/src/main/scala/sbt/LogicalClock.scala create mode 100644 ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala delete mode 100644 ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala create mode 100644 ivy/src/test/scala/CachedResolutionSpec.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index cc39ab42e..db8d8ed1e 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -4,7 +4,7 @@ package sbt import Resolver.PluginPattern -import ivyint.{ ConsolidatedResolveEngine, ConsolidatedResolveCache } +import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache } import java.io.File import java.net.URI @@ -84,7 +84,7 @@ final class IvySbt(val configuration: IvyConfiguration) { } is } - private lazy val ivy: Ivy = + private[sbt] def mkIvy: Ivy = { val i = new Ivy() { private val loggerEngine = new SbtMessageLoggerEngine @@ -94,9 +94,9 @@ final class IvySbt(val configuration: IvyConfiguration) { // We inject the deps we need before we can hook our resolve engine. setSortEngine(new SortEngine(getSettings)) setEventManager(new EventManager()) - if (configuration.updateOptions.consolidatedResolution) { - setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with ConsolidatedResolveEngine { - val consolidatedResolveCache = IvySbt.consolidatedResolveCache + if (configuration.updateOptions.cachedResolution) { + setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine { + val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache val projectResolver = prOpt }) } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) @@ -108,6 +108,8 @@ final class IvySbt(val configuration: IvyConfiguration) { i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) i } + + private lazy val ivy: Ivy = mkIvy // Must be the same file as is used in Update in the launcher private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") /** ========== End Configuration/Setup ============*/ @@ -130,14 +132,14 @@ final class IvySbt(val configuration: IvyConfiguration) { } /** - * Cleans consolidated resolution cache. + * Cleans cached resolution cache. * @param md - module descriptor of the original Ivy graph. */ - private[sbt] def cleanConsolidatedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = + private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = withIvy(log) { i => val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } - if (configuration.updateOptions.consolidatedResolution) { - IvySbt.consolidatedResolveCache.clean(md, prOpt) + if (configuration.updateOptions.cachedResolution) { + IvySbt.cachedResolutionResolveCache.clean(md, prOpt) } } @@ -242,7 +244,7 @@ private[sbt] object IvySbt { val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" val DefaultChecksums = Seq("sha1", "md5") - private[sbt] val consolidatedResolveCache: ConsolidatedResolveCache = new ConsolidatedResolveCache() + private[sbt] val cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache() def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) @@ -270,6 +272,8 @@ private[sbt] object IvySbt { val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } + private[sbt] def isChanging(module: ModuleID): Boolean = + module.revision endsWith "-SNAPSHOT" private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean = mrid.getRevision endsWith "-SNAPSHOT" def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 4d69ae2c7..0d12d5b06 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -6,6 +6,7 @@ package sbt import java.io.File import scala.xml.{ Node => XNode, NodeSeq } import collection.mutable +import ivyint.CachedResolutionResolveEngine import org.apache.ivy.Ivy import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } @@ -69,12 +70,12 @@ object IvyActions { } /** - * Cleans the consolidated resolution cache, if any. + * Cleans the cached resolution cache, if any. * This is called by clean. */ - private[sbt] def cleanConsolidatedResolutionCache(module: IvySbt#Module, log: Logger): Unit = + private[sbt] def cleanCachedResolutionCache(module: IvySbt#Module, log: Logger): Unit = module.withModule(log) { (ivy, md, default) => - module.owner.cleanConsolidatedResolutionCache(md, log) + module.owner.cleanCachedResolutionCache(md, log) } /** Creates a Maven pom from the given Ivy configuration*/ @@ -141,7 +142,7 @@ object IvyActions { */ @deprecated("Use updateEither instead.", "0.13.6") def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = - updateEither(module, configuration, UnresolvedWarningConfiguration(), log) match { + updateEither(module, configuration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { case Right(r) => r case Left(w) => throw w.resolveException @@ -151,9 +152,25 @@ object IvyActions { * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, log: Logger): Either[UnresolvedWarning, UpdateReport] = + private[sbt] def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): Either[UnresolvedWarning, UpdateReport] = module.withModule(log) { + case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution => + ivy.getResolveEngine match { + case x: CachedResolutionResolveEngine => + val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(md) + resolveOptions.setResolveId(resolveId) + x.customResolve(md, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { + case Left(x) => + Left(UnresolvedWarning(x, uwconfig)) + case Right(uReport) => + configuration.retrieve match { + case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case None => Right(uReport) + } + } + } case (ivy, md, default) => val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index 5f07963bd..bb15c68df 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -76,8 +76,12 @@ object IvyRetrieve { val callerConfigurations = caller.getCallerConfigurations.toArray.toVector collect { case x if nonEmptyString(x).isDefined => x } - val extraAttributes = toExtraAttributes(caller.getDependencyDescriptor.getExtraAttributes) - new Caller(m, callerConfigurations, extraAttributes) + val ddOpt = Option(caller.getDependencyDescriptor) + val (extraAttributes, isForce, isChanging, isTransitive) = ddOpt match { + case Some(dd) => (toExtraAttributes(dd.getExtraAttributes), dd.isForce, dd.isChanging, dd.isTransitive) + case None => (Map.empty[String, String], false, false, true) + } + new Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive) } val revId = dep.getResolvedId val moduleId = toModuleID(revId) @@ -160,19 +164,11 @@ object IvyRetrieve { */ def findPath(target: IvyNode, from: ModuleRevisionId): List[IvyNode] = { def doFindPath(current: IvyNode, path: List[IvyNode]): List[IvyNode] = { - val callers = current.getAllRealCallers.toList - // Ivy actually returns non-direct callers here. + // Ivy actually returns mix of direct and non-direct callers here. // that's why we have to calculate all possible paths below and pick the longest path. - val directCallers = callers filter { caller => - val md = caller.getModuleDescriptor - val dd = md.getDependencies.toList find { dd => - (dd.getDependencyRevisionId == current.getId) && - (dd.getParentRevisionId == caller.getModuleRevisionId) - } - dd.isDefined - } - val directCallersRevId = (directCallers map { _.getModuleRevisionId }).distinct - val paths: List[List[IvyNode]] = ((directCallersRevId map { revId => + val callers = current.getAllRealCallers.toList + val callersRevId = (callers map { _.getModuleRevisionId }).distinct + val paths: List[List[IvyNode]] = ((callersRevId map { revId => val node = current.findNode(revId) if (revId == from) node :: path else if (node == node.getRoot) Nil diff --git a/ivy/src/main/scala/sbt/LogicalClock.scala b/ivy/src/main/scala/sbt/LogicalClock.scala new file mode 100644 index 000000000..1056f6560 --- /dev/null +++ b/ivy/src/main/scala/sbt/LogicalClock.scala @@ -0,0 +1,16 @@ +package sbt + +/** + * Represents a logical time point for dependency resolution. + * This is used to cache dependencies across subproject resolution which may change over time. + */ +trait LogicalClock { + def toString: String +} + +object LogicalClock { + def apply(x: String): LogicalClock = new LogicalClock { + override def toString: String = x + } + def unknown: LogicalClock = apply("unknown") +} diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index d3bf28bfc..1d8ad1aec 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -15,22 +15,31 @@ final class UpdateOptions private[sbt] ( /** If set to true, check all resolvers for snapshots. */ val latestSnapshots: Boolean, /** If set to true, use consolidated resolution. */ - val consolidatedResolution: Boolean) { + val consolidatedResolution: Boolean, + /** If set to true, use cached resolution. */ + val cachedResolution: Boolean) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) + @deprecated("Use withCachedResolution instead.", "0.13.7") def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = - copy(consolidatedResolution = consolidatedResolution) + copy(consolidatedResolution = consolidatedResolution, + cachedResolution = consolidatedResolution) + def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = + copy(cachedResolution = cachedResoluton, + consolidatedResolution = cachedResolution) private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, latestSnapshots: Boolean = this.latestSnapshots, - consolidatedResolution: Boolean = this.consolidatedResolution): UpdateOptions = + consolidatedResolution: Boolean = this.consolidatedResolution, + cachedResolution: Boolean = this.cachedResolution): UpdateOptions = new UpdateOptions(circularDependencyLevel, latestSnapshots, - consolidatedResolution) + consolidatedResolution, + cachedResolution) } object UpdateOptions { @@ -38,5 +47,6 @@ object UpdateOptions { new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, latestSnapshots = true, - consolidatedResolution = false) + consolidatedResolution = false, + cachedResolution = false) } diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 7e04d5135..443c84ed3 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -187,7 +187,10 @@ object ModuleReport { final class Caller( val caller: ModuleID, val callerConfigurations: Seq[String], - val callerExtraAttributes: Map[String, String]) { + val callerExtraAttributes: Map[String, String], + val isForceDependency: Boolean, + val isChangingDependency: Boolean, + val isTransitiveDependency: Boolean) { override def toString: String = s"$caller" } diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala new file mode 100644 index 000000000..9db9343bb --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -0,0 +1,411 @@ +package sbt +package ivyint + +import java.util.Date +import java.net.URL +import java.io.File +import collection.concurrent +import collection.immutable.ListMap +import org.apache.ivy.core +import core.resolve._ +import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } +import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } +import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration } +import core.{ IvyPatternHelper, LogOptions } +import org.apache.ivy.util.Message +import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } +import org.json4s._ + +private[sbt] object CachedResolutionResolveCache { + def createID(organization: String, name: String, revision: String) = + ModuleRevisionId.newInstance(organization, name, revision) + def sbtOrgTemp = "org.scala-sbt.temp" +} + +class CachedResolutionResolveCache() { + import CachedResolutionResolveCache._ + val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() + val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() + val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() + val directDependencyCache: concurrent.Map[ModuleRevisionId, Vector[DependencyDescriptor]] = concurrent.TrieMap() + val conflictCache: concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap() + val maxConflictCacheSize: Int = 10000 + + def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { + val mrid0 = md0.getModuleRevisionId + val mds = + if (mrid0.getOrganisation == sbtOrgTemp) Vector(md0) + else buildArtificialModuleDescriptors(md0, prOpt) map { _._1 } + mds foreach { md => + updateReportCache.remove(md.getModuleRevisionId) + // todo: backport this + directDependencyCache.remove(md.getModuleRevisionId) + } + } + def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = + directDependencyCache.getOrElseUpdate(md0.getModuleRevisionId, md0.getDependencies.toVector) + + def buildArtificialModuleDescriptors(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Vector[(DefaultModuleDescriptor, Boolean)] = + { + def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] = + prOpt map { + _.getModuleDescriptor(dep.getDependencyRevisionId) match { + case Some(internal) => directDependencies(internal) flatMap expandInternalDeps + case _ => Vector(dep) + } + } getOrElse Vector(dep) + val expanded = directDependencies(md0) flatMap expandInternalDeps + val rootModuleConfigs = md0.getConfigurations.toVector + expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, prOpt) } + } + def isDependencyChanging(dd: DependencyDescriptor): Boolean = + dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId) + def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = + { + val mrid = dd.getDependencyRevisionId + val confMap = (dd.getModuleConfigurations map { conf => + conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" + }) + val depsString = mrid.toString + ";" + confMap.mkString(";") + val sha1 = Hash.toHex(Hash(depsString)) + val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { + def targetModuleRevisionId: ModuleRevisionId = mrid + } + for { + conf <- rootModuleConfigs + } yield md1.addConfiguration(conf) + md1.addDependency(dd) + (md1, isDependencyChanging(dd)) + } + def getOrElseUpdateMiniGraph(md: ModuleDescriptor, changing0: Boolean, logicalClock: LogicalClock, miniGraphPath: File, cachedDescriptor: File, log: Logger)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = + { + import Path._ + val mrid = md.getResolvedModuleRevisionId + val (pathOrg, pathName, pathRevision) = md match { + case x: ArtificialModuleDescriptor => + val tmrid = x.targetModuleRevisionId + (tmrid.getOrganisation, tmrid.getName, tmrid.getRevision + "_" + mrid.getName) + case _ => + (mrid.getOrganisation, mrid.getName, mrid.getRevision) + } + val staticGraphDirectory = miniGraphPath / "static" + val dynamicGraphDirectory = miniGraphPath / "dynamic" + val staticGraphPath = staticGraphDirectory / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = dynamicGraphDirectory / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + def loadMiniGraphFromFile: Option[Either[ResolveException, UpdateReport]] = + (if (staticGraphPath.exists) Some(staticGraphPath) + else if (dynamicGraphPath.exists) Some(dynamicGraphPath) + else None) map { path => + log.debug(s"parsing ${path.getAbsolutePath.toString}") + val ur = parseUpdateReport(md, path, cachedDescriptor, log) + updateReportCache(md.getModuleRevisionId) = Right(ur) + Right(ur) + } + (updateReportCache.get(mrid) orElse loadMiniGraphFromFile) match { + case Some(result) => result + case None => + f match { + case Right(ur) => + val changing = changing0 || (ur.configurations exists { cr => + cr.details exists { oar => + oar.modules exists { mr => + IvySbt.isChanging(mr.module) || (mr.callers exists { _.isChangingDependency }) + } + } + }) + IO.createDirectory(miniGraphPath) + writeUpdateReport(ur, + if (changing) dynamicGraphPath + else staticGraphPath) + // don't cache dynamic graphs in memory. + if (!changing) { + updateReportCache(md.getModuleRevisionId) = Right(ur) + } + Right(ur) + case Left(re) => + if (!changing0) { + updateReportCache(md.getModuleRevisionId) = Left(re) + } + Left(re) + } + } + } + def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = + { + import org.json4s._ + implicit val formats = native.Serialization.formats(NoTypeHints) + + new ConfigurationSerializer + + new ArtifactSerializer + + new FileSerializer + try { + val json = jawn.support.json4s.Parser.parseFromFile(path) + fromLite(json.get.extract[UpdateReportLite], cachedDescriptor) + } catch { + case e: Throwable => + log.error("Unable to parse mini graph: " + path.toString) + throw e + } + } + def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = + { + implicit val formats = native.Serialization.formats(NoTypeHints) + + new ConfigurationSerializer + + new ArtifactSerializer + + new FileSerializer + import native.Serialization.write + println(graphPath.toString) + val str = write(toLite(ur)) + IO.write(graphPath, str, IO.utf8) + } + def toLite(ur: UpdateReport): UpdateReportLite = + UpdateReportLite(ur.configurations map { cr => + ConfigurationReportLite(cr.configuration, cr.details) + }) + def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = + { + val stats = new UpdateStats(0L, 0L, 0L, false) + val configReports = lite.configurations map { cr => + val details = cr.details + val modules = details flatMap { + _.modules filter { mr => + !mr.evicted && mr.problem.isEmpty + } + } + val evicted = details flatMap { + _.modules filter { mr => + mr.evicted + } + } map { _.module } + new ConfigurationReport(cr.configuration, modules, details, evicted) + } + new UpdateReport(cachedDescriptor, configReports, stats) + } + def getOrElseUpdateConflict(cf0: ModuleID, cf1: ModuleID, conflicts: Vector[ModuleReport])(f: => (Vector[ModuleReport], Vector[ModuleReport], String)): (Vector[ModuleReport], Vector[ModuleReport]) = + { + def reconstructReports(surviving: Vector[ModuleID], evicted: Vector[ModuleID], mgr: String): (Vector[ModuleReport], Vector[ModuleReport]) = { + val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) + (surviving map moduleIdMap, evicted map moduleIdMap map { _.copy(evicted = true, evictedReason = Some(mgr.toString)) }) + } + (conflictCache get ((cf0, cf1))) match { + case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) + case _ => + (conflictCache get ((cf1, cf0))) match { + case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) + case _ => + val (surviving, evicted, mgr) = f + if (conflictCache.size > maxConflictCacheSize) { + conflictCache.remove(conflictCache.head._1) + } + conflictCache((cf0, cf1)) = (surviving map { _.module }, evicted map { _.module }, mgr) + (surviving, evicted) + } + } + } + class FileSerializer extends CustomSerializer[File](format => ( + { + case JString(s) => new File(s) + }, + { + case x: File => JString(x.toString) + } + )) + class ConfigurationSerializer extends CustomSerializer[Configuration](format => ( + { + case JString(s) => new Configuration(s) + }, + { + case x: Configuration => JString(x.name) + } + )) + class ArtifactSerializer extends CustomSerializer[Artifact](format => ( + { + case json: JValue => + implicit val fmt = format + Artifact( + (json \ "name").extract[String], + (json \ "type").extract[String], + (json \ "extension").extract[String], + (json \ "classifier").extract[Option[String]], + (json \ "configurations").extract[List[Configuration]], + (json \ "url").extract[Option[URL]], + (json \ "extraAttributes").extract[Map[String, String]] + ) + }, + { + case x: Artifact => + import DefaultJsonFormats.{ OptionWriter, StringWriter, mapWriter } + val optStr = implicitly[Writer[Option[String]]] + val mw = implicitly[Writer[Map[String, String]]] + JObject(JField("name", JString(x.name)) :: + JField("type", JString(x.`type`)) :: + JField("extension", JString(x.extension)) :: + JField("classifier", optStr.write(x.classifier)) :: + JField("configurations", JArray(x.configurations.toList map { x => JString(x.name) })) :: + JField("url", optStr.write(x.url map { _.toString })) :: + JField("extraAttributes", mw.write(x.extraAttributes)) :: + Nil) + } + )) +} + +private[sbt] trait ArtificialModuleDescriptor { self: DefaultModuleDescriptor => + def targetModuleRevisionId: ModuleRevisionId +} + +private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) +private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) + +private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { + import CachedResolutionResolveCache._ + + private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache + private[sbt] def projectResolver: Option[ProjectResolver] + + // Return sbt's UpdateReport. + def customResolve(md0: ModuleDescriptor, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { + import Path._ + val miniGraphPath = depDir / "module" + val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) + val cache = cachedResolutionResolveCache + val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver) + def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = + { + val options1 = new ResolveOptions(options0) + var rr = super.resolve(md, options1) + if (!rr.hasError) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) + else { + val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct + val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => + val m = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => + IvyRetrieve.toModuleID(x.getId) + } + log.debug("- Unresolved path " + path.toString) + m -> path + }: _*) + val failed = failedPaths.keys.toSeq + Left(new ResolveException(messages, failed, failedPaths)) + } + } + val results = mds map { + case (md, changing) => + cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + doWork(md) + } + } + val uReport = mergeResults(md0, results, log) + val cacheManager = getSettings.getResolutionCacheManager + cacheManager.saveResolvedModuleDescriptor(md0) + val prop0 = "" + val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) + IO.write(ivyPropertiesInCache0, prop0) + uReport + } + def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], log: Logger): Either[ResolveException, UpdateReport] = + if (results exists { _.isLeft }) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) + else Right(mergeReports(md0, results collect { case Right(ur) => ur }, log)) + def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException], log: Logger): ResolveException = + { + val messages = errors flatMap { _.messages } + val failed = errors flatMap { _.failed } + val failedPaths = errors flatMap { + _.failedPaths.toList map { + case (failed, paths) => + if (paths.isEmpty) (failed, paths) + else (failed, List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail) + } + } + new ResolveException(messages, failed, ListMap(failedPaths: _*)) + } + def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], log: Logger): UpdateReport = + { + val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) + val rootModuleConfigs = md0.getConfigurations.toVector + val stats = new UpdateStats(0L, 0L, 0L, false) + val configReports = rootModuleConfigs map { conf => + val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } + mergeConfigurationReports(conf.getName, crs, log) + } + new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + } + def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], log: Logger): ConfigurationReport = + { + // get the details right, and the rest could be derived + val details = mergeOrganizationArtifactReports(rootModuleConf, reports flatMap { _.details }, log) + val modules = details flatMap { + _.modules filter { mr => + !mr.evicted && mr.problem.isEmpty + } + } + val evicted = details flatMap { + _.modules filter { mr => + mr.evicted + } + } map { _.module } + new ConfigurationReport(rootModuleConf, modules, details, evicted) + } + def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], log: Logger): Vector[OrganizationArtifactReport] = + (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector flatMap { + case ((org, name), xs) => + if (xs.size < 2) xs + else Vector(new OrganizationArtifactReport(org, name, mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, log))) + } + def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], log: Logger): Vector[ModuleReport] = + { + val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { + case ((org, name, version), xs) => + if (xs.size < 2) xs + else Vector(xs.head.copy(evicted = xs exists { _.evicted }, callers = xs flatMap { _.callers })) + } + val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } + if (conflicts.size < 2) merged + else resolveConflict(rootModuleConf, conflicts, log) match { + case (survivor, evicted) => + survivor ++ evicted ++ (merged filter { m => m.evicted || m.problem.isDefined }) + } + } + def resolveConflict(rootModuleConf: String, conflicts: Vector[ModuleReport], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = + { + import org.apache.ivy.plugins.conflict.{ NoConflictManager, StrictConflictManager, LatestConflictManager } + val head = conflicts.head + val organization = head.module.organization + val name = head.module.name + log.debug(s"- conflict in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")")) + def useLatest(lcm: LatestConflictManager): (Vector[ModuleReport], Vector[ModuleReport], String) = + conflicts find { m => + m.callers.exists { _.isForceDependency } + } match { + case Some(m) => + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) + case None => + val strategy = lcm.getStrategy + val infos = conflicts map { ModuleReportArtifactInfo(_) } + Option(strategy.findLatest(infos.toArray, None.orNull)) match { + case Some(ModuleReportArtifactInfo(m)) => + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) + case _ => (conflicts, Vector(), lcm.toString) + } + } + def doResolveConflict: (Vector[ModuleReport], Vector[ModuleReport], String) = + getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { + case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) + case _: StrictConflictManager => sys.error((s"conflict was found in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")"))) + case lcm: LatestConflictManager => useLatest(lcm) + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + } + if (conflicts.size == 2) { + val (cf0, cf1) = (conflicts(0).module, conflicts(1).module) + val cache = cachedResolutionResolveCache + cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } + } else { + val (surviving, evicted, mgr) = doResolveConflict + (surviving, evicted) + } + + } +} + +private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) extends IvyArtifactInfo { + override def getLastModified: Long = moduleReport.publicationDate map { _.getTime } getOrElse 0L + override def getRevision: String = moduleReport.module.revision +} diff --git a/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala deleted file mode 100644 index c853791c8..000000000 --- a/ivy/src/main/scala/sbt/ivyint/ConsolidatedResolveEngine.scala +++ /dev/null @@ -1,120 +0,0 @@ -package sbt -package ivyint - -import java.io.File -import collection.concurrent -import org.apache.ivy.core -import core.resolve._ -import core.module.id.ModuleRevisionId -import core.report.ResolveReport -import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor } -import core.{ IvyPatternHelper, LogOptions } -import org.apache.ivy.util.Message - -private[sbt] object ConsolidatedResolveCache { - def createID(organization: String, name: String, revision: String) = - ModuleRevisionId.newInstance(organization, name, revision) - def sbtOrgTemp = "org.scala-sbt.temp" -} - -private[sbt] class ConsolidatedResolveCache() { - import ConsolidatedResolveCache._ - val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() - val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() - val directDependencyCache: concurrent.Map[ModuleDescriptor, Vector[DependencyDescriptor]] = concurrent.TrieMap() - - def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { - val mrid0 = md0.getModuleRevisionId - val md1 = if (mrid0.getOrganisation == sbtOrgTemp) md0 - else buildConsolidatedModuleDescriptor(md0, prOpt) - val mrid1 = md1.getModuleRevisionId - resolveReportCache.remove(mrid1) - resolvePropertiesCache.remove(mrid1) - } - - def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = - directDependencyCache.getOrElseUpdate(md0, md0.getDependencies.toVector) - - def buildConsolidatedModuleDescriptor(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): DefaultModuleDescriptor = { - def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] = - prOpt map { - _.getModuleDescriptor(dep.getDependencyRevisionId) match { - case Some(internal) => directDependencies(internal) flatMap expandInternalDeps - case _ => Vector(dep) - } - } getOrElse Vector(dep) - val expanded = directDependencies(md0) flatMap expandInternalDeps - val depStrings = expanded map { dep => - val mrid = dep.getDependencyRevisionId - val confMap = (dep.getModuleConfigurations map { conf => - conf + "->(" + dep.getDependencyConfigurations(conf).mkString(",") + ")" - }) - mrid.toString + ";" + confMap.mkString(";") - } - val depsString = depStrings.distinct.sorted.mkString("\n") - val sha1 = Hash.toHex(Hash(depsString)) - // println("sha1: " + sha1) - val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) - md1 - } -} - -private[sbt] trait ConsolidatedResolveEngine extends ResolveEngine { - import ConsolidatedResolveCache._ - - private[sbt] def consolidatedResolveCache: ConsolidatedResolveCache - private[sbt] def projectResolver: Option[ProjectResolver] - - /** - * Resolve dependencies of a module described by a module descriptor. - */ - override def resolve(md0: ModuleDescriptor, options0: ResolveOptions): ResolveReport = { - val cache = consolidatedResolveCache - val cacheManager = getSettings.getResolutionCacheManager - val md1 = cache.buildConsolidatedModuleDescriptor(md0, projectResolver) - val md1mrid = md1.getModuleRevisionId - - def doWork: (ResolveReport, String) = { - if (options0.getLog != LogOptions.LOG_QUIET) { - Message.info("Consolidating managed dependencies to " + md1mrid.toString + " ...") - } - md1.setLastModified(System.currentTimeMillis) - for { - x <- md0.getConfigurations - } yield md1.addConfiguration(x) - - for { - x <- md0.getDependencies - } yield md1.addDependency(x) - - val options1 = new ResolveOptions(options0) - options1.setOutputReport(false) - val report0 = super.resolve(md1, options1) - val ivyPropertiesInCache1 = cacheManager.getResolvedIvyPropertiesInCache(md1.getResolvedModuleRevisionId) - val prop0 = - if (ivyPropertiesInCache1.exists) IO.read(ivyPropertiesInCache1) - else "" - if (options0.isOutputReport) { - this.outputReport(report0, cacheManager, options0) - } - cache.resolveReportCache(md1mrid) = report0 - cache.resolvePropertiesCache(md1mrid) = prop0 - (report0, prop0) - } - - val (report0, prop0) = (cache.resolveReportCache.get(md1mrid), cache.resolvePropertiesCache.get(md1mrid)) match { - case (Some(report), Some(prop)) => - if (options0.getLog != LogOptions.LOG_QUIET) { - Message.info("Found consolidated dependency " + md1mrid.toString + " ...") - } - (report, prop) - case _ => doWork - } - cacheManager.saveResolvedModuleDescriptor(md0) - if (prop0 != "") { - val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) - IO.write(ivyPropertiesInCache0, prop0) - } - report0 - } -} diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index e754903fe..09d7da7a2 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -8,10 +8,12 @@ import cross.CrossVersionUtil trait BaseIvySpecification extends Specification { def currentBase: File = new File(".") def currentTarget: File = currentBase / "target" / "ivyhome" + def currentManaged: File = currentBase / "target" / "lib_managed" + def currentDependency: File = currentBase / "target" / "dependency" def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) - lazy val ivySbt = new IvySbt(mkIvyConfiguration) - lazy val log = Logger.Null - def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String]): IvySbt#Module = { + lazy val log = ConsoleLogger() + def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String], + uo: UpdateOptions = UpdateOptions()): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => new IvyScala( scalaFullVersion = fv, @@ -28,10 +30,11 @@ trait BaseIvySpecification extends Specification { dependencies = deps, configurations = Seq(Compile, Test, Runtime), ivyScala = ivyScala) + val ivySbt = new IvySbt(mkIvyConfiguration(uo)) new ivySbt.Module(moduleSetting) } - def mkIvyConfiguration: IvyConfiguration = { + def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = new IvyPaths(currentBase, Some(currentTarget)) val rs = Seq(DefaultMavenRepository) val other = Nil @@ -39,13 +42,20 @@ trait BaseIvySpecification extends Specification { val off = false val check = Nil val resCacheDir = currentTarget / "resolution-cache" - val uo = UpdateOptions() new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) } - def ivyUpdate(module: IvySbt#Module) = { + def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val config = new UpdateConfiguration(None, false, UpdateLogging.Full) - IvyActions.update(module, config, log) + val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern) + val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full) + IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } + + def ivyUpdate(module: IvySbt#Module) = + ivyUpdateEither(module) match { + case Right(r) => r + case Left(w) => + throw w.resolveException + } } diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala new file mode 100644 index 000000000..8ac88740e --- /dev/null +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -0,0 +1,51 @@ +package sbt + +import org.specs2._ + +class CachedResolutionSpec extends BaseIvySpecification { + def is = args(sequential = true) ^ s2""" + + This is a specification to check the cached resolution + + Resolving the same module twice should + work $e1 + + Resolving the unsolvable module should + not work $e2 + """ + + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) + def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile")) + + def defaultOptions = EvictionWarningOptions.default + + import ShowLines._ + + def e1 = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + val report = ivyUpdate(m) + val report2 = ivyUpdate(m) + println(report) + println(report.configurations.head.modules.head.artifacts) + report.configurations.size must_== 3 + } + + def e2 = { + log.setLevel(Level.Debug) + val m = module(ModuleID("com.example", "foo", "0.2.0", Some("compile")), Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + ivyUpdateEither(m) match { + case Right(_) => sys.error("this should've failed") + case Left(uw) => + println(uw.lines.mkString("\n")) + } + ivyUpdateEither(m) match { + case Right(_) => sys.error("this should've failed 2") + case Left(uw) => + uw.lines must contain(allOf("\n\tNote: Unresolved dependencies path:", + "\t\tfoundrylogic.vpp:vpp:2.2.1", + "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", + "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", + "\t\t +- com.example:foo:0.2.0")) + } + } +} From 04499b98ffe18f0f32b7db10538390ce86027d6c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 30 Sep 2014 17:30:51 -0400 Subject: [PATCH 0345/1030] spawn new instance of Ivy during minigraph resolution --- ivy/src/main/scala/sbt/Ivy.scala | 1 + .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index db8d8ed1e..2ea187a23 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -98,6 +98,7 @@ final class IvySbt(val configuration: IvyConfiguration) { setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine { val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache val projectResolver = prOpt + def makeInstance = mkIvy }) } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) super.bind() diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 9db9343bb..466f38ca3 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -6,6 +6,7 @@ import java.net.URL import java.io.File import collection.concurrent import collection.immutable.ListMap +import org.apache.ivy.Ivy import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } @@ -260,6 +261,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache private[sbt] def projectResolver: Option[ProjectResolver] + private[sbt] def makeInstance: Ivy // Return sbt's UpdateReport. def customResolve(md0: ModuleDescriptor, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { @@ -271,7 +273,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) - var rr = super.resolve(md, options1) + val i = makeInstance + var rr = i.resolve(md, options1) if (!rr.hasError) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) else { val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct From 428f2a370644a9c8817561c7f4fe4c6a4719f6d8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 30 Sep 2014 17:44:56 -0400 Subject: [PATCH 0346/1030] split up json persistence into JsonUtil.scala --- ivy/src/main/scala/sbt/JsonUtil.scala | 110 ++++++++++++++++++ .../CachedResolutionResolveEngine.scala | 110 +----------------- 2 files changed, 116 insertions(+), 104 deletions(-) create mode 100644 ivy/src/main/scala/sbt/JsonUtil.scala diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala new file mode 100644 index 000000000..ba843aec1 --- /dev/null +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -0,0 +1,110 @@ +package sbt + +import java.io.File +import java.net.URL +import org.json4s._ +import org.apache.ivy.core +import core.module.descriptor.ModuleDescriptor + +private[sbt] object JsonUtil { + def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = + { + import org.json4s._ + implicit val formats = native.Serialization.formats(NoTypeHints) + + new ConfigurationSerializer + + new ArtifactSerializer + + new FileSerializer + try { + val json = jawn.support.json4s.Parser.parseFromFile(path) + fromLite(json.get.extract[UpdateReportLite], cachedDescriptor) + } catch { + case e: Throwable => + log.error("Unable to parse mini graph: " + path.toString) + throw e + } + } + def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = + { + implicit val formats = native.Serialization.formats(NoTypeHints) + + new ConfigurationSerializer + + new ArtifactSerializer + + new FileSerializer + import native.Serialization.write + val str = write(toLite(ur)) + IO.write(graphPath, str, IO.utf8) + } + def toLite(ur: UpdateReport): UpdateReportLite = + UpdateReportLite(ur.configurations map { cr => + ConfigurationReportLite(cr.configuration, cr.details) + }) + def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = + { + val stats = new UpdateStats(0L, 0L, 0L, false) + val configReports = lite.configurations map { cr => + val details = cr.details + val modules = details flatMap { + _.modules filter { mr => + !mr.evicted && mr.problem.isEmpty + } + } + val evicted = details flatMap { + _.modules filter { mr => + mr.evicted + } + } map { _.module } + new ConfigurationReport(cr.configuration, modules, details, evicted) + } + new UpdateReport(cachedDescriptor, configReports, stats) + } +} + +private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) +private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) + +private[sbt] class FileSerializer extends CustomSerializer[File](format => ( + { + case JString(s) => new File(s) + }, + { + case x: File => JString(x.toString) + } +)) + +private[sbt] class ConfigurationSerializer extends CustomSerializer[Configuration](format => ( + { + case JString(s) => new Configuration(s) + }, + { + case x: Configuration => JString(x.name) + } +)) + +private[sbt] class ArtifactSerializer extends CustomSerializer[Artifact](format => ( + { + case json: JValue => + implicit val fmt = format + Artifact( + (json \ "name").extract[String], + (json \ "type").extract[String], + (json \ "extension").extract[String], + (json \ "classifier").extract[Option[String]], + (json \ "configurations").extract[List[Configuration]], + (json \ "url").extract[Option[URL]], + (json \ "extraAttributes").extract[Map[String, String]] + ) + }, + { + case x: Artifact => + import DefaultJsonFormats.{ OptionWriter, StringWriter, mapWriter } + val optStr = implicitly[Writer[Option[String]]] + val mw = implicitly[Writer[Map[String, String]]] + JObject(JField("name", JString(x.name)) :: + JField("type", JString(x.`type`)) :: + JField("extension", JString(x.extension)) :: + JField("classifier", optStr.write(x.classifier)) :: + JField("configurations", JArray(x.configurations.toList map { x => JString(x.name) })) :: + JField("url", optStr.write(x.url map { _.toString })) :: + JField("extraAttributes", mw.write(x.extraAttributes)) :: + Nil) + } +)) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 466f38ca3..e2c71a877 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -15,7 +15,6 @@ import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, Depen import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } -import org.json4s._ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -39,7 +38,6 @@ class CachedResolutionResolveCache() { else buildArtificialModuleDescriptors(md0, prOpt) map { _._1 } mds foreach { md => updateReportCache.remove(md.getModuleRevisionId) - // todo: backport this directDependencyCache.remove(md.getModuleRevisionId) } } @@ -98,7 +96,7 @@ class CachedResolutionResolveCache() { else if (dynamicGraphPath.exists) Some(dynamicGraphPath) else None) map { path => log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = parseUpdateReport(md, path, cachedDescriptor, log) + val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) updateReportCache(md.getModuleRevisionId) = Right(ur) Right(ur) } @@ -115,9 +113,10 @@ class CachedResolutionResolveCache() { } }) IO.createDirectory(miniGraphPath) - writeUpdateReport(ur, - if (changing) dynamicGraphPath - else staticGraphPath) + val gp = if (changing) dynamicGraphPath + else staticGraphPath + log.debug(s"saving minigraph to $gp") + JsonUtil.writeUpdateReport(ur, gp) // don't cache dynamic graphs in memory. if (!changing) { updateReportCache(md.getModuleRevisionId) = Right(ur) @@ -131,56 +130,7 @@ class CachedResolutionResolveCache() { } } } - def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = - { - import org.json4s._ - implicit val formats = native.Serialization.formats(NoTypeHints) + - new ConfigurationSerializer + - new ArtifactSerializer + - new FileSerializer - try { - val json = jawn.support.json4s.Parser.parseFromFile(path) - fromLite(json.get.extract[UpdateReportLite], cachedDescriptor) - } catch { - case e: Throwable => - log.error("Unable to parse mini graph: " + path.toString) - throw e - } - } - def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = - { - implicit val formats = native.Serialization.formats(NoTypeHints) + - new ConfigurationSerializer + - new ArtifactSerializer + - new FileSerializer - import native.Serialization.write - println(graphPath.toString) - val str = write(toLite(ur)) - IO.write(graphPath, str, IO.utf8) - } - def toLite(ur: UpdateReport): UpdateReportLite = - UpdateReportLite(ur.configurations map { cr => - ConfigurationReportLite(cr.configuration, cr.details) - }) - def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = - { - val stats = new UpdateStats(0L, 0L, 0L, false) - val configReports = lite.configurations map { cr => - val details = cr.details - val modules = details flatMap { - _.modules filter { mr => - !mr.evicted && mr.problem.isEmpty - } - } - val evicted = details flatMap { - _.modules filter { mr => - mr.evicted - } - } map { _.module } - new ConfigurationReport(cr.configuration, modules, details, evicted) - } - new UpdateReport(cachedDescriptor, configReports, stats) - } + def getOrElseUpdateConflict(cf0: ModuleID, cf1: ModuleID, conflicts: Vector[ModuleReport])(f: => (Vector[ModuleReport], Vector[ModuleReport], String)): (Vector[ModuleReport], Vector[ModuleReport]) = { def reconstructReports(surviving: Vector[ModuleID], evicted: Vector[ModuleID], mgr: String): (Vector[ModuleReport], Vector[ModuleReport]) = { @@ -202,60 +152,12 @@ class CachedResolutionResolveCache() { } } } - class FileSerializer extends CustomSerializer[File](format => ( - { - case JString(s) => new File(s) - }, - { - case x: File => JString(x.toString) - } - )) - class ConfigurationSerializer extends CustomSerializer[Configuration](format => ( - { - case JString(s) => new Configuration(s) - }, - { - case x: Configuration => JString(x.name) - } - )) - class ArtifactSerializer extends CustomSerializer[Artifact](format => ( - { - case json: JValue => - implicit val fmt = format - Artifact( - (json \ "name").extract[String], - (json \ "type").extract[String], - (json \ "extension").extract[String], - (json \ "classifier").extract[Option[String]], - (json \ "configurations").extract[List[Configuration]], - (json \ "url").extract[Option[URL]], - (json \ "extraAttributes").extract[Map[String, String]] - ) - }, - { - case x: Artifact => - import DefaultJsonFormats.{ OptionWriter, StringWriter, mapWriter } - val optStr = implicitly[Writer[Option[String]]] - val mw = implicitly[Writer[Map[String, String]]] - JObject(JField("name", JString(x.name)) :: - JField("type", JString(x.`type`)) :: - JField("extension", JString(x.extension)) :: - JField("classifier", optStr.write(x.classifier)) :: - JField("configurations", JArray(x.configurations.toList map { x => JString(x.name) })) :: - JField("url", optStr.write(x.url map { _.toString })) :: - JField("extraAttributes", mw.write(x.extraAttributes)) :: - Nil) - } - )) } private[sbt] trait ArtificialModuleDescriptor { self: DefaultModuleDescriptor => def targetModuleRevisionId: ModuleRevisionId } -private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) -private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) - private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { import CachedResolutionResolveCache._ From 024a99ed074461e31ce797754ab2b09f9353ceb8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 30 Sep 2014 17:48:17 -0400 Subject: [PATCH 0347/1030] update deprecation message --- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 0d12d5b06..f5e57336d 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -140,7 +140,7 @@ object IvyActions { * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - @deprecated("Use updateEither instead.", "0.13.6") + @deprecated("This is no longer public.", "0.13.6") def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = updateEither(module, configuration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { case Right(r) => r From e58a236c9ea5f1fe00a9a4050535228d1f803c8e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 30 Sep 2014 18:19:46 -0400 Subject: [PATCH 0348/1030] some more minor changes --- ivy/src/main/scala/sbt/Ivy.scala | 2 ++ .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 6 ++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 2ea187a23..4bf6ffad6 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -273,6 +273,8 @@ private[sbt] object IvySbt { val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } + private[sbt] def isChanging(dd: DependencyDescriptor): Boolean = + dd.isChanging || isChanging(dd.getDependencyRevisionId) private[sbt] def isChanging(module: ModuleID): Boolean = module.revision endsWith "-SNAPSHOT" private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean = diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index e2c71a877..4b6cd3e9e 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -22,7 +22,7 @@ private[sbt] object CachedResolutionResolveCache { def sbtOrgTemp = "org.scala-sbt.temp" } -class CachedResolutionResolveCache() { +private[sbt] class CachedResolutionResolveCache() { import CachedResolutionResolveCache._ val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() @@ -57,8 +57,6 @@ class CachedResolutionResolveCache() { val rootModuleConfigs = md0.getConfigurations.toVector expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, prOpt) } } - def isDependencyChanging(dd: DependencyDescriptor): Boolean = - dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId) def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = { val mrid = dd.getDependencyRevisionId @@ -74,7 +72,7 @@ class CachedResolutionResolveCache() { conf <- rootModuleConfigs } yield md1.addConfiguration(conf) md1.addDependency(dd) - (md1, isDependencyChanging(dd)) + (md1, IvySbt.isChanging(dd)) } def getOrElseUpdateMiniGraph(md: ModuleDescriptor, changing0: Boolean, logicalClock: LogicalClock, miniGraphPath: File, cachedDescriptor: File, log: Logger)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = { From b9dc9f8f4f3eb65f324772d9541df85f51684f3d Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 1 Oct 2014 08:04:39 -0400 Subject: [PATCH 0349/1030] Fix regression where IOExceptions were not caught on trying to access disk. Fixes #1632 --- ivy/src/main/scala/sbt/Resolver.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 01db05ea1..7f558181d 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -3,7 +3,7 @@ */ package sbt -import java.io.File +import java.io.{ IOException, File } import java.net.URL import scala.xml.{ Text, NodeSeq, Elem, XML } import org.apache.ivy.plugins.resolver.DependencyResolver @@ -312,6 +312,8 @@ object Resolver { } catch { // Occurs inside File constructor when property or environment variable does not exist case _: NullPointerException => None + // Occurs when File does not exist + case _: IOException => None case e: SAXParseException => System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); None } loadHomeFromSettings(() => new File(Path.userHome, ".m2/settings.xml")) orElse From c84a5e70c73867ece97c1506acdbb45c82ee3c97 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 1 Oct 2014 08:18:09 -0400 Subject: [PATCH 0350/1030] Add file existence check for Eugene. --- ivy/src/main/scala/sbt/Resolver.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 7f558181d..57a73dec2 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -304,11 +304,12 @@ object Resolver { private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { - val file = XML.loadFile(f()) - (file \ "localRepository").text match { + val file = f() + if(!file.exists) None + else ((XML.loadFile(file) \ "localRepository").text match { case "" => None case e @ _ => Some(new File(e)) - } + }) } catch { // Occurs inside File constructor when property or environment variable does not exist case _: NullPointerException => None From 83cd45d6f15e72e43bea6456ea46b7889fc5df3b Mon Sep 17 00:00:00 2001 From: Jean-Remi Desjardins Date: Mon, 15 Sep 2014 22:38:44 -0700 Subject: [PATCH 0351/1030] Change additional constructor to what it should probably be I am at a total loss for why this is not compiling. --- ivy/src/main/scala/sbt/IvyInterface.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index c5d4db1ea..b42ba89c4 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -11,8 +11,8 @@ import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { - def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) = - this(nameFormal = nameFormal, description = description, homepage = homepage, startYear = startYear, licenses = licenses, organizationName = organizationName, organizationHomepage = organizationHomepage, scmInfo = scmInfo, developers = Seq()) + def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) = + this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq()) def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) def licensed(lics: (String, URL)*) = copy(licenses = lics) @@ -43,4 +43,4 @@ object ConflictManager { val latestCompatible = ConflictManager("latest-compatible") val strict = ConflictManager("strict") val default = latestRevision -} \ No newline at end of file +} From 9c447246f6b078d3b5eb0a30bd4e25664ba61e5c Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 26 Sep 2014 13:26:48 -0400 Subject: [PATCH 0352/1030] Remove binary compatibility breakages and migrate new parser features into an internal package. --- ivy/src/main/scala/sbt/IvyInterface.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index b42ba89c4..e4c2e8e46 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -11,7 +11,7 @@ import org.apache.ivy.util.url.CredentialsStore /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { - def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) = + def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) = this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq()) def formally(name: String) = copy(nameFormal = name) def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) From 7547a70991386c859e6022572c5121edc2a3956c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 5 Oct 2014 04:24:22 -0400 Subject: [PATCH 0353/1030] Fixed json serialization turning license into {}. --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 3 ++- ivy/src/main/scala/sbt/Resolver.scala | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index bb15c68df..1e74f3955 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -128,7 +128,8 @@ object IvyRetrieve { val licenses: Seq[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toArray.toVector collect { case lic: IvyLicense if Option(lic.getName).isDefined => - (lic.getName, nonEmptyString(lic.getUrl)) + val temporaryURL = "http://localhost" + (lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) }) } case _ => Nil } diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 57a73dec2..c7e67f876 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -305,7 +305,7 @@ object Resolver { def loadHomeFromSettings(f: () => File): Option[File] = try { val file = f() - if(!file.exists) None + if (!file.exists) None else ((XML.loadFile(file) \ "localRepository").text match { case "" => None case e @ _ => Some(new File(e)) From c2b4c0ec9435efecc71cc5dbe128be319d04ed41 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 8 Oct 2014 17:14:06 -0400 Subject: [PATCH 0354/1030] Fixes #1649. Adds exclusion rules into SHA-1 of minigraph path --- .../CachedResolutionResolveEngine.scala | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 4b6cd3e9e..3ee26964e 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -11,7 +11,7 @@ import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } -import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration } +import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } @@ -59,11 +59,28 @@ private[sbt] class CachedResolutionResolveCache() { } def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = { + def excludeRuleString(rule: ExcludeRule): String = + s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" + def includeRuleString(rule: IncludeRule): String = + s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" }) - val depsString = mrid.toString + ";" + confMap.mkString(";") + val exclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getExcludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map excludeRuleString).mkString(",") + ")") + } + }) + val inclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getIncludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") + } + }) + val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};""" val sha1 = Hash.toHex(Hash(depsString)) val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { def targetModuleRevisionId: ModuleRevisionId = mrid From 832bf601b5a3ed7e55e61a31a96f8996da96fe15 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 Oct 2014 13:11:13 -0400 Subject: [PATCH 0355/1030] Fixes #1639. Fixes cached resolution interacting with force() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When conflicts are found for a given module, a forced one is selected before conflict manager kicks in. The problem is that DependencyDescriptor seems to mark transitive forced dependency as forced as well, so the actual forced dependency are sometimes not prioritized. To work around this, I’ve introduced a mixin called SbtDefaultDependencyDescriptor, which carries around ModuleID to detect direct dependencies. --- ivy/src/main/scala/sbt/Ivy.scala | 6 ++++-- ivy/src/main/scala/sbt/IvyRetrieve.scala | 12 ++++++++---- ivy/src/main/scala/sbt/UpdateReport.scala | 3 ++- .../sbt/ivyint/CachedResolutionResolveEngine.scala | 11 +++++++++-- .../sbt/ivyint/SbtDefaultDependencyDescriptor.scala | 9 +++++++++ 5 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 4bf6ffad6..c0e7d508a 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -4,7 +4,7 @@ package sbt import Resolver.PluginPattern -import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache } +import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } import java.io.File import java.net.URI @@ -570,7 +570,9 @@ private[sbt] object IvySbt { /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ def convertDependency(moduleID: DefaultModuleDescriptor, dependency: ModuleID, parser: CustomXmlParser.CustomParser): DefaultDependencyDescriptor = { - val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) + val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) with SbtDefaultDependencyDescriptor { + def dependencyModuleId = dependency + } dependency.configurations match { case None => // The configuration for this dependency was not explicitly specified, so use the default parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index 1e74f3955..f453efb1f 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -13,6 +13,7 @@ import module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveReport } import resolve.{ IvyNode, IvyNodeCallers } import IvyNodeCallers.{ Caller => IvyCaller } +import ivyint.SbtDefaultDependencyDescriptor object IvyRetrieve { def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = @@ -77,11 +78,14 @@ object IvyRetrieve { case x if nonEmptyString(x).isDefined => x } val ddOpt = Option(caller.getDependencyDescriptor) - val (extraAttributes, isForce, isChanging, isTransitive) = ddOpt match { - case Some(dd) => (toExtraAttributes(dd.getExtraAttributes), dd.isForce, dd.isChanging, dd.isTransitive) - case None => (Map.empty[String, String], false, false, true) + val (extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) = ddOpt match { + case Some(dd: SbtDefaultDependencyDescriptor) => + val mod = dd.dependencyModuleId + (toExtraAttributes(dd.getExtraAttributes), mod.isForce, mod.isChanging, mod.isTransitive, mod.isForce) + case Some(dd) => (toExtraAttributes(dd.getExtraAttributes), dd.isForce, dd.isChanging, dd.isTransitive, false) + case None => (Map.empty[String, String], false, false, true, false) } - new Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive) + new Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) } val revId = dep.getResolvedId val moduleId = toModuleID(revId) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 443c84ed3..696fa4d20 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -190,7 +190,8 @@ final class Caller( val callerExtraAttributes: Map[String, String], val isForceDependency: Boolean, val isChangingDependency: Boolean, - val isTransitiveDependency: Boolean) { + val isTransitiveDependency: Boolean, + val isDirectlyForceDependency: Boolean) { override def toString: String = s"$caller" } diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 3ee26964e..850f1b61d 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -36,6 +36,9 @@ private[sbt] class CachedResolutionResolveCache() { val mds = if (mrid0.getOrganisation == sbtOrgTemp) Vector(md0) else buildArtificialModuleDescriptors(md0, prOpt) map { _._1 } + + updateReportCache.remove(md0.getModuleRevisionId) + directDependencyCache.remove(md0.getModuleRevisionId) mds foreach { md => updateReportCache.remove(md.getModuleRevisionId) directDependencyCache.remove(md.getModuleRevisionId) @@ -186,6 +189,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val miniGraphPath = depDir / "module" val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val cache = cachedResolutionResolveCache + cache.directDependencyCache.remove(md0.getModuleRevisionId) val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver) def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { @@ -292,10 +296,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val name = head.module.name log.debug(s"- conflict in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")")) def useLatest(lcm: LatestConflictManager): (Vector[ModuleReport], Vector[ModuleReport], String) = - conflicts find { m => + (conflicts find { m => + m.callers.exists { _.isDirectlyForceDependency } + } orElse (conflicts find { m => m.callers.exists { _.isForceDependency } - } match { + })) match { case Some(m) => + log.debug(s"- forced dependency: $m") (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) case None => val strategy = lcm.getStrategy diff --git a/ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala b/ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala new file mode 100644 index 000000000..0a3338fac --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala @@ -0,0 +1,9 @@ +package sbt +package ivyint + +import org.apache.ivy.core +import core.module.descriptor.DefaultDependencyDescriptor + +trait SbtDefaultDependencyDescriptor { self: DefaultDependencyDescriptor => + def dependencyModuleId: ModuleID +} From 1de783aec6203a576b55ee0a6a07a9c1cf592507 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 00:34:05 -0400 Subject: [PATCH 0356/1030] Fixes #1660 Provide overloads for transitiveScratch and updateClassifiers that work with IvyActions.updateEither. --- ivy/src/main/scala/sbt/IvyActions.scala | 24 ++++++++++++++++++++--- ivy/src/main/scala/sbt/LogicalClock.scala | 5 +++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index f5e57336d..d52bf23d6 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -198,17 +198,31 @@ object IvyActions { def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = mods groupBy (grouping) mapValues (_.map(_.revision).toSet) + @deprecated("This is no longer public.", "0.13.6") def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = + transitiveScratch(ivySbt, label, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) + + private[sbt] def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): UpdateReport = { import config.{ configuration => c, ivyScala, module => mod } import mod.{ id, modules => deps } val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) - val report = update(module, c, log) + val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { + case Right(r) => r + case Left(w) => + throw w.resolveException + } val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, log) + updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, log) } + @deprecated("This is no longer public.", "0.13.6") def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = + updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) + + private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): UpdateReport = { import config.{ configuration => c, module => mod, _ } import mod.{ configurations => confs, _ } @@ -218,7 +232,11 @@ object IvyActions { val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) - update(module, upConf, log) + updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { + case Right(r) => r + case Left(w) => + throw w.resolveException + } } def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { diff --git a/ivy/src/main/scala/sbt/LogicalClock.scala b/ivy/src/main/scala/sbt/LogicalClock.scala index 1056f6560..d4e1d4cc3 100644 --- a/ivy/src/main/scala/sbt/LogicalClock.scala +++ b/ivy/src/main/scala/sbt/LogicalClock.scala @@ -9,6 +9,11 @@ trait LogicalClock { } object LogicalClock { + def apply(hashCode: Int): LogicalClock = { + def intToByteArray(x: Int): Array[Byte] = + Array((x >>> 24).toByte, (x >> 16 & 0xff).toByte, (x >> 8 & 0xff).toByte, (x & 0xff).toByte) + apply(Hash.toHex(intToByteArray(hashCode))) + } def apply(x: String): LogicalClock = new LogicalClock { override def toString: String = x } From dc2f6e5c559cf794cf28109b1ad3917637287612 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 03:20:12 -0400 Subject: [PATCH 0357/1030] Make sure IvyAction.update works --- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index d52bf23d6..41850b247 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -155,7 +155,7 @@ object IvyActions { private[sbt] def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): Either[UnresolvedWarning, UpdateReport] = module.withModule(log) { - case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution => + case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined => ivy.getResolveEngine match { case x: CachedResolutionResolveEngine => val resolveOptions = new ResolveOptions From 61d7b7e426c3f58225a0417d389d64177003e40d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 06:40:56 -0400 Subject: [PATCH 0358/1030] Use correct stats for cached resolution --- ivy/src/main/scala/sbt/UpdateReport.scala | 11 +++++++++++ .../ivyint/CachedResolutionResolveEngine.scala | 18 ++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 696fa4d20..03ee2fe31 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -34,6 +34,12 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ def allConfigurations: Seq[String] = configurations.map(_.configuration) + + private[sbt] def withStats(us: UpdateStats): UpdateReport = + new UpdateReport(this.cachedDescriptor, + this.configurations, + us, + this.stamps) } /** @@ -268,4 +274,9 @@ object UpdateReport { } final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") + private[sbt] def withCached(c: Boolean): UpdateStats = + new UpdateStats(resolveTime = this.resolveTime, + downloadTime = this.downloadTime, + downloadSize = this.downloadSize, + cached = c) } \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 850f1b61d..e57499737 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -119,7 +119,11 @@ private[sbt] class CachedResolutionResolveCache() { Right(ur) } (updateReportCache.get(mrid) orElse loadMiniGraphFromFile) match { - case Some(result) => result + case Some(result) => + result match { + case Right(ur) => Right(ur.withStats(ur.stats.withCached(true))) + case x => x + } case None => f match { case Right(ur) => @@ -186,6 +190,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // Return sbt's UpdateReport. def customResolve(md0: ModuleDescriptor, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { import Path._ + val start = System.currentTimeMillis val miniGraphPath = depDir / "module" val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val cache = cachedResolutionResolveCache @@ -217,7 +222,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { doWork(md) } } - val uReport = mergeResults(md0, results, log) + val uReport = mergeResults(md0, results, System.currentTimeMillis - start, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0) val prop0 = "" @@ -225,9 +230,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { IO.write(ivyPropertiesInCache0, prop0) uReport } - def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], log: Logger): Either[ResolveException, UpdateReport] = + def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], resolveTime: Long, log: Logger): Either[ResolveException, UpdateReport] = if (results exists { _.isLeft }) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) - else Right(mergeReports(md0, results collect { case Right(ur) => ur }, log)) + else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException], log: Logger): ResolveException = { val messages = errors flatMap { _.messages } @@ -241,11 +246,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } new ResolveException(messages, failed, ListMap(failedPaths: _*)) } - def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], log: Logger): UpdateReport = + def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], resolveTime: Long, log: Logger): UpdateReport = { val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val rootModuleConfigs = md0.getConfigurations.toVector - val stats = new UpdateStats(0L, 0L, 0L, false) + val cachedReports = reports filter { !_.stats.cached } + val stats = new UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) val configReports = rootModuleConfigs map { conf => val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } mergeConfigurationReports(conf.getName, crs, log) From 4ef1c5b4f3e4b26638c620bfedee7534216ca673 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 06:50:36 -0400 Subject: [PATCH 0359/1030] Make sure all files exist in minigraph. --- .../ivyint/CachedResolutionResolveEngine.scala | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index e57499737..e7ef58b42 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -112,11 +112,19 @@ private[sbt] class CachedResolutionResolveCache() { def loadMiniGraphFromFile: Option[Either[ResolveException, UpdateReport]] = (if (staticGraphPath.exists) Some(staticGraphPath) else if (dynamicGraphPath.exists) Some(dynamicGraphPath) - else None) map { path => - log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) - updateReportCache(md.getModuleRevisionId) = Right(ur) - Right(ur) + else None) match { + case Some(path) => + log.debug(s"parsing ${path.getAbsolutePath.toString}") + val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) + if (ur.allFiles forall { _.exists }) { + updateReportCache(md.getModuleRevisionId) = Right(ur) + Some(Right(ur)) + } else { + log.debug(s"some files are missing from the cache, so invalidating the minigraph") + IO.delete(path) + None + } + case _ => None } (updateReportCache.get(mrid) orElse loadMiniGraphFromFile) match { case Some(result) => From cf4e882ac9a8bc240b12418c48b252d850692b51 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 15:42:26 -0400 Subject: [PATCH 0360/1030] enable -deprecation for Scala 2.10 Enable -deprecation flag to catch old code being use when we migrate things. In this commit I moved error to sys.error. --- ivy/src/main/scala/sbt/Credentials.scala | 2 +- ivy/src/main/scala/sbt/EvictionWarning.scala | 2 +- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- ivy/src/main/scala/sbt/UpdateReport.scala | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/Credentials.scala b/ivy/src/main/scala/sbt/Credentials.scala index fd6a85538..464d5de8e 100644 --- a/ivy/src/main/scala/sbt/Credentials.scala +++ b/ivy/src/main/scala/sbt/Credentials.scala @@ -27,7 +27,7 @@ object Credentials { def toDirect(c: Credentials): DirectCredentials = c match { case dc: DirectCredentials => dc case fc: FileCredentials => loadCredentials(fc.path) match { - case Left(err) => error(err) + case Left(err) => sys.error(err) case Right(dc) => dc } } diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index c40860081..25ad9014b 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -155,7 +155,7 @@ object EvictionWarning { val transitiveEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => - options.guessCompatible(r.module, p.winner map { _.module }, module.moduleSettings.ivyScala) + options.guessCompatible((r.module, p.winner map { _.module }, module.moduleSettings.ivyScala)) } pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index f5e57336d..c1e8bccf4 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -313,7 +313,7 @@ object IvyActions { private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) { val missing = artifacts filter { case (a, file) => !file.exists } if (missing.nonEmpty) - error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) + sys.error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) } } final class ResolveException( diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 443c84ed3..dbd913620 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -220,7 +220,7 @@ object UpdateReport { private[this] def select0(f: DependencyFilter): Seq[File] = for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { - if (file == null) error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) + if (file == null) sys.error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) file } From 68b3f8d5ed98c3d11e62ceaca51e06954f6c46ce Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Oct 2014 17:25:43 -0400 Subject: [PATCH 0361/1030] Implement configuration.missingOk to fix updateClassifiers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updateClassifiers sets missingOk to true. cached resolution wasn’t respecting the looseness. --- ivy/src/main/scala/sbt/IvyActions.scala | 2 +- .../ivyint/CachedResolutionResolveEngine.scala | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 41850b247..7dd07df7d 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -161,7 +161,7 @@ object IvyActions { val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(md) resolveOptions.setResolveId(resolveId) - x.customResolve(md, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { + x.customResolve(md, configuration.missingOk, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { case Left(x) => Left(UnresolvedWarning(x, uwconfig)) case Right(uReport) => diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index e7ef58b42..09da3b501 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -195,8 +195,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def projectResolver: Option[ProjectResolver] private[sbt] def makeInstance: Ivy - // Return sbt's UpdateReport. - def customResolve(md0: ModuleDescriptor, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { + /** + * This returns sbt's UpdateReport structure. + * missingOk allows sbt to call this with classifiers that may or may not exist, and grab the JARs. + */ + def customResolve(md0: ModuleDescriptor, missingOk: Boolean, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { import Path._ val start = System.currentTimeMillis val miniGraphPath = depDir / "module" @@ -209,7 +212,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val options1 = new ResolveOptions(options0) val i = makeInstance var rr = i.resolve(md, options1) - if (!rr.hasError) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) + if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) else { val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => @@ -230,7 +233,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { doWork(md) } } - val uReport = mergeResults(md0, results, System.currentTimeMillis - start, log) + val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0) val prop0 = "" @@ -238,8 +241,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { IO.write(ivyPropertiesInCache0, prop0) uReport } - def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], resolveTime: Long, log: Logger): Either[ResolveException, UpdateReport] = - if (results exists { _.isLeft }) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) + def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], missingOk: Boolean, resolveTime: Long, log: Logger): Either[ResolveException, UpdateReport] = + if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException], log: Logger): ResolveException = { From 2d3bb4ca7536c56df3d6e97ae84ba6e8b8e6cf68 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 18 Oct 2014 07:15:52 -0400 Subject: [PATCH 0362/1030] Fixes #1677. Provide URLSerializer. Without this json4s is unable to parse URLs. --- ivy/src/main/scala/sbt/JsonUtil.scala | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index ba843aec1..c1e03d1d5 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -13,7 +13,8 @@ private[sbt] object JsonUtil { implicit val formats = native.Serialization.formats(NoTypeHints) + new ConfigurationSerializer + new ArtifactSerializer + - new FileSerializer + new FileSerializer + + new URLSerializer try { val json = jawn.support.json4s.Parser.parseFromFile(path) fromLite(json.get.extract[UpdateReportLite], cachedDescriptor) @@ -61,6 +62,15 @@ private[sbt] object JsonUtil { private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) +private[sbt] class URLSerializer extends CustomSerializer[URL](format => ( + { + case JString(s) => new URL(s) + }, + { + case x: URL => JString(x.toString) + } +)) + private[sbt] class FileSerializer extends CustomSerializer[File](format => ( { case JString(s) => new File(s) From 1a38b6902e131b12c3921fa1d35e37ea3d507d16 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 20 Oct 2014 12:26:40 -0400 Subject: [PATCH 0363/1030] Revert chain resolver by default, for older behavior. The issue comes into play where we cannot accurately get a publication date from Maven artifacts, leading to the current mechanism having undefined behavior and causing other bugs to pop up in resolution. --- ivy/src/main/scala/sbt/UpdateOptions.scala | 2 +- .../scala/sbt/ivyint/SbtChainResolver.scala | 72 +++++++++++-------- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index 1d8ad1aec..2f7ad26ec 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -46,7 +46,7 @@ object UpdateOptions { def apply(): UpdateOptions = new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, - latestSnapshots = true, + latestSnapshots = false, consolidatedResolution = false, cachedResolution = false) } diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index bd748527e..46bb35f60 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -57,12 +57,20 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting // and if a previously resolved or cached revision has been found. def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { + // useLatest - Means we should always download the JARs from the internet, no matter what. + // This will only be true *IF* the depenendency is dynamic/changing *and* latestSnapshots is true. + // If you find multiple candidates, + // - If `isReturnFirst` is true, you return the first value found + // - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and + // leads to undefined behavior. val useLatest = (dd.isChanging || (IvySbt.isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots if (useLatest) { Message.verbose(s"${getName} is changing. Checking all resolvers on the chain") } val data = new ResolveData(data0, doValidate(data0)) + // Returns the value if we've already been resolved from some other branch of the resolution tree. val resolved = Option(data.getCurrentResolvedModuleRevision) + // If we don't have any previously resolved date, we try to pull the value from the cache. val resolvedOrCached = resolved orElse { Message.verbose(getName + ": Checking cache for: " + dd) @@ -71,50 +79,41 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting forcedRevision(mr) } } + + // Default value for resolution. We use this while we loop... + // If useLatest is true, we want to try to download from the internet so we DO NOT start with a valid value. var temp: Option[ResolvedModuleRevision] = if (useLatest) None else resolvedOrCached + // Cast resolvers to something useful. TODO - we dropping anything here? val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + + // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. + // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything + // - If we do not, try to resolve. + // RETURNS: Left -> Error + // Right -> Some(resolved module) // Found in this resolver, can use this result. + // Right -> None // Do not use this resolver val results = resolvers map { x => - // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers + // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. if (isReturnFirst && temp.isDefined && !useLatest) Right(None) else { + // We actually do resolution. val resolver = x val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) try { val previouslyResolved = temp // if the module qualifies as changing, then resolve all resolvers - if (useLatest) data.setCurrentResolvedModuleRevision(None.orNull) + if (useLatest) data.setCurrentResolvedModuleRevision(null) else data.setCurrentResolvedModuleRevision(temp.orNull) temp = Option(resolver.getDependency(dd, data)) - val retval = Right( + Right( if (temp eq previouslyResolved) None else if (useLatest) temp map { x => (reparseModuleDescriptor(dd, data, resolver, x), resolver) } else temp map { x => (forcedRevision(x), resolver) } ) - retval match { - case Right(Some((rmr, _))) => - rmr.getDescriptor.getPublicationDate match { - case null => - (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { - case (null, _) => - // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file - if (dd.isChanging) - Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") - case (ivf, dmd: DefaultModuleDescriptor) => - val lmd = new java.util.Date(ivf.getLastModified) - Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") - dmd.setPublicationDate(lmd) - case _ => - Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") - } - case _ => // All other cases ok - } - case _ => - } - retval } catch { case ex: Exception => Message.verbose("problem occurred while resolving " + dd + " with " + resolver @@ -130,7 +129,24 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } val sorted = if (useLatest) (foundRevisions.sortBy { - case (rmr, _) => + case (rmr, resolver) => + // Just issue warning about issues with publication date, and fake one on it for now. + rmr.getDescriptor.getPublicationDate match { + case null => + (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { + case (null, _) => + // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file + if (dd.isChanging) + Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + case (ivf, dmd: DefaultModuleDescriptor) => + val lmd = new java.util.Date(ivf.getLastModified) + Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + dmd.setPublicationDate(lmd) + case _ => + Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + } + case _ => // All other cases ok + } rmr.getDescriptor.getPublicationDate match { case null => 0L case d => d.getTime @@ -141,8 +157,7 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { case None if resolver.getName == "inter-project" => // do nothing - case None => throw new RuntimeException("\t" + resolver.getName - + ": no ivy file nor artifact found for " + rmr) + case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") case Some(artifactRef) => val systemMd = toSystem(rmr.getDescriptor) getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, @@ -150,7 +165,8 @@ class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], setting } rmr } - else foundRevisions.reverse.headOption map { _._1 } + else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached mrOpt match { case None if errors.size == 1 => From d2f2d120a99e1471811396ff617f826a7baab709 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 21 Oct 2014 11:48:06 -0400 Subject: [PATCH 0364/1030] Fixes #1684. cached resolution applies overrides on conflict This change brings over dependency overrides to artificial graph. However, it seems forced might win, so I need to take overrides logic in account during conflict resolution. --- .../CachedResolutionResolveEngine.scala | 85 ++++++++++++++----- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 09da3b501..5e7ca55e0 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -12,9 +12,11 @@ import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } +import core.module.descriptor.OverrideDependencyDescriptorMediator import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } +import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -58,9 +60,10 @@ private[sbt] class CachedResolutionResolveCache() { } getOrElse Vector(dep) val expanded = directDependencies(md0) flatMap expandInternalDeps val rootModuleConfigs = md0.getConfigurations.toVector - expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, prOpt) } + expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt) } } - def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = + + def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = { def excludeRuleString(rule: ExcludeRule): String = s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" @@ -82,8 +85,10 @@ private[sbt] class CachedResolutionResolveCache() { case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") } }) + val os = extractOverrides(parent) + val moduleLevel = s"""dependencyOverrides=${os.mkString(",")}""" val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};""" + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex(Hash(depsString)) val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { def targetModuleRevisionId: ModuleRevisionId = mrid @@ -92,8 +97,25 @@ private[sbt] class CachedResolutionResolveCache() { conf <- rootModuleConfigs } yield md1.addConfiguration(conf) md1.addDependency(dd) + os foreach { ovr => + md1.addDependencyDescriptorMediator(ovr.moduleId, ovr.pm, ovr.ddm) + } (md1, IvySbt.isChanging(dd)) } + def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = + { + import scala.collection.JavaConversions._ + (md0.getAllDependencyDescriptorMediators.getAllRules).toSeq.toVector sortBy { + case (k, v) => + k.toString + } collect { + case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => + val attr: Map[Any, Any] = k.getAttributes.toMap + val module = IvyModuleId.newInstance(attr(IvyPatternHelper.ORGANISATION_KEY).toString, attr(IvyPatternHelper.MODULE_KEY).toString) + val pm = k.getPatternMatcher + IvyOverride(module, pm, v) + } + } def getOrElseUpdateMiniGraph(md: ModuleDescriptor, changing0: Boolean, logicalClock: LogicalClock, miniGraphPath: File, cachedDescriptor: File, log: Logger)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = { import Path._ @@ -206,6 +228,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val cache = cachedResolutionResolveCache cache.directDependencyCache.remove(md0.getModuleRevisionId) + val os = cache.extractOverrides(md0) val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver) def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { @@ -233,7 +256,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { doWork(md) } } - val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, log) + val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0) val prop0 = "" @@ -241,9 +264,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { IO.write(ivyPropertiesInCache0, prop0) uReport } - def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], missingOk: Boolean, resolveTime: Long, log: Logger): Either[ResolveException, UpdateReport] = + def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], missingOk: Boolean, resolveTime: Long, + os: Vector[IvyOverride], log: Logger): Either[ResolveException, UpdateReport] = if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) - else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, log)) + else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException], log: Logger): ResolveException = { val messages = errors flatMap { _.messages } @@ -257,7 +281,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } new ResolveException(messages, failed, ListMap(failedPaths: _*)) } - def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], resolveTime: Long, log: Logger): UpdateReport = + def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], resolveTime: Long, os: Vector[IvyOverride], log: Logger): UpdateReport = { val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val rootModuleConfigs = md0.getConfigurations.toVector @@ -265,14 +289,14 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val stats = new UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) val configReports = rootModuleConfigs map { conf => val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } - mergeConfigurationReports(conf.getName, crs, log) + mergeConfigurationReports(conf.getName, crs, os, log) } new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } - def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], log: Logger): ConfigurationReport = + def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], os: Vector[IvyOverride], log: Logger): ConfigurationReport = { // get the details right, and the rest could be derived - val details = mergeOrganizationArtifactReports(rootModuleConf, reports flatMap { _.details }, log) + val details = mergeOrganizationArtifactReports(rootModuleConf, reports flatMap { _.details }, os, log) val modules = details flatMap { _.modules filter { mr => !mr.evicted && mr.problem.isEmpty @@ -285,13 +309,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } map { _.module } new ConfigurationReport(rootModuleConf, modules, details, evicted) } - def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], log: Logger): Vector[OrganizationArtifactReport] = + def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector flatMap { case ((org, name), xs) => if (xs.size < 2) xs - else Vector(new OrganizationArtifactReport(org, name, mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, log))) + else Vector(new OrganizationArtifactReport(org, name, mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log))) } - def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], log: Logger): Vector[ModuleReport] = + def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): Vector[ModuleReport] = { val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { case ((org, name, version), xs) => @@ -300,12 +324,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } if (conflicts.size < 2) merged - else resolveConflict(rootModuleConf, conflicts, log) match { + else resolveConflict(rootModuleConf, conflicts, os, log) match { case (survivor, evicted) => survivor ++ evicted ++ (merged filter { m => m.evicted || m.problem.isDefined }) } } - def resolveConflict(rootModuleConf: String, conflicts: Vector[ModuleReport], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = + def resolveConflict(rootModuleConf: String, conflicts: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { import org.apache.ivy.plugins.conflict.{ NoConflictManager, StrictConflictManager, LatestConflictManager } val head = conflicts.head @@ -319,7 +343,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { m.callers.exists { _.isForceDependency } })) match { case Some(m) => - log.debug(s"- forced dependency: $m") + log.debug(s"- forced dependency: $m ${m.callers}") (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) case None => val strategy = lcm.getStrategy @@ -331,13 +355,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } } def doResolveConflict: (Vector[ModuleReport], Vector[ModuleReport], String) = - getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { - case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) - case _: StrictConflictManager => sys.error((s"conflict was found in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")"))) - case lcm: LatestConflictManager => useLatest(lcm) - case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + os find { ovr => ovr.moduleId.getOrganisation == organization && ovr.moduleId.getName == name } match { + case Some(ovr) if Option(ovr.ddm.getVersion).isDefined => + val ovrVersion = ovr.ddm.getVersion + conflicts find { mr => + mr.module.revision == ovrVersion + } match { + case Some(m) => + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("override")) }, "override") + case None => + sys.error(s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { _.module }).mkString("(", ", ", ")")) + } + case None => + getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { + case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) + case _: StrictConflictManager => sys.error((s"conflict was found in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")"))) + case lcm: LatestConflictManager => useLatest(lcm) + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + } } - if (conflicts.size == 2) { + if (conflicts.size == 2 && os.isEmpty) { val (cf0, cf1) = (conflicts(0).module, conflicts(1).module) val cache = cachedResolutionResolveCache cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } @@ -345,7 +382,6 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val (surviving, evicted, mgr) = doResolveConflict (surviving, evicted) } - } } @@ -353,3 +389,6 @@ private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) ext override def getLastModified: Long = moduleReport.publicationDate map { _.getTime } getOrElse 0L override def getRevision: String = moduleReport.module.revision } +private[sbt] case class IvyOverride(moduleId: IvyModuleId, pm: PatternMatcher, ddm: OverrideDependencyDescriptorMediator) { + override def toString: String = s"""IvyOverride($moduleId,$pm,${ddm.getVersion},${ddm.getBranch})""" +} From 55fc4a29c14db1efca482c7bc4b64568bb95b287 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 28 Oct 2014 14:28:33 -0400 Subject: [PATCH 0365/1030] Fixes #1699. ignore transitive force during cached resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When Ivy translates pom to ivy.xml, it adds force=“true”. So when both non-Maven dependencies and Maven dependencies are mixed, Maven dependencies always wins, which is the case for scala-library dependency added by the user. --- .../CachedResolutionResolveEngine.scala | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 5e7ca55e0..5654e479c 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -216,6 +216,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache private[sbt] def projectResolver: Option[ProjectResolver] private[sbt] def makeInstance: Ivy + private[sbt] val ignoreTransitiveForce: Boolean = true /** * This returns sbt's UpdateReport structure. @@ -339,19 +340,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def useLatest(lcm: LatestConflictManager): (Vector[ModuleReport], Vector[ModuleReport], String) = (conflicts find { m => m.callers.exists { _.isDirectlyForceDependency } - } orElse (conflicts find { m => - m.callers.exists { _.isForceDependency } - })) match { + }) match { case Some(m) => - log.debug(s"- forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) + log.debug(s"- directly forced dependency: $m ${m.callers}") + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("direct-force")) }, "direct-force") case None => - val strategy = lcm.getStrategy - val infos = conflicts map { ModuleReportArtifactInfo(_) } - Option(strategy.findLatest(infos.toArray, None.orNull)) match { - case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) - case _ => (conflicts, Vector(), lcm.toString) + (conflicts find { m => + m.callers.exists { _.isForceDependency } + }) match { + // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. + case Some(m) if !ignoreTransitiveForce => + log.debug(s"- transitively forced dependency: $m ${m.callers}") + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("transitive-force")) }, "transitive-force") + case _ => + val strategy = lcm.getStrategy + val infos = conflicts map { ModuleReportArtifactInfo(_) } + Option(strategy.findLatest(infos.toArray, None.orNull)) match { + case Some(ModuleReportArtifactInfo(m)) => + (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) + case _ => (conflicts, Vector(), lcm.toString) + } } } def doResolveConflict: (Vector[ModuleReport], Vector[ModuleReport], String) = From 6052cd65b4c8529f610311d58faa2a367244656c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 28 Oct 2014 22:31:20 -0400 Subject: [PATCH 0366/1030] added comments --- .../sbt/ivyint/CachedResolutionResolveEngine.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 5654e479c..73003bcb7 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -330,6 +330,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { survivor ++ evicted ++ (merged filter { m => m.evicted || m.problem.isDefined }) } } + /** + * resolves dependency resolution conflicts in which multiple candidates are found for organization+name combos. + * The main input is conflicts, which is a Vector of ModuleReport, which contains full info on the modulerevision, including its callers. + * Conflict resolution could be expensive, so this is first cached to `cachedResolutionResolveCache` if the conflict is between 2 modules. + * Otherwise, the default "latest" resolution takes the following precedence: + * 1. overrides passed in to `os`. + * 2. diretly forced dependency within the artificial module. + * 3. latest revision. + * Note transitively forced dependencies are not respected. This seems to be the case for stock Ivy's behavior as well, + * which may be because Ivy makes all Maven dependencies as forced="true". + */ def resolveConflict(rootModuleConf: String, conflicts: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { import org.apache.ivy.plugins.conflict.{ NoConflictManager, StrictConflictManager, LatestConflictManager } From 4de9c3960d28697b045118eef6bb2f310b56fbb5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 1 Nov 2014 20:45:44 -0400 Subject: [PATCH 0367/1030] Fixes #1710. Fixed cached resolution mutual eviction When stitching the minigraphs together only exclude the artifacts that were evicted in *all* graphs, instead of some graphs. Consider the following scenario: - Y1 evicts slf4j-api 1.6.6 and picks 1.7.5 - Y2 evicts slf4j-api 1.7.5 and picks 1.6.6 At the root level, we need to use our own judgement and pick 1.7.5. --- .../main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 73003bcb7..88dd4241c 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -321,7 +321,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { case ((org, name, version), xs) => if (xs.size < 2) xs - else Vector(xs.head.copy(evicted = xs exists { _.evicted }, callers = xs flatMap { _.callers })) + else Vector(xs.head.copy(evicted = xs forall { _.evicted }, callers = xs flatMap { _.callers })) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } if (conflicts.size < 2) merged From b60bd95d7363f143690e87d1a330d8724c938c7f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 4 Nov 2014 17:56:34 -0500 Subject: [PATCH 0368/1030] Fixes #1711. Fixes cached resolution pulling in % "test" from subproj deps --- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 88dd4241c..fa8361c95 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -54,8 +54,10 @@ private[sbt] class CachedResolutionResolveCache() { def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] = prOpt map { _.getModuleDescriptor(dep.getDependencyRevisionId) match { - case Some(internal) => directDependencies(internal) flatMap expandInternalDeps - case _ => Vector(dep) + case Some(internal) => directDependencies(internal) filter { dd => + !dd.getDependencyConfigurations("compile").isEmpty + } flatMap expandInternalDeps + case _ => Vector(dep) } } getOrElse Vector(dep) val expanded = directDependencies(md0) flatMap expandInternalDeps From 1f49e6a5ce40da2ba12dd067ecee811314513190 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 4 Nov 2014 19:01:30 -0500 Subject: [PATCH 0369/1030] Fixes #1704. Fixes cached resolution + module-level exclusions --- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index fa8361c95..4b852f48a 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -87,8 +87,10 @@ private[sbt] class CachedResolutionResolveCache() { case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") } }) + val mes = parent.getAllExcludeRules.toVector + val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) - val moduleLevel = s"""dependencyOverrides=${os.mkString(",")}""" + val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex(Hash(depsString)) @@ -102,6 +104,9 @@ private[sbt] class CachedResolutionResolveCache() { os foreach { ovr => md1.addDependencyDescriptorMediator(ovr.moduleId, ovr.pm, ovr.ddm) } + mes foreach { exclude => + md1.addExcludeRule(exclude) + } (md1, IvySbt.isChanging(dd)) } def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = From 05eab70210422ff31f1875f8793d2380d10573fa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 6 Nov 2014 00:28:26 -0500 Subject: [PATCH 0370/1030] expand internal dependencies more accurately --- .../CachedResolutionResolveEngine.scala | 104 +++++++++++++----- 1 file changed, 74 insertions(+), 30 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 4b852f48a..120e3042c 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -11,7 +11,7 @@ import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } -import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } +import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } import core.module.descriptor.OverrideDependencyDescriptorMediator import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message @@ -29,42 +29,85 @@ private[sbt] class CachedResolutionResolveCache() { val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() - val directDependencyCache: concurrent.Map[ModuleRevisionId, Vector[DependencyDescriptor]] = concurrent.TrieMap() val conflictCache: concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap() val maxConflictCacheSize: Int = 10000 def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { - val mrid0 = md0.getModuleRevisionId - val mds = - if (mrid0.getOrganisation == sbtOrgTemp) Vector(md0) - else buildArtificialModuleDescriptors(md0, prOpt) map { _._1 } - - updateReportCache.remove(md0.getModuleRevisionId) - directDependencyCache.remove(md0.getModuleRevisionId) - mds foreach { md => - updateReportCache.remove(md.getModuleRevisionId) - directDependencyCache.remove(md.getModuleRevisionId) - } + updateReportCache.clear } def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = - directDependencyCache.getOrElseUpdate(md0.getModuleRevisionId, md0.getDependencies.toVector) - - def buildArtificialModuleDescriptors(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Vector[(DefaultModuleDescriptor, Boolean)] = + md0.getDependencies.toVector + def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver]): Vector[(DefaultModuleDescriptor, Boolean)] = { - def expandInternalDeps(dep: DependencyDescriptor): Vector[DependencyDescriptor] = - prOpt map { - _.getModuleDescriptor(dep.getDependencyRevisionId) match { - case Some(internal) => directDependencies(internal) filter { dd => - !dd.getDependencyConfigurations("compile").isEmpty - } flatMap expandInternalDeps - case _ => Vector(dep) - } - } getOrElse Vector(dep) - val expanded = directDependencies(md0) flatMap expandInternalDeps - val rootModuleConfigs = md0.getConfigurations.toVector + val rootModuleConfigs = md0.getConfigurations.toArray.toVector + val expanded = expandInternalDependencies(md0, data, prOpt) expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt) } } - + // This expands out all internal dependencies and merge them into a single graph that consists + // only of external dependencies. + // The tricky part is the merger of configurations, even though in most cases we will only see compile->compile when it comes to internal deps. + // Theoretically, there could be a potential for test->test->runtime kind of situation. nextConfMap and remapConfigurations track + // the configuration chains transitively. + def expandInternalDependencies(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver]): Vector[DependencyDescriptor] = + { + val rootModuleConfigs = md0.getConfigurations.toArray.toVector + val rootNode = new IvyNode(data, md0) + def expandInternalDeps(dep: DependencyDescriptor, confMap: Map[String, Array[String]]): Vector[DependencyDescriptor] = + internalDependency(dep) match { + case Some(internal) => + val allConfigurations: Vector[String] = + (if (confMap.isEmpty) nextConfMap(dep, confMap) + else confMap).values.flatten.toList.distinct.toVector + directDependencies(internal) filter { dd => + allConfigurations exists { conf => !dd.getDependencyConfigurations(conf).isEmpty } + } flatMap { dd => expandInternalDeps(dd, nextConfMap(dd, confMap)) } + case _ => + if (confMap.isEmpty) Vector(dep) + else Vector(remapConfigurations(dep, confMap)) + } + def internalDependency(dep: DependencyDescriptor): Option[ModuleDescriptor] = + prOpt match { + case Some(pr) => pr.getModuleDescriptor(dep.getDependencyRevisionId) + case _ => None + } + // This creates confMap. The key of the map is rootModuleConf for md0, the value is the dependency configs for dd. + def nextConfMap(dd: DependencyDescriptor, previous: Map[String, Array[String]]): Map[String, Array[String]] = + if (previous.isEmpty) { + ListMap(dd.getModuleConfigurations.toList map { conf => + conf -> (dd.getDependencyConfigurations(conf) flatMap { confName => + if (confName == "*") Array(confName) + else rootNode.getRealConfs(confName) + }) + }: _*) + } else previous map { + case (rootModuleConf, vs) => + rootModuleConf -> (vs flatMap { conf => + dd.getDependencyConfigurations(conf) flatMap { confName => + if (confName == "*") Array(confName) + else rootNode.getRealConfs(confName) + } + }) + } + def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]]): DependencyDescriptor = + { + val dd = new DefaultDependencyDescriptor(md0, dd0.getDependencyRevisionId, dd0.getDynamicConstraintDependencyRevisionId, + dd0.isForce, dd0.isChanging, dd0.isTransitive) + for { + moduleConf <- dd0.getModuleConfigurations + (rootModuleConf, vs) <- confMap + } if (vs contains moduleConf) { + // moduleConf in dd0 maps to rootModuleConf in dd + dd0.getDependencyConfigurations(moduleConf) foreach { conf => + dd.addDependencyConfiguration(rootModuleConf, conf) + } + dd0.getExcludeRules(moduleConf) foreach { rule => + dd.addExcludeRule(rootModuleConf, rule) + } + } + dd + } + directDependencies(md0) flatMap { dep => expandInternalDeps(dep, Map()) } + } def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = { def excludeRuleString(rule: ExcludeRule): String = @@ -235,9 +278,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val miniGraphPath = depDir / "module" val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val cache = cachedResolutionResolveCache - cache.directDependencyCache.remove(md0.getModuleRevisionId) val os = cache.extractOverrides(md0) - val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver) + val options1 = new ResolveOptions(options0) + val data = new ResolveData(this, options1) + val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver) def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) From b57152c77e9103a3e5fcccb2ac5643d603a026fe Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 9 Nov 2014 23:32:03 -0500 Subject: [PATCH 0371/1030] fixes #1719. cached resolution: fixes handling of classifier and other explicit artifacts --- .../CachedResolutionResolveEngine.scala | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 120e3042c..be2a366a3 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -12,7 +12,7 @@ import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } -import core.module.descriptor.OverrideDependencyDescriptorMediator +import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor } import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } @@ -37,19 +37,21 @@ private[sbt] class CachedResolutionResolveCache() { } def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector - def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver]): Vector[(DefaultModuleDescriptor, Boolean)] = + def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[(DefaultModuleDescriptor, Boolean)] = { + log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") + val expanded = expandInternalDependencies(md0, data, prOpt, log) val rootModuleConfigs = md0.getConfigurations.toArray.toVector - val expanded = expandInternalDependencies(md0, data, prOpt) - expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt) } + expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt, log) } } // This expands out all internal dependencies and merge them into a single graph that consists // only of external dependencies. // The tricky part is the merger of configurations, even though in most cases we will only see compile->compile when it comes to internal deps. // Theoretically, there could be a potential for test->test->runtime kind of situation. nextConfMap and remapConfigurations track // the configuration chains transitively. - def expandInternalDependencies(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver]): Vector[DependencyDescriptor] = + def expandInternalDependencies(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[DependencyDescriptor] = { + log.debug(s"::: expanding internal dependencies of module descriptor ${md0.getModuleRevisionId}") val rootModuleConfigs = md0.getConfigurations.toArray.toVector val rootNode = new IvyNode(data, md0) def expandInternalDeps(dep: DependencyDescriptor, confMap: Map[String, Array[String]]): Vector[DependencyDescriptor] = @@ -93,27 +95,36 @@ private[sbt] class CachedResolutionResolveCache() { val dd = new DefaultDependencyDescriptor(md0, dd0.getDependencyRevisionId, dd0.getDynamicConstraintDependencyRevisionId, dd0.isForce, dd0.isChanging, dd0.isTransitive) for { - moduleConf <- dd0.getModuleConfigurations - (rootModuleConf, vs) <- confMap + moduleConf <- dd0.getModuleConfigurations.toVector + (rootModuleConf, vs) <- confMap.toSeq } if (vs contains moduleConf) { // moduleConf in dd0 maps to rootModuleConf in dd dd0.getDependencyConfigurations(moduleConf) foreach { conf => dd.addDependencyConfiguration(rootModuleConf, conf) } + dd0.getIncludeRules(moduleConf) foreach { rule => + dd.addIncludeRule(rootModuleConf, rule) + } dd0.getExcludeRules(moduleConf) foreach { rule => dd.addExcludeRule(rootModuleConf, rule) } + dd0.getDependencyArtifacts(moduleConf) foreach { dad => + dd.addDependencyArtifact(rootModuleConf, dad) + } } dd } directDependencies(md0) flatMap { dep => expandInternalDeps(dep, Map()) } } - def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, prOpt: Option[ProjectResolver]): (DefaultModuleDescriptor, Boolean) = + def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], + parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean) = { def excludeRuleString(rule: ExcludeRule): String = s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" def includeRuleString(rule: IncludeRule): String = s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" + def artifactString(dad: DependencyArtifactDescriptor): String = + s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations.mkString(",")})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" @@ -130,6 +141,13 @@ private[sbt] class CachedResolutionResolveCache() { case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") } }) + val explicitArtifacts = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getDependencyArtifacts(conf).toVector match { + case Vector() => None + case dads => Some(conf + "->(" + (dads map artifactString).mkString(",") + ")") + } + }) + val mes = parent.getAllExcludeRules.toVector val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) @@ -281,7 +299,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val os = cache.extractOverrides(md0) val options1 = new ResolveOptions(options0) val data = new ResolveData(this, options1) - val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver) + val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) From 78929291c7eda6ce54ae9b3403e108a3acad7cb8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 10 Nov 2014 01:10:37 -0500 Subject: [PATCH 0372/1030] fixes #1711, #1716. Fixes configuration remapping The actual change is one line at line 64. nextConfMap takes dep instead of dd. --- .../ivyint/CachedResolutionResolveEngine.scala | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index be2a366a3..15c3e3b79 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -57,15 +57,18 @@ private[sbt] class CachedResolutionResolveCache() { def expandInternalDeps(dep: DependencyDescriptor, confMap: Map[String, Array[String]]): Vector[DependencyDescriptor] = internalDependency(dep) match { case Some(internal) => + log.debug(s""":::: found internal dependency ${internal.getResolvedModuleRevisionId}""") val allConfigurations: Vector[String] = (if (confMap.isEmpty) nextConfMap(dep, confMap) else confMap).values.flatten.toList.distinct.toVector - directDependencies(internal) filter { dd => + val next = nextConfMap(dep, confMap) + val directs = directDependencies(internal) filter { dd => allConfigurations exists { conf => !dd.getDependencyConfigurations(conf).isEmpty } - } flatMap { dd => expandInternalDeps(dd, nextConfMap(dd, confMap)) } + } + directs flatMap { dd => expandInternalDeps(dd, next) } case _ => if (confMap.isEmpty) Vector(dep) - else Vector(remapConfigurations(dep, confMap)) + else Vector(remapConfigurations(dep, confMap, log)) } def internalDependency(dep: DependencyDescriptor): Option[ModuleDescriptor] = prOpt match { @@ -90,15 +93,17 @@ private[sbt] class CachedResolutionResolveCache() { } }) } - def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]]): DependencyDescriptor = + def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]], log: Logger): DependencyDescriptor = { + log.debug(s""":::: remapping configuration of ${dd0} with ${confMap.toList map { case (k, v) => (k, v.toList) }}""") val dd = new DefaultDependencyDescriptor(md0, dd0.getDependencyRevisionId, dd0.getDynamicConstraintDependencyRevisionId, dd0.isForce, dd0.isChanging, dd0.isTransitive) + val moduleConfigurations = dd0.getModuleConfigurations.toVector for { - moduleConf <- dd0.getModuleConfigurations.toVector + moduleConf <- moduleConfigurations (rootModuleConf, vs) <- confMap.toSeq } if (vs contains moduleConf) { - // moduleConf in dd0 maps to rootModuleConf in dd + log.debug(s""":::: ${dd0}: $moduleConf maps to $rootModuleConf""") dd0.getDependencyConfigurations(moduleConf) foreach { conf => dd.addDependencyConfiguration(rootModuleConf, conf) } @@ -112,6 +117,7 @@ private[sbt] class CachedResolutionResolveCache() { dd.addDependencyArtifact(rootModuleConf, dad) } } + log.debug(s""":::: remapped dd: $dd""") dd } directDependencies(md0) flatMap { dep => expandInternalDeps(dep, Map()) } From 813a8ff3262a90d571c70eb7290381b5edadddc1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 11 Nov 2014 21:15:11 -0500 Subject: [PATCH 0373/1030] Fixes #1723. classifier-related fixes - minigraph sha now contains extra attributes from artifacts - artifacts are merged from different mini graphs (in some cases, this should result to better resolution than stock ivy) --- .../CachedResolutionResolveEngine.scala | 70 +++++++++++-------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 15c3e3b79..32442167a 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -12,7 +12,7 @@ import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } -import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor } +import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.Message import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } @@ -42,7 +42,11 @@ private[sbt] class CachedResolutionResolveCache() { log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") val expanded = expandInternalDependencies(md0, data, prOpt, log) val rootModuleConfigs = md0.getConfigurations.toArray.toVector - expanded map { buildArtificialModuleDescriptor(_, rootModuleConfigs, md0, prOpt, log) } + expanded map { dd => + val arts = dd.getAllDependencyArtifacts.toVector map { x => s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } + log.debug(s"::: expanded dd: $dd (artifacts: ${arts.mkString(",")})") + buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log) + } } // This expands out all internal dependencies and merge them into a single graph that consists // only of external dependencies. @@ -58,17 +62,16 @@ private[sbt] class CachedResolutionResolveCache() { internalDependency(dep) match { case Some(internal) => log.debug(s""":::: found internal dependency ${internal.getResolvedModuleRevisionId}""") - val allConfigurations: Vector[String] = - (if (confMap.isEmpty) nextConfMap(dep, confMap) - else confMap).values.flatten.toList.distinct.toVector + val allConfigurations: Vector[String] = confMap.values.flatten.toVector.distinct val next = nextConfMap(dep, confMap) - val directs = directDependencies(internal) filter { dd => + // direct dependencies of an internal dependency + val directs0 = directDependencies(internal) + val directs = directs0 filter { dd => allConfigurations exists { conf => !dd.getDependencyConfigurations(conf).isEmpty } } directs flatMap { dd => expandInternalDeps(dd, next) } case _ => - if (confMap.isEmpty) Vector(dep) - else Vector(remapConfigurations(dep, confMap, log)) + Vector(remapConfigurations(dep, confMap, log)) } def internalDependency(dep: DependencyDescriptor): Option[ModuleDescriptor] = prOpt match { @@ -77,14 +80,7 @@ private[sbt] class CachedResolutionResolveCache() { } // This creates confMap. The key of the map is rootModuleConf for md0, the value is the dependency configs for dd. def nextConfMap(dd: DependencyDescriptor, previous: Map[String, Array[String]]): Map[String, Array[String]] = - if (previous.isEmpty) { - ListMap(dd.getModuleConfigurations.toList map { conf => - conf -> (dd.getDependencyConfigurations(conf) flatMap { confName => - if (confName == "*") Array(confName) - else rootNode.getRealConfs(confName) - }) - }: _*) - } else previous map { + previous map { case (rootModuleConf, vs) => rootModuleConf -> (vs flatMap { conf => dd.getDependencyConfigurations(conf) flatMap { confName => @@ -93,6 +89,10 @@ private[sbt] class CachedResolutionResolveCache() { } }) } + // The key of the confMap is rootModuleConf for md0, and the values are modules configuratons of dd0. + // For example if project Root depends on project B % "test", and project B depends on junit, + // confMap should contain Map("test", Array("compile")). + // This remaps junit dependency as junit % "test". def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]], log: Logger): DependencyDescriptor = { log.debug(s""":::: remapping configuration of ${dd0} with ${confMap.toList map { case (k, v) => (k, v.toList) }}""") @@ -113,14 +113,25 @@ private[sbt] class CachedResolutionResolveCache() { dd0.getExcludeRules(moduleConf) foreach { rule => dd.addExcludeRule(rootModuleConf, rule) } - dd0.getDependencyArtifacts(moduleConf) foreach { dad => - dd.addDependencyArtifact(rootModuleConf, dad) + dd0.getAllDependencyArtifacts foreach { dad0 => + (Option(dad0.getConfigurations) map { confs => confs.isEmpty || confs.contains(moduleConf) || confs.contains("*") }) match { + case Some(false) => // do nothing + case _ => + val dad = new DefaultDependencyArtifactDescriptor(dd, dad0.getName, dad0.getType, dad0.getExt, dad0.getUrl, dad0.getExtraAttributes) + dad.addConfiguration(rootModuleConf) + dd.addDependencyArtifact(rootModuleConf, dad) + } } } log.debug(s""":::: remapped dd: $dd""") dd } - directDependencies(md0) flatMap { dep => expandInternalDeps(dep, Map()) } + directDependencies(md0) flatMap { dep => + val initialMap = Map(dep.getModuleConfigurations map { rootModuleConf => + (rootModuleConf -> Array(rootModuleConf)) + }: _*) + expandInternalDeps(dep, initialMap) + } } def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean) = @@ -130,7 +141,7 @@ private[sbt] class CachedResolutionResolveCache() { def includeRuleString(rule: IncludeRule): String = s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" def artifactString(dad: DependencyArtifactDescriptor): String = - s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations.mkString(",")})""" + s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations.mkString(",")},${dad.getExtraAttributes})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" @@ -147,19 +158,13 @@ private[sbt] class CachedResolutionResolveCache() { case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") } }) - val explicitArtifacts = (dd.getModuleConfigurations.toVector flatMap { conf => - dd.getDependencyArtifacts(conf).toVector match { - case Vector() => None - case dads => Some(conf + "->(" + (dads map artifactString).mkString(",") + ")") - } - }) - + val explicitArtifacts = dd.getAllDependencyArtifacts.toVector map { artifactString } val mes = parent.getAllExcludeRules.toVector val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};$moduleLevel;""" + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts.mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex(Hash(depsString)) val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { def targetModuleRevisionId: ModuleRevisionId = mrid @@ -393,10 +398,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): Vector[ModuleReport] = { + def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = { + val completelyEvicted = xs forall { _.evicted } + val allCallers = xs flatMap { _.callers } + val allArtifacts = (xs flatMap { _.artifacts }).distinct + log.debug(s":: merging module report for $org:$name:$version - $allArtifacts") + xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = allCallers) + } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { case ((org, name, version), xs) => if (xs.size < 2) xs - else Vector(xs.head.copy(evicted = xs forall { _.evicted }, callers = xs flatMap { _.callers })) + else Vector(mergeModuleReports(org, name, version, xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } if (conflicts.size < 2) merged From e0e7fd002cfe05393fa58f2e6b828ed15cefc8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-R=C3=A9mi=20Desjardins?= Date: Wed, 3 Dec 2014 09:56:34 -0800 Subject: [PATCH 0374/1030] Minor code cleanup --- ivy/src/main/scala/sbt/ConflictWarning.scala | 2 +- ivy/src/main/scala/sbt/EvictionWarning.scala | 10 +++++----- ivy/src/main/scala/sbt/Ivy.scala | 8 ++++---- ivy/src/main/scala/sbt/IvyActions.scala | 10 +++++----- ivy/src/main/scala/sbt/MakePom.scala | 8 ++++---- ivy/src/main/scala/sbt/ResolutionCache.scala | 2 +- ivy/src/main/scala/sbt/VersionNumber.scala | 4 ++-- .../sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- .../scala/sbt/ivyint/ErrorMessageAuthenticator.scala | 4 ++-- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 6e6b8a37d..082a478b6 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -33,7 +33,7 @@ object ConflictWarning { } private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) { val crossMismatches = crossVersionMismatches(report) - if (!crossMismatches.isEmpty) { + if (crossMismatches.nonEmpty) { val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " val conflictMsgs = for (((org, rawName), fullNames) <- crossMismatches) yield { diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 25ad9014b..cb786ca3f 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -93,7 +93,7 @@ object EvictionPair { } else "" r.module.revision + callers - }).headOption map { " -> " + _ } getOrElse "" + }) map { " -> " + _ } getOrElse "" Seq(s"\t* ${a.organization}:${a.name}:${revsStr}$winnerRev") } } @@ -160,7 +160,7 @@ object EvictionWarning { pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => (module.moduleSettings.ivyScala, p.winner) match { - case (Some(s), Some(winner)) if ((s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction) => + case (Some(s), Some(winner)) if (s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction => scalaEvictions += p case _ => } @@ -180,21 +180,21 @@ object EvictionWarning { implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => import ShowLines._ val out: mutable.ListBuffer[String] = mutable.ListBuffer() - if (!a.scalaEvictions.isEmpty) { + if (a.scalaEvictions.nonEmpty) { out += "Scala version was updated by one of library dependencies:" out ++= (a.scalaEvictions flatMap { _.lines }) out += "To force scalaVersion, add the following:" out += "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" } - if (!a.directEvictions.isEmpty || !a.transitiveEvictions.isEmpty) { + if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { out += "There may be incompatibilities among your library dependencies." out += "Here are some of the libraries that were evicted:" out ++= (a.directEvictions flatMap { _.lines }) out ++= (a.transitiveEvictions flatMap { _.lines }) } - if (!a.allEvictions.isEmpty && !a.reportedEvictions.isEmpty && !a.options.showCallers) { + if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty && !a.options.showCallers) { out += "Run 'evicted' to see detailed eviction warnings" } diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index c0e7d508a..8b3bfe5ec 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -19,7 +19,7 @@ import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheM import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } -import org.apache.ivy.core.module.descriptor.{ OverrideDependencyDescriptorMediator } +import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision, ResolveEngine } import org.apache.ivy.core.settings.IvySettings @@ -496,7 +496,7 @@ private[sbt] object IvySbt { private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { val info = { x } \ "info" - if (!info.isEmpty) { + if (info.nonEmpty) { def check(found: NodeSeq, expected: String, label: String) = if (found.isEmpty) sys.error("Missing " + label + " in inline Ivy XML.") @@ -508,7 +508,7 @@ private[sbt] object IvySbt { check(info \ "@module", module.name, "name") check(info \ "@revision", module.revision, "version") } - !info.isEmpty + info.nonEmpty } /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = @@ -582,7 +582,7 @@ private[sbt] object IvySbt { for (artifact <- dependency.explicitArtifacts) { import artifact.{ name, classifier, `type`, extension, url } val extraMap = extra(artifact) - val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.getOrElse(null), extraMap) + val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.orNull, extraMap) copyConfigurations(artifact, ivyArtifact.addConfiguration) for (conf <- dependencyDescriptor.getModuleConfigurations) dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index a6754b138..39af5bee9 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -226,7 +226,7 @@ object IvyActions { { import config.{ configuration => c, module => mod, _ } import mod.{ configurations => confs, _ } - assert(!classifiers.isEmpty, "classifiers cannot be empty") + assert(classifiers.nonEmpty, "classifiers cannot be empty") val baseModules = modules map { m => restrictedCopy(m, true) } val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) @@ -375,16 +375,16 @@ object UnresolvedWarning { case _ => "" } implicit val unresolvedWarningLines: ShowLines[UnresolvedWarning] = ShowLines { a => - val withExtra = a.resolveException.failed.filter(!_.extraDependencyAttributes.isEmpty) + val withExtra = a.resolveException.failed.filter(_.extraDependencyAttributes.nonEmpty) val buffer = mutable.ListBuffer[String]() - if (!withExtra.isEmpty) { + if (withExtra.nonEmpty) { buffer += "\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes." withExtra foreach { id => buffer += "\t\t" + id } } - if (!a.failedPaths.isEmpty) { + if (a.failedPaths.nonEmpty) { buffer += "\n\tNote: Unresolved dependencies path:" a.failedPaths foreach { path => - if (!path.isEmpty) { + if (path.nonEmpty) { val head = path.head buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) path.tail foreach { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index eba0cd94d..904be0c8c 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -258,7 +258,7 @@ class MakePom(val log: Logger) { @deprecated("No longer used and will be removed.", "0.12.1") def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { - val jarDep = dependency.getAllDependencyArtifacts.filter(d => includeTypes(d.getType)).headOption + val jarDep = dependency.getAllDependencyArtifacts.find(d => includeTypes(d.getType)) jarDep match { case Some(a) => classifierElem(artifactClassifier(a)) case None => NodeSeq.Empty @@ -298,15 +298,15 @@ class MakePom(val log: Logger) { val (opt, notOptional) = confs.partition(_ == Optional.name) val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) val scope = defaultNotOptional.map(_.name) - (scope, !opt.isEmpty) + (scope, opt.nonEmpty) } def exclusions(dependency: DependencyDescriptor): NodeSeq = { val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) - if (!warns.isEmpty) log.warn(warns.mkString(IO.Newline)) - if (!excls.isEmpty) { excls } + if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) + if (excls.nonEmpty) { excls } else NodeSeq.Empty } def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala index 41721a784..0fd7a0a06 100644 --- a/ivy/src/main/scala/sbt/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/ResolutionCache.scala @@ -52,7 +52,7 @@ private[sbt] final class ResolutionCache(base: File, settings: IvySettings) exte throw new IllegalStateException("Ivy file not found in cache for " + mrid + "!") } - return XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, ivyFile.toURI().toURL(), false) + XmlModuleDescriptorParser.getInstance().parseDescriptor(settings, ivyFile.toURI.toURL, false) } def saveResolvedModuleDescriptor(md: ModuleDescriptor): Unit = { diff --git a/ivy/src/main/scala/sbt/VersionNumber.scala b/ivy/src/main/scala/sbt/VersionNumber.scala index 7db8c8fef..182d44edc 100644 --- a/ivy/src/main/scala/sbt/VersionNumber.scala +++ b/ivy/src/main/scala/sbt/VersionNumber.scala @@ -97,7 +97,7 @@ object VersionNumber { case (0L, _, _, _, 0L, _, _, _) => // Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable. equalsIgnoreExtra(v1, v2) - case (_, 0, 0, ts1, _, 0, 0, ts2) if (!ts1.isEmpty) || (!ts2.isEmpty) => + case (_, 0, 0, ts1, _, 0, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, _, _, _, x2, _, _, _) => @@ -125,7 +125,7 @@ object VersionNumber { (v1, v2) match { case (v1, v2) if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { - case (x1, y1, 0, ts1, x2, y2, 0, ts2) if (!ts1.isEmpty) || (!ts2.isEmpty) => + case (x1, y1, 0, ts1, x2, y2, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, y1, _, _, x2, y2, _, _) => diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 32442167a..76b576412 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -67,7 +67,7 @@ private[sbt] class CachedResolutionResolveCache() { // direct dependencies of an internal dependency val directs0 = directDependencies(internal) val directs = directs0 filter { dd => - allConfigurations exists { conf => !dd.getDependencyConfigurations(conf).isEmpty } + allConfigurations exists { conf => dd.getDependencyConfigurations(conf).nonEmpty } } directs flatMap { dd => expandInternalDeps(dd, next) } case _ => diff --git a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala index e59e36e34..bb5996834 100644 --- a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala @@ -92,7 +92,7 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato // TODO - levenshtein distance "did you mean" message. Message.error(s"Unable to find credentials for [${getRequestingPrompt} @ ${host}].") val configuredRealms = IvyCredentialsLookup.realmsForHost.getOrElse(host, Set.empty) - if (!configuredRealms.isEmpty) { + if (configuredRealms.nonEmpty) { Message.error(s" Is one of these realms mispelled for host [${host}]:") configuredRealms foreach { realm => Message.error(s" * ${realm}") @@ -116,7 +116,7 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato getRequestingScheme)) finally Authenticator.setDefault(this) } - originalAuthentication.getOrElse(null) + originalAuthentication.orNull } /** From 5cace88095051ae2f93793ff9ddccc4b0a234bad Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 4 Dec 2014 12:34:30 -0500 Subject: [PATCH 0375/1030] Fixes #1752. Fixes cached resolution too verbose. - Fixes cached resolution being too verbose - Adds new UpdateLogging named "Default" - When global logLevel or logLevel in update is Debug, Default will bump up to Full UpdateLogging. --- ivy/src/main/scala/sbt/IvyActions.scala | 15 ++++++++-- .../CachedResolutionResolveEngine.scala | 28 +++++++++++++++++-- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index a6754b138..3db09e636 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -24,7 +24,13 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St this(ivyFile, resolverName, artifacts, checksums, logging, false) } -final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) +final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) { + private[sbt] def copy( + retrieve: Option[RetrieveConfiguration] = this.retrieve, + missingOk: Boolean = this.missingOk, + logging: UpdateLogging.Value = this.logging): UpdateConfiguration = + new UpdateConfiguration(retrieve, missingOk, logging) +} final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID @@ -44,9 +50,10 @@ object UnresolvedWarningConfiguration { * `Full` is the default and logs the most. * `DownloadOnly` only logs what is downloaded. * `Quiet` only displays errors. + * `Default` uses the current log level of `update` task. */ object UpdateLogging extends Enumeration { - val Full, DownloadOnly, Quiet = Value + val Full, DownloadOnly, Quiet, Default = Value } object IvyActions { @@ -161,6 +168,7 @@ object IvyActions { val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(md) resolveOptions.setResolveId(resolveId) + resolveOptions.setLog(ivyLogLevel(configuration.logging)) x.customResolve(md, configuration.missingOk, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { case Left(x) => Left(UnresolvedWarning(x, uwconfig)) @@ -303,13 +311,14 @@ object IvyActions { IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra) } - import UpdateLogging.{ Quiet, Full, DownloadOnly } + import UpdateLogging.{ Quiet, Full, DownloadOnly, Default } import LogOptions.{ LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY } private def ivyLogLevel(level: UpdateLogging.Value) = level match { case Quiet => LOG_QUIET case DownloadOnly => LOG_DOWNLOAD_ONLY case Full => LOG_DEFAULT + case Default => LOG_DOWNLOAD_ONLY } def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 32442167a..87ad6e23c 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -14,7 +14,7 @@ import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } import core.{ IvyPatternHelper, LogOptions } -import org.apache.ivy.util.Message +import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } @@ -297,6 +297,27 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def makeInstance: Ivy private[sbt] val ignoreTransitiveForce: Boolean = true + def withIvy[A](log: Logger)(f: Ivy => A): A = + withIvy(new IvyLoggerInterface(log))(f) + def withIvy[A](log: MessageLogger)(f: Ivy => A): A = + withDefaultLogger(log) { + val ivy = makeInstance + ivy.pushContext() + ivy.getLoggerEngine.pushLogger(log) + try { f(ivy) } + finally { + ivy.getLoggerEngine.popLogger() + ivy.popContext() + } + } + def withDefaultLogger[A](log: MessageLogger)(f: => A): A = + { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(log) + try { f } + finally { Message.setDefaultLogger(originalLogger) } + } + /** * This returns sbt's UpdateReport structure. * missingOk allows sbt to call this with classifiers that may or may not exist, and grab the JARs. @@ -314,8 +335,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) - val i = makeInstance - var rr = i.resolve(md, options1) + var rr = withIvy(log) { ivy => + ivy.resolve(md, options1) + } if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) else { val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct From 5e0085ee497c8fc12650bbeff808eaa55874146d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 4 Dec 2014 17:35:30 -0500 Subject: [PATCH 0376/1030] Adds excludeDependencies. Fixes #1748 Adds project-level dependency exclusions: excludeDependencies += "org.apache.logging.log4j" excludeDependencies += "com.example" %% "foo" In the first example, all artifacts from the organization `"org.apache.logging.log4j"` are excluded from the managed dependency. In the second example, artifacts with the organization `"com.example"` and the name `"foo"` cross versioned to the current `scalaVersion` are excluded. --- ivy/src/main/scala/sbt/CrossVersion.scala | 7 ++ ivy/src/main/scala/sbt/EvictionWarning.scala | 5 +- ivy/src/main/scala/sbt/Ivy.scala | 32 ++++++--- ivy/src/main/scala/sbt/IvyActions.scala | 11 +-- .../main/scala/sbt/IvyConfigurations.scala | 72 +++++++++++++++++-- ivy/src/main/scala/sbt/SbtExclusionRule.scala | 44 ++++++++++++ .../scala/sbt/impl/DependencyBuilders.scala | 8 ++- 7 files changed, 157 insertions(+), 22 deletions(-) create mode 100644 ivy/src/main/scala/sbt/SbtExclusionRule.scala diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index 79dfe091e..da37da251 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -96,6 +96,13 @@ object CrossVersion { def crossName(name: String, cross: String): String = name + "_" + cross + /** Cross-versions `exclude` according to its `crossVersion`. */ + private[sbt] def substituteCross(exclude: SbtExclusionRule, is: Option[IvyScala]): SbtExclusionRule = { + val fopt: Option[String => String] = + is flatMap { i => CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) } + exclude.copy(name = applyCross(exclude.name, fopt)) + } + /** Cross-versions `a` according to cross-version function `cross`. */ def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = a.copy(name = applyCross(a.name, cross)) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 25ad9014b..7279b77da 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -137,8 +137,9 @@ object EvictionWarning { private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { val directDependencies = module.moduleSettings match { - case x: InlineConfiguration => x.dependencies - case _ => Seq() + case x: InlineConfiguration => x.dependencies + case x: InlineConfigurationWithExcludes => x.dependencies + case _ => Seq() } val pairs = reports map { detail => val evicteds = detail.modules filter { _.evicted } diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index c0e7d508a..64afd5a40 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -163,16 +163,17 @@ final class IvySbt(val configuration: IvyConfiguration) { { val (baseModule, baseConfiguration) = moduleSettings match { - case ic: InlineConfiguration => configureInline(ic, configuration.log) - case ec: EmptyConfiguration => configureEmpty(ec) - case pc: PomConfiguration => configurePom(pc) - case ifc: IvyFileConfiguration => configureIvyFile(ifc) + case ic: InlineConfiguration => configureInline(ic.withExcludes, configuration.log) + case ic: InlineConfigurationWithExcludes => configureInline(ic, configuration.log) + case ec: EmptyConfiguration => configureEmpty(ec) + case pc: PomConfiguration => configurePom(pc) + case ifc: IvyFileConfiguration => configureIvyFile(ifc) } moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } - private def configureInline(ic: InlineConfiguration, log: Logger) = + private def configureInline(ic: InlineConfigurationWithExcludes, log: Logger) = { import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) @@ -183,6 +184,7 @@ final class IvySbt(val configuration: IvyConfiguration) { val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) IvySbt.addMainArtifact(moduleID) IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) + IvySbt.addExcludes(moduleID, excludes, ivyScala) val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) IvySbt.addDependencies(moduleID, transformedDeps, parser) (moduleID, parser.getDefaultConf) @@ -433,9 +435,10 @@ private[sbt] object IvySbt { { val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { - case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) - case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) - case _ => m + case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) + case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) + case ic: InlineConfigurationWithExcludes => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) + case _ => m } } @@ -603,6 +606,19 @@ private[sbt] object IvySbt { confs foreach addConfiguration } + def addExcludes(moduleID: DefaultModuleDescriptor, excludes: Seq[SbtExclusionRule], ivyScala: Option[IvyScala]): Unit = + excludes foreach addExclude(moduleID, ivyScala) + def addExclude(moduleID: DefaultModuleDescriptor, ivyScala: Option[IvyScala])(exclude0: SbtExclusionRule): Unit = + { + // this adds _2.11 postfix + val exclude = CrossVersion.substituteCross(exclude0, ivyScala) + val confs = + if (exclude.configurations.isEmpty) moduleID.getConfigurationsNames.toList + else exclude.configurations + val excludeRule = IvyScala.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) + moduleID.addExcludeRule(excludeRule) + } + def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = overrides foreach addOverride(moduleID, matcher) def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 3db09e636..31c104081 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -132,9 +132,10 @@ object IvyActions { } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { - case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) - case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) - case _ => None + case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) + case i: InlineConfigurationWithExcludes => CrossVersion(i.module, i.ivyScala) + case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) + case _ => None } def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = { @@ -216,7 +217,7 @@ object IvyActions { import config.{ configuration => c, ivyScala, module => mod } import mod.{ id, modules => deps } val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) + val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { case Right(r) => r case Left(w) => @@ -238,7 +239,7 @@ object IvyActions { val baseModules = modules map { m => restrictedCopy(m, true) } val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) + val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { case Right(r) => r diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index b3e1dba1b..d064006a0 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -82,15 +82,18 @@ final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], va final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { def noScala = copy(ivyScala = None) } + +// TODO: When we go sbt 1.0 we should rename InlineConfigurationWithExcludes to InlineConfiguration. +@deprecated("Use InlineConfigurationWithExcludes.", "0.13.8") final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) -} -@deprecated("Define a module using inline Scala (InlineConfiguration), a pom.xml (PomConfiguration), or an ivy.xml (IvyFileConfiguration).", "0.13.0") -final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { - def noScala = copy(ivyScala = None) + def withExcludes: InlineConfigurationWithExcludes = + InlineConfigurationWithExcludes(this.module, this.moduleInfo, this.dependencies, this.overrides, Nil, this.ivyXML, + this.configurations, this.defaultConfiguration, this.ivyScala, this.validate, this.conflictManager) } object InlineConfiguration { + @deprecated("Use InlineConfigurationWithExcludes.explicitConfigurations.", "0.13.8") def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if (explicitConfigurations.isEmpty) { defaultConfiguration match { @@ -101,6 +104,67 @@ object InlineConfiguration { } else explicitConfigurations } + +final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, + val moduleInfo: ModuleInfo, + val dependencies: Seq[ModuleID], + val overrides: Set[ModuleID] = Set.empty, + val excludes: Seq[SbtExclusionRule], + val ivyXML: NodeSeq = NodeSeq.Empty, + val configurations: Seq[Configuration] = Nil, + val defaultConfiguration: Option[Configuration] = None, + val ivyScala: Option[IvyScala] = None, + val validate: Boolean = false, + val conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { + def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) + def noScala = copy(ivyScala = None) + + def copy(module: ModuleID = this.module, + moduleInfo: ModuleInfo = this.moduleInfo, + dependencies: Seq[ModuleID] = this.dependencies, + overrides: Set[ModuleID] = this.overrides, + excludes: Seq[SbtExclusionRule] = this.excludes, + ivyXML: NodeSeq = this.ivyXML, + configurations: Seq[Configuration] = this.configurations, + defaultConfiguration: Option[Configuration] = this.defaultConfiguration, + ivyScala: Option[IvyScala] = this.ivyScala, + validate: Boolean = this.validate, + conflictManager: ConflictManager = this.conflictManager): InlineConfigurationWithExcludes = + InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, + configurations, defaultConfiguration, ivyScala, validate, conflictManager) + +} +object InlineConfigurationWithExcludes { + def apply(module: ModuleID, + moduleInfo: ModuleInfo, + dependencies: Seq[ModuleID], + overrides: Set[ModuleID] = Set.empty, + excludes: Seq[SbtExclusionRule] = Nil, + ivyXML: NodeSeq = NodeSeq.Empty, + configurations: Seq[Configuration] = Nil, + defaultConfiguration: Option[Configuration] = None, + ivyScala: Option[IvyScala] = None, + validate: Boolean = false, + conflictManager: ConflictManager = ConflictManager.default): InlineConfigurationWithExcludes = + new InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, + configurations, defaultConfiguration, ivyScala, validate, conflictManager) + + def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = + if (explicitConfigurations.isEmpty) { + defaultConfiguration match { + case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil + case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations + case _ => Nil + } + } else + explicitConfigurations +} + +@deprecated("Define a module using inline Scala (InlineConfiguration), a pom.xml (PomConfiguration), or an ivy.xml (IvyFileConfiguration).", "0.13.0") +final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { + def noScala = copy(ivyScala = None) +} + object ModuleSettings { @deprecated("Explicitly select configuration from pom.xml, ivy.xml, or inline Scala.", "0.13.0") def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = diff --git a/ivy/src/main/scala/sbt/SbtExclusionRule.scala b/ivy/src/main/scala/sbt/SbtExclusionRule.scala new file mode 100644 index 000000000..6e897a16b --- /dev/null +++ b/ivy/src/main/scala/sbt/SbtExclusionRule.scala @@ -0,0 +1,44 @@ +package sbt + +import sbt.impl.{ GroupID, GroupArtifactID } + +final class SbtExclusionRule( + val organization: String, + val name: String, + val artifact: String, + val configurations: Seq[String], + val crossVersion: CrossVersion) { + + def copy(organization: String = this.organization, + name: String = this.name, + artifact: String = this.artifact, + configurations: Seq[String] = this.configurations, + crossVersion: CrossVersion = this.crossVersion): SbtExclusionRule = + SbtExclusionRule(organization = organization, + name = name, + artifact = artifact, + configurations = configurations, + crossVersion = crossVersion) +} + +object SbtExclusionRule { + def apply(organization: String): SbtExclusionRule = + new SbtExclusionRule(organization, "*", "*", Nil, CrossVersion.Disabled) + + def apply(organization: String, name: String): SbtExclusionRule = + new SbtExclusionRule(organization, name, "*", Nil, CrossVersion.Disabled) + + def apply(organization: String, + name: String, + artifact: String, + configurations: Seq[String], + crossVersion: CrossVersion): SbtExclusionRule = + new SbtExclusionRule(organization, name, artifact, configurations, crossVersion) + + implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = + SbtExclusionRule(organization.groupID) + implicit def stringToExclusionRule(organization: String): SbtExclusionRule = + SbtExclusionRule(organization) + implicit def groupArtifactIDToExcludsionRule(gaid: GroupArtifactID): SbtExclusionRule = + SbtExclusionRule(gaid.groupID, gaid.artifactID, "*", Nil, gaid.crossVersion) +} diff --git a/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala b/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala index 16a1fa504..c449393f7 100755 --- a/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala +++ b/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala @@ -24,7 +24,7 @@ trait DependencyBuilders { } } -final class GroupID private[sbt] (groupID: String) { +final class GroupID private[sbt] (private[sbt] val groupID: String) { def %(artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) @@ -38,10 +38,12 @@ final class GroupID private[sbt] (groupID: String) { nonEmpty(artifactID, "Artifact ID") new GroupArtifactID(groupID, artifactID, cross) } - private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" } -final class GroupArtifactID private[sbt] (groupID: String, artifactID: String, crossVersion: CrossVersion) { +final class GroupArtifactID private[sbt] ( + private[sbt] val groupID: String, + private[sbt] val artifactID: String, + private[sbt] val crossVersion: CrossVersion) { def %(revision: String): ModuleID = { nonEmpty(revision, "Revision") From ca6b138a68049f32390c043b2c75b3b9a3ee58cc Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 8 Dec 2014 09:27:56 -0500 Subject: [PATCH 0377/1030] Fixes #1620. Fixes Set[ModuleID] serialization that broke update cache. --- .../main/scala/sbt/IvyConfigurations.scala | 81 +++++++++++++++++-- ivy/src/main/scala/sbt/Resolver.scala | 13 +++ ivy/src/main/scala/sbt/UpdateOptions.scala | 17 ++++ .../scala/sbt/ivyint/SbtChainResolver.scala | 27 ++++++- 4 files changed, 129 insertions(+), 9 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index d064006a0..3c695f71a 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -34,12 +34,42 @@ final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resol checksums: Seq[String], resolutionCacheDir: Option[File], log: Logger) = this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, UpdateOptions(), log) + override def toString: String = s"InlineIvyConfiguration($paths, $resolvers, $otherResolvers, " + + s"$moduleConfigurations, $localOnly, $checksums, $resolutionCacheDir, $updateOptions)" + type This = InlineIvyConfiguration def baseDirectory = paths.baseDirectory def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, updateOptions, log) def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, updateOptions, log) + + override def equals(o: Any): Boolean = o match { + case o: InlineIvyConfiguration => + this.paths == o.paths && + this.resolvers == o.resolvers && + this.otherResolvers == o.otherResolvers && + this.moduleConfigurations == o.moduleConfigurations && + this.localOnly == o.localOnly && + this.checksums == o.checksums && + this.resolutionCacheDir == o.resolutionCacheDir && + this.updateOptions == o.updateOptions + case _ => false + } + + override def hashCode: Int = + { + var hash = 1 + hash = hash * 31 + this.paths.## + hash = hash * 31 + this.resolvers.## + hash = hash * 31 + this.otherResolvers.## + hash = hash * 31 + this.moduleConfigurations.## + hash = hash * 31 + this.localOnly.## + hash = hash * 31 + this.checksums.## + hash = hash * 31 + this.resolutionCacheDir.## + hash = hash * 31 + this.updateOptions.## + hash + } } final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration { @@ -108,18 +138,18 @@ object InlineConfiguration { final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, val moduleInfo: ModuleInfo, val dependencies: Seq[ModuleID], - val overrides: Set[ModuleID] = Set.empty, + val overrides: Set[ModuleID], val excludes: Seq[SbtExclusionRule], - val ivyXML: NodeSeq = NodeSeq.Empty, - val configurations: Seq[Configuration] = Nil, - val defaultConfiguration: Option[Configuration] = None, - val ivyScala: Option[IvyScala] = None, - val validate: Boolean = false, - val conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { + val ivyXML: NodeSeq, + val configurations: Seq[Configuration], + val defaultConfiguration: Option[Configuration], + val ivyScala: Option[IvyScala], + val validate: Boolean, + val conflictManager: ConflictManager) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) - def copy(module: ModuleID = this.module, + private[sbt] def copy(module: ModuleID = this.module, moduleInfo: ModuleInfo = this.moduleInfo, dependencies: Seq[ModuleID] = this.dependencies, overrides: Set[ModuleID] = this.overrides, @@ -133,6 +163,41 @@ final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, ivyScala, validate, conflictManager) + override def toString: String = + s"InlineConfigurationWithExcludes($module, $moduleInfo, $dependencies, $overrides, $excludes, " + + s"$ivyXML, $configurations, $defaultConfiguration, $ivyScala, $validate, $conflictManager)" + + override def equals(o: Any): Boolean = o match { + case o: InlineConfigurationWithExcludes => + this.module == o.module && + this.moduleInfo == o.moduleInfo && + this.dependencies == o.dependencies && + this.overrides == o.overrides && + this.excludes == o.excludes && + this.ivyXML == o.ivyXML && + this.configurations == o.configurations && + this.defaultConfiguration == o.defaultConfiguration && + this.ivyScala == o.ivyScala && + this.validate == o.validate && + this.conflictManager == o.conflictManager + case _ => false + } + + override def hashCode: Int = + { + var hash = 1 + hash = hash * 31 + this.module.## + hash = hash * 31 + this.dependencies.## + hash = hash * 31 + this.overrides.## + hash = hash * 31 + this.excludes.## + hash = hash * 31 + this.ivyXML.## + hash = hash * 31 + this.configurations.## + hash = hash * 31 + this.defaultConfiguration.## + hash = hash * 31 + this.ivyScala.## + hash = hash * 31 + this.validate.## + hash = hash * 31 + this.conflictManager.## + hash + } } object InlineConfigurationWithExcludes { def apply(module: ModuleID, diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index c7e67f876..406c27e78 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -15,6 +15,19 @@ sealed trait Resolver { final class RawRepository(val resolver: DependencyResolver) extends Resolver { def name = resolver.getName override def toString = "Raw(" + resolver.toString + ")" + + override def equals(o: Any): Boolean = o match { + case o: RawRepository => + this.name == o.name + case _ => false + } + + override def hashCode: Int = + { + var hash = 1 + hash = hash * 31 + this.name.## + hash + } } sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver sealed case class MavenRepository(name: String, root: String) extends Resolver { diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index 2f7ad26ec..1d4688481 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -40,6 +40,23 @@ final class UpdateOptions private[sbt] ( latestSnapshots, consolidatedResolution, cachedResolution) + + override def equals(o: Any): Boolean = o match { + case o: UpdateOptions => + this.circularDependencyLevel == o.circularDependencyLevel && + this.latestSnapshots == o.latestSnapshots && + this.cachedResolution == o.cachedResolution + case _ => false + } + + override def hashCode: Int = + { + var hash = 1 + hash = hash * 31 + this.circularDependencyLevel.## + hash = hash * 31 + this.latestSnapshots.## + hash = hash * 31 + this.cachedResolution.## + hash + } } object UpdateOptions { diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 46bb35f60..a4d60c997 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -16,7 +16,32 @@ import org.apache.ivy.plugins.resolver.{ ChainResolver, BasicResolver, Dependenc import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } -class SbtChainResolver(name: String, resolvers: Seq[DependencyResolver], settings: IvySettings, updateOptions: UpdateOptions, log: Logger) extends ChainResolver { +private[sbt] case class SbtChainResolver( + name: String, + resolvers: Seq[DependencyResolver], + settings: IvySettings, + updateOptions: UpdateOptions, + log: Logger) extends ChainResolver { + + override def equals(o: Any): Boolean = o match { + case o: SbtChainResolver => + this.name == o.name && + this.resolvers == o.resolvers && + this.settings == o.settings && + this.updateOptions == o.updateOptions + case _ => false + } + + override def hashCode: Int = + { + var hash = 1 + hash = hash * 31 + this.name.## + hash = hash * 31 + this.resolvers.## + hash = hash * 31 + this.settings.## + hash = hash * 31 + this.updateOptions.## + hash + } + // TODO - We need to special case the project resolver so it always "wins" when resolving with inter-project dependencies. // Initialize ourselves. From 08e9230aeb0bbc2e94395f6ebc2993ff263ef0ef Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Dec 2014 17:46:19 -0500 Subject: [PATCH 0378/1030] Fixes #1615. Move the invocation of eviction warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This moves the invocation of eviction warning so it’s called only when actual ivy update is being performed. --- ivy/src/main/scala/sbt/EvictionWarning.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 7279b77da..38d626a86 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -41,6 +41,8 @@ final class EvictionWarningOptions private[sbt] ( } object EvictionWarningOptions { + def empty: EvictionWarningOptions = + new EvictionWarningOptions(Vector(), false, false, false, false, defaultGuess) def default: EvictionWarningOptions = new EvictionWarningOptions(Vector(Compile), true, true, false, false, defaultGuess) def full: EvictionWarningOptions = From ccef278865549b3c5c174bf4fae9567ab98eb80e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Dec 2014 23:30:05 -0500 Subject: [PATCH 0379/1030] 'evicted' task to display all evictions --- ivy/src/main/scala/sbt/EvictionWarning.scala | 41 ++++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/ivy/src/main/scala/sbt/EvictionWarning.scala index 38d626a86..0e0234de5 100644 --- a/ivy/src/main/scala/sbt/EvictionWarning.scala +++ b/ivy/src/main/scala/sbt/EvictionWarning.scala @@ -9,6 +9,7 @@ final class EvictionWarningOptions private[sbt] ( val warnScalaVersionEviction: Boolean, val warnDirectEvictions: Boolean, val warnTransitiveEvictions: Boolean, + val infoAllEvictions: Boolean, val showCallers: Boolean, val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { private[sbt] def configStrings = configurations map { _.name } @@ -21,6 +22,8 @@ final class EvictionWarningOptions private[sbt] ( copy(warnDirectEvictions = warnDirectEvictions) def withWarnTransitiveEvictions(warnTransitiveEvictions: Boolean): EvictionWarningOptions = copy(warnTransitiveEvictions = warnTransitiveEvictions) + def withInfoAllEvictions(infoAllEvictions: Boolean): EvictionWarningOptions = + copy(infoAllEvictions = infoAllEvictions) def withShowCallers(showCallers: Boolean): EvictionWarningOptions = copy(showCallers = showCallers) def withGuessCompatible(guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]): EvictionWarningOptions = @@ -30,23 +33,25 @@ final class EvictionWarningOptions private[sbt] ( warnScalaVersionEviction: Boolean = warnScalaVersionEviction, warnDirectEvictions: Boolean = warnDirectEvictions, warnTransitiveEvictions: Boolean = warnTransitiveEvictions, + infoAllEvictions: Boolean = infoAllEvictions, showCallers: Boolean = showCallers, guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible): EvictionWarningOptions = new EvictionWarningOptions(configurations = configurations, warnScalaVersionEviction = warnScalaVersionEviction, warnDirectEvictions = warnDirectEvictions, warnTransitiveEvictions = warnTransitiveEvictions, + infoAllEvictions = infoAllEvictions, showCallers = showCallers, guessCompatible = guessCompatible) } object EvictionWarningOptions { def empty: EvictionWarningOptions = - new EvictionWarningOptions(Vector(), false, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(), false, false, false, false, false, defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, false, false, defaultGuess) + new EvictionWarningOptions(Vector(Compile), true, true, false, false, false, defaultGuess) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, true, true, defaultGuess) + new EvictionWarningOptions(Vector(Compile), true, true, true, true, true, defaultGuess) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse @@ -80,6 +85,18 @@ final class EvictionPair private[sbt] ( val showCallers: Boolean) { override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString + override def equals(o: Any): Boolean = o match { + case o: EvictionPair => + (this.organization == o.organization) && + (this.name == o.name) + case _ => false + } + override def hashCode: Int = { + var hash = 1 + hash = hash * 31 + this.organization.## + hash = hash * 31 + this.name.## + hash + } } object EvictionPair { @@ -107,6 +124,7 @@ final class EvictionWarning private[sbt] ( val transitiveEvictions: Seq[EvictionPair], val allEvictions: Seq[EvictionPair]) { def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions + private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) } object EvictionWarning { @@ -203,4 +221,21 @@ object EvictionWarning { out.toList } + + private[sbt] def infoAllTheThings(a: EvictionWarning): List[String] = + if (a.options.infoAllEvictions) { + import ShowLines._ + val evo = a.options + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + a.allEvictions foreach { ev => + if ((a.scalaEvictions contains ev) && evo.warnScalaVersionEviction) () + else if ((a.directEvictions contains ev) && evo.warnDirectEvictions) () + else if ((a.transitiveEvictions contains ev) && evo.warnTransitiveEvictions) () + else { + out ++= ev.lines + } + } + if (out.isEmpty) Nil + else List("Here are other libraries that were evicted:") ::: out.toList + } else Nil } From 80db26bc20e7f2a2619115a1d9e61e92c2c8f179 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 14 Dec 2014 07:52:05 -0500 Subject: [PATCH 0380/1030] Fixes #1634. Adds inconsistent duplicate warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #1634 is about a library getting wiped out of deps graph when it’s included twice in ascending order of version. I’d say that’s a logically inconsistent state, and we should just issue warning instead of trying to fix it. --- ivy/src/main/scala/sbt/Ivy.scala | 23 +++++++++++++++ ivy/src/main/scala/sbt/IvyActions.scala | 4 +++ .../scala/InconsistentDuplicateSpec.scala | 28 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 ivy/src/test/scala/InconsistentDuplicateSpec.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 64afd5a40..32f2f6440 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -527,6 +527,29 @@ private[sbt] object IvySbt { parser } + def inconsistentDuplicateWarning(moduleID: DefaultModuleDescriptor): List[String] = + { + import IvyRetrieve.toModuleID + val dds = moduleID.getDependencies + inconsistentDuplicateWarning(dds map { dd => toModuleID(dd.getDependencyRevisionId) }) + } + + def inconsistentDuplicateWarning(dependencies: Seq[ModuleID]): List[String] = + { + val warningHeader = "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:" + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + (dependencies groupBy { dep => (dep.organization, dep.name) }) foreach { + case (k, vs) if vs.size > 1 => + val v0 = vs.head + (vs find { _.revision != v0.revision }) foreach { v => + out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }).mkString(", ") + ")" + } + case _ => () + } + if (out.isEmpty) Nil + else warningHeader :: out.toList + } + /** This method is used to add inline dependencies to the provided module. */ def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) { val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 31c104081..dcf393517 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -166,6 +166,8 @@ object IvyActions { case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined => ivy.getResolveEngine match { case x: CachedResolutionResolveEngine => + val iw = IvySbt.inconsistentDuplicateWarning(md) + iw foreach { log.warn(_) } val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(md) resolveOptions.setResolveId(resolveId) @@ -181,6 +183,8 @@ object IvyActions { } } case (ivy, md, default) => + val iw = IvySbt.inconsistentDuplicateWarning(md) + iw foreach { log.warn(_) } val (report, err) = resolve(configuration.logging)(ivy, md, default) err match { case Some(x) if !configuration.missingOk => diff --git a/ivy/src/test/scala/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/InconsistentDuplicateSpec.scala new file mode 100644 index 000000000..b9f4a05ef --- /dev/null +++ b/ivy/src/test/scala/InconsistentDuplicateSpec.scala @@ -0,0 +1,28 @@ +package sbt + +import org.specs2._ + +class InconsistentDuplicateSpec extends Specification { + def is = s2""" + + This is a specification to check the inconsistent duplicate warnings + + Duplicate with different version should + be warned $warn1 + + Duplicate with same version should + not be warned $nodupe1 + """ + + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary + def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary + def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("test")) cross CrossVersion.binary + + def warn1 = + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) must_== + List("Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", + " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)") + + def nodupe1 = + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) must_== Nil +} From 4403863aca966e1c3c1bf05f7070e1ad837bf658 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 16 Dec 2014 13:14:14 -0500 Subject: [PATCH 0381/1030] Create a new Ivy DependencyResolver which uses Aether. * Here we wire Aether into the Ivy dependency chain * Add hooks into Aether to use Ivy's http library (so credentials are configured the same) * Create the actual Resolver which extracts metadata information from Aether * Deprecate old Ivy-Maven integrations * Create hooks in existing Resolver facilities to expose a flag to enable the new behavior. * Create notes documenting the feature. * Create a new resolver type `MavenCache` which denotes how to read/write local maven cache metadata correctly. We use this type for publishM2 and mavenLocal. * Update failing -SNAPSHOT related tests to use new Aether resolver * Create specification for expected behavior from the new resolvers. Known to fix #1322, #321, #647, #1616 --- .../ReplaceMavenConfigurationMappings.scala | 5 + .../resolver/MavenRepositoryResolver.scala | 656 ++++++++++++++++++ .../MavenRepositorySystemFactory.scala | 140 ++++ .../internal/SbtArtifactDescriptorReader.java | 556 +++++++++++++++ .../internal/SbtExtraProperties.java | 23 + .../internal/SbtRepositoryLayout.scala | 100 +++ ivy/src/main/scala/sbt/ConvertResolver.scala | 33 +- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 + ivy/src/main/scala/sbt/Ivy.scala | 11 +- ivy/src/main/scala/sbt/MakePom.scala | 2 + ivy/src/main/scala/sbt/Resolver.scala | 20 +- ivy/src/main/scala/sbt/UpdateOptions.scala | 18 +- .../scala/sbt/ivyint/SbtChainResolver.scala | 31 +- ivy/src/test/scala/BaseIvySpecification.scala | 29 +- ivy/src/test/scala/MavenResolutionSpec.scala | 291 ++++++++ 15 files changed, 1884 insertions(+), 33 deletions(-) create mode 100644 ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala create mode 100644 ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala create mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java create mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java create mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala create mode 100644 ivy/src/test/scala/MavenResolutionSpec.scala diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index 68a9dad40..0e85d5b6b 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -26,6 +26,11 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; */ object ReplaceMavenConfigurationMappings { + def addMappings(dd: DefaultDependencyDescriptor, scope: String, isOptional: Boolean) = { + val mapping = ReplaceMavenConfigurationMappings.REPLACEMENT_MAVEN_MAPPINGS.get(scope) + mapping.addMappingConfs(dd, isOptional) + } + val REPLACEMENT_MAVEN_MAPPINGS = { // Here we copy paste from Ivy val REPLACEMENT_MAPPINGS = new java.util.HashMap[String, PomModuleDescriptorBuilder.ConfMapper] diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala new file mode 100644 index 000000000..253830e6e --- /dev/null +++ b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala @@ -0,0 +1,656 @@ +package org.apache.ivy.plugins.resolver + +import java.io.{ File, IOException } +import java.text.ParseException +import java.util.Date +import org.apache.ivy.core.IvyContext +import org.apache.ivy.core.module.descriptor._ +import org.apache.ivy.core.module.id.{ ModuleId, ArtifactId, ModuleRevisionId } +import org.apache.ivy.core.report.{ ArtifactDownloadReport, DownloadStatus, MetadataArtifactDownloadReport, DownloadReport } +import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData, DownloadOptions } +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.matcher.ExactPatternMatcher +import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorBuilder, ReplaceMavenConfigurationMappings } +import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter +import org.apache.ivy.plugins.resolver.MavenRepositoryResolver.JarPackaging +import org.apache.ivy.plugins.resolver.util.ResolvedResource +import org.apache.ivy.util.Message +import org.apache.maven.repository.internal.{ SbtRepositoryLayout, SbtExtraProperties } +import org.eclipse.aether.{ RepositorySystemSession, RepositorySystem } +import org.eclipse.aether.artifact.{ DefaultArtifact => AetherArtifact } +import org.eclipse.aether.metadata.{ Metadata, DefaultMetadata } +import org.eclipse.aether.resolution.{ + ArtifactDescriptorRequest => AetherDescriptorRequest, + ArtifactDescriptorResult => AetherDescriptorResult, + MetadataRequest => AetherMetadataRequest, + ArtifactRequest => AetherArtifactRequest, + ArtifactResolutionException +} +import org.eclipse.aether.deployment.{ DeployRequest => AetherDeployRequest } +import org.eclipse.aether.installation.{ InstallRequest => AetherInstallRequest } +import org.apache.ivy.core.cache.{ ModuleDescriptorWriter, ArtifactOrigin } +import sbt.{ CustomPomParser, MavenCache, MavenRepository } +import scala.collection.JavaConverters._ + +object MavenRepositoryResolver { + val MAVEN_METADATA_XML = "maven-metadata.xml" + val CLASSIFIER_ATTRIBUTE = "e:classifier" + + val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar", "jar", "bundle") + + object JarPackaging { + def unapply(in: String): Boolean = JarPackagings.contains(in) + } + + // Example: 2014 12 18 09 33 56 + val LAST_UPDATE_FORMAT = new java.text.SimpleDateFormat("yyyyMMddhhmmss") + def parseTimeString(in: String): Option[Long] = + try Some(LAST_UPDATE_FORMAT.parse(in).getTime) + catch { + case _: java.text.ParseException => None + } + + val DEFAULT_ARTIFACT_CONFIGURATION = "master" + +} + +/** + * A resolver instance which can resolve from a REMOTE maven repository. + * + * Note: This creates its *own* local cache directory for cache metadata. using its name. + * + */ +class MavenRemoteRepositoryResolver(val repo: MavenRepository, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { + setName(repo.name) + override def toString = s"${repo.name}: ${repo.root}" + protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl + // Note: All maven repository resolvers will use the SAME maven cache. + // We're not sure if we care whether or not this means that the wrong resolver may report finding an artifact. + // The key is not to duplicate files repeatedly across many caches. + private val localRepo = new java.io.File(settings.getDefaultIvyUserDir, s"maven-cache") + sbt.IO.createDirectory(localRepo) + protected val session = MavenRepositorySystemFactory.newSessionImpl(system, localRepo) + private val aetherRepository = { + new org.eclipse.aether.repository.RemoteRepository.Builder(repo.name, SbtRepositoryLayout.LAYOUT_NAME, repo.root).build() + } + // TODO - Check if isUseCacheOnly is used correctly. + private def isUseCacheOnly: Boolean = + Option(IvyContext.getContext).flatMap(x => Option(x.getResolveData)).flatMap(x => Option(x.getOptions)).map(_.isUseCacheOnly).getOrElse(false) + protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest = + if (isUseCacheOnly) request else request.addRepository(aetherRepository) + protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest = + if (isUseCacheOnly) request else request.addRepository(aetherRepository) + /** Actually publishes aether artifacts. */ + protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit = { + val request = new AetherDeployRequest() + request.setRepository(aetherRepository) + artifacts foreach request.addArtifact + system.deploy(session, request) + } + protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] = { + val metadataRequest = new AetherMetadataRequest() + metadataRequest.setMetadata( + new DefaultMetadata( + mrid.getOrganisation, + mrid.getName, + mrid.getRevision, + MavenRepositoryResolver.MAVEN_METADATA_XML, + Metadata.Nature.RELEASE_OR_SNAPSHOT)) + if (!isUseCacheOnly) metadataRequest.setRepository(aetherRepository) + val metadataResultOpt = + try system.resolveMetadata(session, java.util.Arrays.asList(metadataRequest)).asScala.headOption + catch { + case e: org.eclipse.aether.resolution.ArtifactResolutionException => None + } + try metadataResultOpt match { + case Some(md) if md.isResolved => + import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader + import org.codehaus.plexus.util.ReaderFactory + val readMetadata = { + val reader = ReaderFactory.newXmlReader(md.getMetadata.getFile) + try new MetadataXpp3Reader().read(reader, false) + finally reader.close() + } + val timestampOpt = + for { + v <- Option(readMetadata.getVersioning) + sp <- Option(v.getSnapshot) + ts <- Option(sp.getTimestamp) + t <- MavenRepositoryResolver.parseTimeString(ts) + } yield t + val lastUpdatedOpt = + for { + v <- Option(readMetadata.getVersioning) + lu <- Option(v.getLastUpdated) + d <- MavenRepositoryResolver.parseTimeString(lu) + } yield d + // TODO - Only look at timestamp *IF* the version is for a snapshot. + timestampOpt orElse lastUpdatedOpt + case _ => None + } + } +} + +/** + * A resolver instance which can resolve from a maven CACHE. + * + * Note: This should never hit somethign remote, as it just looks in the maven cache for things already resolved. + */ +class MavenCacheRepositoryResolver(val repo: MavenCache, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { + setName(repo.name) + protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl + sbt.IO.createDirectory(repo.rootFile) + protected val session = MavenRepositorySystemFactory.newSessionImpl(system, repo.rootFile) + protected def setRepository(request: AetherMetadataRequest): AetherMetadataRequest = request + protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest = request + protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest = request + protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit = { + val request = new AetherInstallRequest() + artifacts foreach request.addArtifact + system.install(session, request) + } + // TODO - Share this with non-local repository code, since it's MOSTLY the same. + protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] = { + val metadataRequest = new AetherMetadataRequest() + metadataRequest.setMetadata( + new DefaultMetadata( + mrid.getOrganisation, + mrid.getName, + mrid.getRevision, + MavenRepositoryResolver.MAVEN_METADATA_XML, + Metadata.Nature.RELEASE_OR_SNAPSHOT)) + val metadataResultOpt = + try system.resolveMetadata(session, java.util.Arrays.asList(metadataRequest)).asScala.headOption + catch { + case e: org.eclipse.aether.resolution.ArtifactResolutionException => None + } + try metadataResultOpt match { + case Some(md) if md.isResolved => + import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader + import org.codehaus.plexus.util.ReaderFactory + val readMetadata = { + val reader = ReaderFactory.newXmlReader(md.getMetadata.getFile) + try new MetadataXpp3Reader().read(reader, false) + finally reader.close() + } + val timestampOpt = + for { + v <- Option(readMetadata.getVersioning) + sp <- Option(v.getSnapshot) + ts <- Option(sp.getTimestamp) + t <- MavenRepositoryResolver.parseTimeString(ts) + } yield t + val lastUpdatedOpt = + for { + v <- Option(readMetadata.getVersioning) + lu <- Option(v.getLastUpdated) + d <- MavenRepositoryResolver.parseTimeString(lu) + } yield d + // TODO - Only look at timestamp *IF* the version is for a snapshot. + timestampOpt orElse lastUpdatedOpt + case _ => None + } + } + override def toString = s"${repo.name}: ${repo.root}" +} + +/** An exception we can throw if we encounter issues. */ +class MavenResolutionException(msg: String) extends RuntimeException(msg) {} + +abstract class AbstractMavenRepositoryResolver(settings: IvySettings) extends AbstractResolver { + + /** Our instance of the aether repository system. */ + protected val system: RepositorySystem + /** + * Our instance of the aether repository system session. + * + * TODO - We may want to tie this into an IvyContext. + */ + protected val session: RepositorySystemSession + + /** Determine the publication time of a module. The mechanism may differ if the repository is remote vs. local. */ + protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] + /** Inject necessary repositories into a descriptor request. */ + protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest + protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest + + /** Actually publishes aether artifacts. */ + protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit + + // TOOD - deal with packaging here. + private def aetherArtifactIdFromMrid(mrid: ModuleRevisionId): String = + getSbtVersion(mrid) match { + case Some(sbt) => s"${mrid.getName}_sbt_$sbt" + case None => mrid.getName + } + private def aetherCoordsFromMrid(mrid: ModuleRevisionId): String = + s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:${mrid.getRevision}" + + private def aetherCoordsFromMrid(mrid: ModuleRevisionId, packaging: String): String = + s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:$packaging:${mrid.getRevision}" + + private def aetherCoordsFromMrid(mrid: ModuleRevisionId, packaging: String, extension: String): String = + s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:$extension:$packaging:${mrid.getRevision}" + + // Handles appending licenses to the module descriptor fromthe pom. + private def addLicenseInfo(md: DefaultModuleDescriptor, map: java.util.Map[String, AnyRef]) = { + val count = map.get(SbtExtraProperties.LICENSE_COUNT_KEY) match { + case null => 0 + case x: java.lang.Integer => x.intValue + case x: String => x.toInt + case _ => 0 + } + for { + i <- 0 until count + name <- Option(map.get(SbtExtraProperties.makeLicenseName(i))).map(_.toString) + url <- Option(map.get(SbtExtraProperties.makeLicenseUrl(i))).map(_.toString) + } md.addLicense(new License(name, url)) + } + + // This grabs the dependency for Ivy. + override def getDependency(dd: DependencyDescriptor, rd: ResolveData): ResolvedModuleRevision = { + val context = IvyContext.pushNewCopyContext + try { + // TODO - Check to see if we're asking for latest.* version, and if so, we should run a latest version query + // first and use that result to return the metadata/final module. + Message.debug(s"Requesting conf [${dd.getModuleConfigurations.mkString(",")}] from Aether module ${dd.getDependencyRevisionId} in resolver ${getName}") + val request = new AetherDescriptorRequest() + val coords = aetherCoordsFromMrid(dd.getDependencyRevisionId) + Message.debug(s"Aether about to resolve [$coords]...") + request.setArtifact(new AetherArtifact(coords, getArtifactProperties(dd.getDependencyRevisionId))) + addRepositories(request) + val result = system.readArtifactDescriptor(session, request) + val packaging = getPackagingFromPomProperties(result.getProperties) + Message.debug(s"Aether resolved ${dd.getDependencyId} w/ packaging ${packaging}") + + // TODO - better pub date if we have no metadata. + val lastModifiedTime = getPublicationTime(dd.getDependencyRevisionId) getOrElse 0L + + // Construct a new Ivy module descriptor + val desc: ModuleDescriptor = { + // TODO - Better detection of snapshot and handling latest.integration/latest.snapshot + val status = + if (dd.getDependencyRevisionId.getRevision.endsWith("-SNAPSHOT")) "integration" + else "release" + val md = + new DefaultModuleDescriptor(dd.getDependencyRevisionId, status, null /* pubDate */ , false) + //DefaultModuleDescriptor.newDefaultInstance(dd.getDependencyRevisionId) + // Here we add the standard configurations + for (config <- PomModuleDescriptorBuilder.MAVEN2_CONFIGURATIONS) { + md.addConfiguration(config) + } + + // Here we look into the artifacts specified from the dependency descriptor *and* those that are defaulted, + // and append them to the appropriate configurations. + addArtifactsFromPom(dd, packaging, md, lastModifiedTime) + // Here we add dependencies. + addDependenciesFromAether(result, md) + // Here we use pom.xml Dependency management section to create Ivy dependency mediators. + addManagedDependenciesFromAether(result, md) + // TODO - Add excludes? + + // Here we rip out license info. + addLicenseInfo(md, result.getProperties) + md.addExtraInfo(SbtExtraProperties.MAVEN_PACKAGING_KEY, packaging) + Message.debug(s"Setting publication date to ${new Date(lastModifiedTime)}") + // TODO - Figure out the differences between these items. + md.setPublicationDate(new Date(lastModifiedTime)) + md.setLastModified(lastModifiedTime) + md.setResolvedPublicationDate(new Date(lastModifiedTime)) + md.check() + // TODO - do we need the toSystem? + toSystem(md) + } + + // Here we need to pretend we downloaded the pom.xml file + val pom = DefaultArtifact.newPomArtifact(dd.getDependencyRevisionId, new java.util.Date(lastModifiedTime)) + val madr = new MetadataArtifactDownloadReport(pom) + madr.setSearched(true) + madr.setDownloadStatus(DownloadStatus.SUCCESSFUL) // TODO - Figure this things out for this report. + val rmr = new ResolvedModuleRevision(this, this, desc, madr, false /* Force */ ) + + // TODO - Here we cache the transformed pom.xml into an ivy.xml in the cache because ChainResolver will be looking at it. + // This doesn't appear to really work correctly. + // However, I think the chain resolver doesn't use this instance anyway. Ideally we don't put anything + // in the ivy cache, but this should be "ok". + getRepositoryCacheManager.originalToCachedModuleDescriptor(this, + null /* ivyRef. Just passed back to us. */ , + pom, + rmr, + new ModuleDescriptorWriter() { + def write(originalMdResource: ResolvedResource, md: ModuleDescriptor, src: File, dest: File): Unit = { + // a basic ivy file is written containing default data + XmlModuleDescriptorWriter.write(md, dest); + } + } + ) + rmr + } catch { + case e: org.eclipse.aether.resolution.ArtifactDescriptorException => + Message.warn(s"Failed to read descriptor ${dd} from ${getName}, ${e.getMessage}") + e.printStackTrace(System.err) + rd.getCurrentResolvedModuleRevision + case e: MavenResolutionException => + Message.debug(s"Resolution Exception from ${getName}, ${e.getMessage}, returning: ${rd.getCurrentResolvedModuleRevision}") + rd.getCurrentResolvedModuleRevision + } finally IvyContext.popContext() + } + + def getSbtVersion(dd: ModuleRevisionId): Option[String] = + Option(dd.getExtraAttribute(CustomPomParser.SbtVersionKey)) + + def getArtifactProperties(dd: ModuleRevisionId): java.util.Map[String, String] = { + val m = new java.util.HashMap[String, String] + Option(dd.getExtraAttribute(CustomPomParser.ScalaVersionKey)) foreach { sv => + m.put(SbtExtraProperties.POM_SCALA_VERSION, sv) + } + getSbtVersion(dd) foreach { sv => + m.put(SbtExtraProperties.POM_SBT_VERSION, sv) + } + m + } + + final def checkJarArtifactExists(dd: DependencyDescriptor): Boolean = { + // TODO - We really want this to be as fast/efficient as possible! + val request = new AetherArtifactRequest() + val art = new AetherArtifact( + aetherCoordsFromMrid(dd.getDependencyRevisionId, "jar"), + getArtifactProperties(dd.getDependencyRevisionId)) + request.setArtifact(art) + addRepositories(request) + try { + val result = system.resolveArtifact(session, request) + result.isResolved && !result.isMissing + } catch { + case e: ArtifactResolutionException => + // Ignore, as we're just working around issues with pom.xml's with no jars or POM packaging + Message.debug(s"Could not find $art in ${getName}") + false + } + } + + /** Determines which artifacts are associated with this maven module and appends them to the descriptor. */ + def addArtifactsFromPom(dd: DependencyDescriptor, packaging: String, md: DefaultModuleDescriptor, lastModifiedTime: Long): Unit = { + Message.debug(s"Calculating artifacts for ${dd.getDependencyId} w/ packaging $packaging") + // Here we add in additional artifact requests, which ALLWAYS have to be explicit since + // Maven/Aether doesn't include all known artifacts in a pom.xml + // TODO - This does not appear to be working correctly. + if (dd.getAllDependencyArtifacts.isEmpty) { + val artifactId = s"${dd.getDependencyId.getName}-${dd.getDependencyRevisionId.getRevision}" + // Add the artifacts we know about the module + packaging match { + case "pom" => + // THere we have to attempt to download the JAR and see if it comes, if not, we can punt. + // This is because sometimes pom-packaging attaches a JAR. + if (checkJarArtifactExists(dd)) { + val defaultArt = + new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), artifactId, packaging, "jar") + md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) + } + case JarPackaging() => + // Here we fail the resolution. This is an issue when pom.xml files exist with no JAR, which happens + // on maven central for some reason on old artifacts. + if (!checkJarArtifactExists(dd)) + throw new MavenResolutionException(s"Failed to find JAR file associated with $dd") + // Assume for now everything else is a jar. + val defaultArt = + new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), artifactId, packaging, "jar") + // TODO - Unfortunately we have to try to download the JAR file HERE and then fail resolution if we cannot find it. + // This is because sometime a pom.xml exists with no JARs. + md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) + case _ => // Ignore, we have no idea what this artifact is. + Message.warn(s"Not adding artifacts for resolution because we don't understand packaging: $packaging") + } + + } else { + // NOTE: this means that someone is requested specific artifacts from us. What we need to do is *only* download the + // requested artifacts rather than the default "jar". What's odd, is that pretty much this almost ALWAYS happens. + // but in some circumstances, the above logic is checked. + // Additionally, we may want to somehow merge the "defined" artifacts from maven with the requested ones here, rather + // than having completely separate logic. For now, this appears to work the same way it was before. + // Since we aren't accurately guessing what maven files are meant to be included as artifacts ANYWAY, this + // is probably the right way to go. + for (requestedArt <- dd.getAllDependencyArtifacts) { + getClassifier(requestedArt) match { + case None => + // This is the default artifact. We do need to add this, and to the default configuration. + val defaultArt = + new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), requestedArt.getName, requestedArt.getType, requestedArt.getExt) + md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) + case Some(scope) => + Message.debug(s"Adding additional artifact in $scope, $requestedArt") + // TODO - more Extra attributes? + val mda = + new MDArtifact( + md, + requestedArt.getName, + requestedArt.getType, + requestedArt.getExt, + requestedArt.getUrl, + requestedArt.getExtraAttributes) + md.addArtifact(getConfiguration(scope), mda) + } + } + } + } + + /** Adds the dependency mediators required based on the managed dependency instances from this pom. */ + def addManagedDependenciesFromAether(result: AetherDescriptorResult, md: DefaultModuleDescriptor) { + for (d <- result.getManagedDependencies.asScala) { + + if (d.getArtifact.getArtifactId == "stringtemplate") { + Message.warn(s"Found managed stringtemplate in $md !") + } + + md.addDependencyDescriptorMediator( + ModuleId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId), + ExactPatternMatcher.INSTANCE, + new OverrideDependencyDescriptorMediator(null, d.getArtifact.getVersion) { + override def mediate(dd: DependencyDescriptor): DependencyDescriptor = { + super.mediate(dd) + } + }) + + } + } + + /** Adds the list of dependencies this artifact has on other artifacts. */ + def addDependenciesFromAether(result: AetherDescriptorResult, md: DefaultModuleDescriptor) { + for (d <- result.getDependencies.asScala) { + // TODO - Is this correct for changing detection. We should use the Ivy mechanism configured... + val isChanging = d.getArtifact.getVersion.endsWith("-SNAPSHOT") + val drid = ModuleRevisionId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId, d.getArtifact.getVersion) + // Note: The previous maven integration ALWAYS set force to true for dependnecies. If we do not do this, for some + // reason, Ivy will create dummy nodes when doing dependnecy mediation (e.g. dependencyManagement of one pom overrides version of a dependency) + // which was leading to "data not found" exceptions as Ivy would pick the correct IvyNode in the dependency tree but never load it with data.... + val dd = new DefaultDependencyDescriptor(md, drid, /* force */ true, isChanging, true) {} + + // TODO - Configuration mappings (are we grabbing scope correctly, or should the default not always be compile?) + val scope = Option(d.getScope).filterNot(_.isEmpty).getOrElse("compile") + val mapping = ReplaceMavenConfigurationMappings.addMappings(dd, scope, d.isOptional) + // TODO - include rules and exclude rules. + Message.debug(s"Adding maven transitive dependency ${md.getModuleRevisionId} -> ${dd}") + // TODO - Unify this borrowed Java code into something a bit friendlier. + // Now we add the artifact.... + if ((d.getArtifact.getClassifier != null) || ((d.getArtifact.getExtension != null) && !("jar" == d.getArtifact.getExtension))) { + val tpe: String = + if (d.getArtifact.getExtension != null) d.getArtifact.getExtension + else "jar" + val ext: String = tpe match { + case "test-jar" => "jar" + case JarPackaging() => "jar" + case other => other + } + // Here we add the classifier, hopefully correctly... + val extraAtt = new java.util.HashMap[String, AnyRef]() + if (d.getArtifact.getClassifier != null) { + extraAtt.put("m:classifier", d.getArtifact.getClassifier) + } + val depArtifact: DefaultDependencyArtifactDescriptor = + new DefaultDependencyArtifactDescriptor(dd, dd.getDependencyId.getName, tpe, ext, null, extraAtt) + val optionalizedScope: String = if (d.isOptional) "optional" else scope + // TOOD - We may need to fix the configuration mappings here. + dd.addDependencyArtifact(optionalizedScope, depArtifact) + } + // TODO - is toSystem call correct? + md.addDependency(dd) + + if (d.getArtifact.getArtifactId == "stringtemplate") { + Message.warn(s"Found stringtemplate dependency! $dd") + } + } + } + + // This method appears to be deprecated/unused in all of Ivy so we do not implement it. + override def findIvyFileRef(dd: DependencyDescriptor, rd: ResolveData): ResolvedResource = { + Message.error(s"Looking for ivy file ref, method not implemented! MavenRepositoryResolver($getName) will always return null.") + null + } + + private def getPackagingFromPomProperties(props: java.util.Map[String, AnyRef]): String = + if (props.containsKey(SbtExtraProperties.MAVEN_PACKAGING_KEY)) + props.get(SbtExtraProperties.MAVEN_PACKAGING_KEY).toString + else "jar" + + override def download(artifacts: Array[Artifact], dopts: DownloadOptions): DownloadReport = { + // TODO - Status reports on download and possibly parallel downloads + val report = new DownloadReport + val requests = + for (a <- artifacts) yield { + val request = new AetherArtifactRequest + val aetherArt = + getClassifier(a) match { + case None | Some("") => + new AetherArtifact( + aetherCoordsFromMrid(a.getModuleRevisionId), + getArtifactProperties(a.getModuleRevisionId)) + case Some(other) => new AetherArtifact( + aetherCoordsFromMrid(a.getModuleRevisionId, other, a.getExt), + getArtifactProperties(a.getModuleRevisionId)) + } + Message.debug(s"Requesting download of [$aetherArt]") + request.setArtifact(aetherArt) + addRepositories(request) + request + } + val (aetherResults, failed) = + try { + (system.resolveArtifacts(session, requests.toList.asJava).asScala, false) + } catch { + case e: org.eclipse.aether.resolution.ArtifactResolutionException => + Message.error(s"Failed to resolve artifacts from ${getName}, ${e.getMessage}") + (e.getResults.asScala, true) + } + for ((result, art) <- aetherResults zip artifacts) { + Message.debug(s"Aether resolved artifact result: $result") + val adr = new ArtifactDownloadReport(art) + adr.setDownloadDetails(result.toString) + // TODO - Fill this out with a real estimate on time... + adr.setDownloadTimeMillis(0L) + // TODO - what is artifact origin actuallyused for? + adr.setArtifactOrigin(new ArtifactOrigin( + art, + true, + getName)) + if (result.isMissing) { + adr.setDownloadStatus(DownloadStatus.FAILED) + adr.setDownloadDetails(ArtifactDownloadReport.MISSING_ARTIFACT) + } else if (!result.isResolved) { + adr.setDownloadStatus(DownloadStatus.FAILED) + adr.setDownloadDetails(result.toString) + // TODO - we should set download status to NO in the event we don't care about an artifact... + } else { + val file = result.getArtifact.getFile + Message.debug(s"Succesffully downloaded: $file") + adr.setLocalFile(file) + adr.setSize(file.length) + adr.setDownloadStatus(DownloadStatus.SUCCESSFUL) + } + report.addArtifactReport(adr) + } + report + } + + case class PublishTransaction(module: ModuleRevisionId, artifacts: Seq[(Artifact, File)]) + private var currentTransaction: Option[PublishTransaction] = None + + override def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean): Unit = { + currentTransaction match { + case Some(t) => throw new IllegalStateException(s"Publish Transaction already open for [$getName]") + case None => currentTransaction = Some(PublishTransaction(module, Nil)) + } + } + override def abortPublishTransaction(): Unit = { + currentTransaction = None + } + + def getClassifier(art: Artifact): Option[String] = + // TODO - Do we need to look anywere else? + Option(art.getExtraAttribute("classifier")) + + def getClassifier(art: org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor): Option[String] = + art.getType match { + case "doc" | "javadoc" => Some("javadoc") + case "src" | "source" => Some("sources") + case "test-jar" | "test" => Some("tests") + case _ => + // Look for extra attributes + art.getExtraAttribute(MavenRepositoryResolver.CLASSIFIER_ATTRIBUTE) match { + case null => None + case c => Some(c) + } + } + + def getConfiguration(classifier: String): String = + classifier match { + // TODO - choice of configuration actually depends on whether or not the artifact is + // REQUESTED by the user, in which case it should be on master. + // Currently, we don't actually look for sources/javadoc/test artifacts at all, + // which means any artifact is in the master configuration, but we should + // fix this for better integration into the maven ecosystem from ivy. + //case "sources" => "sources" + //case "javadoc" => "javadoc" + case other => MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION + } + + override def commitPublishTransaction(): Unit = { + // TODO - actually send all artifacts to aether + currentTransaction match { + case Some(t) => + Message.debug(s"Publishing module ${t.module}, with artifact count = ${t.artifacts.size}") + val artifacts = + for ((art, file) <- t.artifacts) yield { + Message.debug(s" - Publishing $art (${art.getType})(${art.getExtraAttribute("classifier")}) in [${art.getConfigurations.mkString(",")}] from $file") + new AetherArtifact( + t.module.getOrganisation, + aetherArtifactIdFromMrid(t.module), + getClassifier(art).orNull, + art.getExt, + t.module.getRevision, + getArtifactProperties(t.module), + file + ) + } + publishArtifacts(artifacts) + // TODO - Any kind of validity checking? + currentTransaction = None + case None => throw new IllegalStateException(s"Publish Transaction already open for [$getName]") + } + } + + override def publish(art: Artifact, file: File, overwrite: Boolean): Unit = { + currentTransaction match { + case Some(t) => + val allArts = t.artifacts ++ List(art -> file) + currentTransaction = Some(t.copy(artifacts = allArts)) + case None => + throw new IllegalStateException(("MavenRepositories require transactional publish")) + } + } + + override def equals(a: Any): Boolean = + a match { + case x: AbstractMavenRepositoryResolver => x.getName == getName + case _ => false + } +} diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala new file mode 100644 index 000000000..367143a57 --- /dev/null +++ b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala @@ -0,0 +1,140 @@ +package org.apache.ivy.plugins.resolver + +import java.net.URI + +import org.apache.ivy.plugins.repository.Resource +import org.apache.ivy.plugins.repository.url.URLResource +import org.apache.ivy.util.Message +import org.apache.ivy.util.url.URLHandlerRegistry +import org.eclipse.aether.artifact.Artifact +import org.eclipse.aether.impl.{ MetadataGeneratorFactory, ArtifactDescriptorReader, RepositoryConnectorProvider, DefaultServiceLocator } +import org.eclipse.aether.metadata.Metadata +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory +import org.eclipse.aether.spi.connector.layout.{ RepositoryLayoutFactory, RepositoryLayoutProvider, RepositoryLayout } +import org.eclipse.aether.spi.connector.layout.RepositoryLayout.Checksum +import org.eclipse.aether.{ + RepositorySystem, + RepositorySystemSession +} + +import org.eclipse.aether.repository.{ RemoteRepository, LocalRepository } +import org.eclipse.aether.RepositorySystemSession +import org.apache.maven.repository.internal._ +import org.eclipse.aether.spi.connector.transport._ +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import java.io.File + +/** Helper methods for dealing with starting up Aether. */ +object MavenRepositorySystemFactory { + def newRepositorySystemImpl: RepositorySystem = { + // For now we just log Aether instantiation issues. These should probably cause fatal errors. + val locator = MavenRepositorySystemUtils.newServiceLocator() + locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler { + override def serviceCreationFailed(tpe: Class[_], impl: Class[_], exception: Throwable): Unit = { + Message.error(s"Failed to create $tpe, of class $impl") + } + }) + // Here we register the Ivy <-> Aether transport bridge + locator.addService(classOf[TransporterFactory], classOf[MyTransportFactory]) + // This connects the download mechanism to our transports. Why is it needed? no clue. + locator.addService(classOf[RepositoryConnectorFactory], classOf[BasicRepositoryConnectorFactory]) + + // Plugins cause issues here, as their layout is super odd. Here we inject a new plugin layout + locator.addService(classOf[RepositoryLayoutFactory], classOf[SbtPluginLayoutFactory]) + + // Here we add the metadata services so aether will automatically add maven-metadata.xml files. + locator.addService(classOf[MetadataGeneratorFactory], classOf[SnapshotMetadataGeneratorFactory]) + locator.addService(classOf[MetadataGeneratorFactory], classOf[VersionsMetadataGeneratorFactory]) + + // Add our hook for parsing pom.xml files. + locator.setService(classOf[ArtifactDescriptorReader], classOf[SbtArtifactDescriptorReader]) + // Finally, use the DI to create our repository system. + locator.getService(classOf[RepositorySystem]) + } + def newSessionImpl(system: RepositorySystem, localRepoDir: File): RepositorySystemSession = { + val session = MavenRepositorySystemUtils.newSession() + val localRepo = new LocalRepository(localRepoDir) + session setLocalRepositoryManager (system.newLocalRepositoryManager(session, localRepo)) + // Here we set a descriptor policy that FORCES the pom.xml to exist, otherwise Ivy's resolution + // algorithm freaks out. What we could do is also do the ivy lame-thing of checking for a JAR + // instead of a pom.xml, but let's see if this is actually a problem in practice. + val descriptorPolicy = new org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy( + /* ignoreMissing */ false, /* ignoreInvalid. */ true) + session.setArtifactDescriptorPolicy(descriptorPolicy) + session + } + + def defaultLocalRepo: java.io.File = { + new java.io.File(s"${sys.props("user.home")}/.m2/repository") + } +} +/** Override aether's default transport with Ivy-ones. */ +class MyTransportFactory extends TransporterFactory { + override def newInstance(session: RepositorySystemSession, repository: RemoteRepository): Transporter = + repository.getProtocol match { + case "http" | "https" => new HttpTransport(repository) + case "file" => new FileTransport(repository) + case other => throw new IllegalArgumentException(s"Unsupported transport protocol: $other") + } + override def getPriority: Float = 1.0f +} + +/** Aether Http <-> Ivy Http adapter. Aether's is better, but Ivy's has configuration hooks in sbt. */ +class HttpTransport(repository: RemoteRepository) extends AbstractTransporter { + class NotFoundException(msg: String) extends Exception(msg) + private def toURL(task: TransportTask): java.net.URL = + try new java.net.URL(s"${repository.getUrl}/${task.getLocation.toASCIIString}") + catch { + case e: IllegalArgumentException => throw new IllegalArgumentException(s" URL (${task.getLocation}) is not absolute.") + } + private def toResource(task: TransportTask): Resource = new URLResource(toURL(task)) + override def implPeek(peek: PeekTask): Unit = { + if (!toResource(peek).exists()) throw new NotFoundException(s"Could not find ${peek.getLocation}") + } + override def implClose(): Unit = () + override def implGet(out: GetTask): Unit = { + if (!toResource(out).exists()) throw new NotFoundException(s"Could not find ${out.getLocation}") + URLHandlerRegistry.getDefault.download(toURL(out), out.getDataFile, null) + } + override def implPut(put: PutTask): Unit = { + URLHandlerRegistry.getDefault.upload(put.getDataFile, toURL(put), null) + } + override def classify(err: Throwable): Int = + err match { + // TODO - Implement + case _: NotFoundException => Transporter.ERROR_NOT_FOUND + case _ => Transporter.ERROR_OTHER + } +} + +class FileTransport(repository: RemoteRepository) extends AbstractTransporter { + class NotFoundException(msg: String) extends Exception(msg) + private def toURL(task: TransportTask): java.net.URL = + try new java.net.URL(s"${repository.getUrl}/${task.getLocation.toASCIIString}") + catch { + case e: IllegalArgumentException => throw new IllegalArgumentException(s" URL (${task.getLocation}) is not absolute.") + } + private def toResource(task: TransportTask): Resource = new URLResource(toURL(task)) + private def toFile(task: TransportTask): java.io.File = + new java.io.File(toURL(task).toURI) + override def implPeek(peek: PeekTask): Unit = { + if (!toFile(peek).exists()) throw new NotFoundException(s"Could not find ${peek.getLocation}") + } + override def implClose(): Unit = () + override def implGet(out: GetTask): Unit = { + val from = toFile(out) + if (!from.exists()) throw new NotFoundException(s"Could not find ${out.getLocation}") + sbt.IO.copyFile(from, out.getDataFile, true) + } + override def implPut(put: PutTask): Unit = { + val to = toFile(put) + val from = put.getDataFile + sbt.IO.copyFile(from, to, true) + } + override def classify(err: Throwable): Int = + err match { + // TODO - Implement + case _: NotFoundException => Transporter.ERROR_NOT_FOUND + case _ => Transporter.ERROR_OTHER + } +} \ No newline at end of file diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java new file mode 100644 index 000000000..316cee911 --- /dev/null +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java @@ -0,0 +1,556 @@ +package org.apache.maven.repository.internal; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.apache.maven.model.DependencyManagement; +import org.apache.maven.model.DistributionManagement; +import org.apache.maven.model.License; +import org.apache.maven.model.Model; +import org.apache.maven.model.Prerequisites; +import org.apache.maven.model.Relocation; +import org.apache.maven.model.Repository; +import org.apache.maven.model.building.DefaultModelBuilderFactory; +import org.apache.maven.model.building.DefaultModelBuildingRequest; +import org.apache.maven.model.building.FileModelSource; +import org.apache.maven.model.building.ModelBuilder; +import org.apache.maven.model.building.ModelBuildingException; +import org.apache.maven.model.building.ModelBuildingRequest; +import org.apache.maven.model.building.ModelProblem; +import org.apache.maven.model.resolution.UnresolvableModelException; +import org.codehaus.plexus.component.annotations.Component; +import org.codehaus.plexus.component.annotations.Requirement; +import org.eclipse.aether.RepositoryException; +import org.eclipse.aether.RepositoryEvent.EventType; +import org.eclipse.aether.RepositoryEvent; +import org.eclipse.aether.RepositorySystemSession; +import org.eclipse.aether.RequestTrace; +import org.eclipse.aether.artifact.Artifact; +import org.eclipse.aether.artifact.ArtifactProperties; +import org.eclipse.aether.artifact.ArtifactType; +import org.eclipse.aether.artifact.ArtifactTypeRegistry; +import org.eclipse.aether.artifact.DefaultArtifact; +import org.eclipse.aether.artifact.DefaultArtifactType; +import org.eclipse.aether.graph.Dependency; +import org.eclipse.aether.graph.Exclusion; +import org.eclipse.aether.impl.*; +import org.eclipse.aether.repository.WorkspaceRepository; +import org.eclipse.aether.resolution.ArtifactDescriptorException; +import org.eclipse.aether.resolution.ArtifactDescriptorPolicy; +import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest; +import org.eclipse.aether.resolution.ArtifactDescriptorRequest; +import org.eclipse.aether.resolution.ArtifactDescriptorResult; +import org.eclipse.aether.resolution.ArtifactRequest; +import org.eclipse.aether.resolution.ArtifactResolutionException; +import org.eclipse.aether.resolution.ArtifactResult; +import org.eclipse.aether.resolution.VersionRequest; +import org.eclipse.aether.resolution.VersionResolutionException; +import org.eclipse.aether.resolution.VersionResult; +import org.eclipse.aether.spi.locator.Service; +import org.eclipse.aether.spi.locator.ServiceLocator; +import org.eclipse.aether.spi.log.Logger; +import org.eclipse.aether.spi.log.LoggerFactory; +import org.eclipse.aether.spi.log.NullLoggerFactory; +import org.eclipse.aether.transfer.ArtifactNotFoundException; + +/** + * A hacked version of maven's default artifact descriptor reader which we use in place of the standard aether adapter. + * + * This adds the following to the parsing of maven files: + * + * Additonal properties: + * + * - `sbt.pom.packaging` - The pom.packaging value. + * + * + * @author Benjamin Bentmann + * @author Josh Suereth - Adapted for sbt + */ +@Named +@Component( role = ArtifactDescriptorReader.class ) +public class SbtArtifactDescriptorReader + implements ArtifactDescriptorReader, Service +{ + + @SuppressWarnings( "unused" ) + @Requirement( role = LoggerFactory.class ) + private Logger logger = NullLoggerFactory.LOGGER; + + @Requirement + private RemoteRepositoryManager remoteRepositoryManager; + + @Requirement + private VersionResolver versionResolver; + + @Requirement + private VersionRangeResolver versionRangeResolver; + + @Requirement + private ArtifactResolver artifactResolver; + + @Requirement + private RepositoryEventDispatcher repositoryEventDispatcher; + + @Requirement + private ModelBuilder modelBuilder; + + public SbtArtifactDescriptorReader() + { + // enable no-arg constructor + } + + @Inject + SbtArtifactDescriptorReader( RemoteRepositoryManager remoteRepositoryManager, VersionResolver versionResolver, + ArtifactResolver artifactResolver, ModelBuilder modelBuilder, + RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory ) + { + setRemoteRepositoryManager( remoteRepositoryManager ); + setVersionResolver( versionResolver ); + setArtifactResolver( artifactResolver ); + setModelBuilder( modelBuilder ); + setLoggerFactory( loggerFactory ); + setRepositoryEventDispatcher( repositoryEventDispatcher ); + } + + public void initService( ServiceLocator locator ) + { + setLoggerFactory(locator.getService(LoggerFactory.class)); + setRemoteRepositoryManager(locator.getService(RemoteRepositoryManager.class)); + setVersionResolver(locator.getService(VersionResolver.class)); + setArtifactResolver(locator.getService(ArtifactResolver.class)); + setRepositoryEventDispatcher(locator.getService(RepositoryEventDispatcher.class)); + setVersionRangeResolver(locator.getService(VersionRangeResolver.class)); + modelBuilder = locator.getService( ModelBuilder.class ); + if ( modelBuilder == null ) + { + setModelBuilder( new DefaultModelBuilderFactory().newInstance() ); + } + } + + public SbtArtifactDescriptorReader setLoggerFactory( LoggerFactory loggerFactory ) + { + this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() ); + return this; + } + + void setLogger( LoggerFactory loggerFactory ) + { + // plexus support + setLoggerFactory( loggerFactory ); + } + + public SbtArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) + { + if ( remoteRepositoryManager == null ) + { + throw new IllegalArgumentException( "remote repository manager has not been specified" ); + } + this.remoteRepositoryManager = remoteRepositoryManager; + return this; + } + + public SbtArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver ) + { + if ( versionResolver == null ) + { + throw new IllegalArgumentException( "version resolver has not been specified" ); + } + this.versionResolver = versionResolver; + return this; + } + + public SbtArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver ) + { + if ( artifactResolver == null ) + { + throw new IllegalArgumentException( "artifact resolver has not been specified" ); + } + this.artifactResolver = artifactResolver; + return this; + } + + public SbtArtifactDescriptorReader setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher ) + { + if ( repositoryEventDispatcher == null ) + { + throw new IllegalArgumentException( "repository event dispatcher has not been specified" ); + } + this.repositoryEventDispatcher = repositoryEventDispatcher; + return this; + } + + public SbtArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder ) + { + if ( modelBuilder == null ) + { + throw new IllegalArgumentException( "model builder has not been specified" ); + } + this.modelBuilder = modelBuilder; + return this; + } + + public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session, + ArtifactDescriptorRequest request ) + throws ArtifactDescriptorException + { + ArtifactDescriptorResult result = new ArtifactDescriptorResult( request ); + + Model model = loadPom( session, request, result ); + + if ( model != null ) + { + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); + + for ( Repository r : model.getRepositories() ) + { + result.addRepository( ArtifactDescriptorUtils.toRemoteRepository( r ) ); + } + + for ( org.apache.maven.model.Dependency dependency : model.getDependencies() ) + { + result.addDependency( convert( dependency, stereotypes ) ); + } + + DependencyManagement mngt = model.getDependencyManagement(); + if ( mngt != null ) + { + for ( org.apache.maven.model.Dependency dependency : mngt.getDependencies() ) + { + result.addManagedDependency( convert( dependency, stereotypes ) ); + } + } + + Map properties = new LinkedHashMap(); + + Prerequisites prerequisites = model.getPrerequisites(); + if ( prerequisites != null ) + { + properties.put( "prerequisites.maven", prerequisites.getMaven() ); + } + + List licenses = model.getLicenses(); + properties.put( SbtExtraProperties.LICENSE_COUNT_KEY, licenses.size() ); + for ( int i = 0; i < licenses.size(); i++ ) + { + License license = licenses.get( i ); + properties.put( SbtExtraProperties.makeLicenseName(i), license.getName() ); + properties.put( SbtExtraProperties.makeLicenseUrl(i), license.getUrl() ); + properties.put( "license." + i + ".comments", license.getComments() ); + properties.put( "license." + i + ".distribution", license.getDistribution() ); + } + + // SBT ADDED - Here we push in the pom packaging type for Ivy expectations. + final String packaging = + (model.getPackaging() == null) ? "jar" : model.getPackaging(); + properties.put(SbtExtraProperties.MAVEN_PACKAGING_KEY, packaging); + // SBT ADDED - Here we inject the sbt/scala version we parse out of the pom. + final Properties mprops = model.getProperties(); + if(mprops.containsKey(SbtExtraProperties.POM_SBT_VERSION)) { + final String sbtVersion = mprops.getProperty(SbtExtraProperties.POM_SBT_VERSION); + properties.put(SbtExtraProperties.SBT_VERSION_KEY, sbtVersion); + } + if(mprops.containsKey(SbtExtraProperties.POM_SCALA_VERSION)) { + properties.put(SbtExtraProperties.SCALA_VERSION_KEY, mprops.getProperty(SbtExtraProperties.POM_SCALA_VERSION)); + } + + // TODO - Add extra attributes, e.g. sbtVersion + scalaVersion. + + result.setProperties( properties); + + setArtifactProperties( result, model ); + } + + return result; + } + + // SBT FIX - We make sure that artifact properties are copied over here, so we can find sbt-plugin POM files. + public static Artifact toPomArtifact(Artifact artifact) { + Artifact pomArtifact = artifact; + if(artifact.getClassifier().length() > 0 || !"pom".equals(artifact.getExtension())) { + // TODO - only copy over sbt-important properties. + pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion()).setProperties(artifact.getProperties()); + } + return pomArtifact; + } + + private Model loadPom( RepositorySystemSession session, ArtifactDescriptorRequest request, + ArtifactDescriptorResult result ) + throws ArtifactDescriptorException + { + RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); + + Set visited = new LinkedHashSet(); + for ( Artifact artifact = request.getArtifact();; ) + { + // SBT FIX - we need to use our own variant here to preserve extra attributes. + // Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact( artifact ); + Artifact pomArtifact = toPomArtifact(artifact); + try + { + VersionRequest versionRequest = + new VersionRequest( artifact, request.getRepositories(), request.getRequestContext() ); + versionRequest.setTrace( trace ); + VersionResult versionResult = versionResolver.resolveVersion( session, versionRequest ); + + artifact = artifact.setVersion( versionResult.getVersion() ); + + versionRequest = + new VersionRequest( pomArtifact, request.getRepositories(), request.getRequestContext() ); + versionRequest.setTrace( trace ); + versionResult = versionResolver.resolveVersion( session, versionRequest ); + + pomArtifact = pomArtifact.setVersion( versionResult.getVersion() ); + } + catch ( VersionResolutionException e ) + { + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + if ( !visited.add( artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion() ) ) + { + RepositoryException exception = + new RepositoryException( "Artifact relocations form a cycle: " + visited ); + invalidDescriptor( session, trace, artifact, exception ); + if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 ) + { + return null; + } + result.addException( exception ); + throw new ArtifactDescriptorException( result ); + } + + ArtifactResult resolveResult; + try + { + ArtifactRequest resolveRequest = + new ArtifactRequest( pomArtifact, request.getRepositories(), request.getRequestContext() ); + resolveRequest.setTrace( trace ); + resolveResult = artifactResolver.resolveArtifact( session, resolveRequest ); + pomArtifact = resolveResult.getArtifact(); + result.setRepository( resolveResult.getRepository() ); + } + catch ( ArtifactResolutionException e ) + { + if ( e.getCause() instanceof ArtifactNotFoundException ) + { + missingDescriptor( session, trace, artifact, (Exception) e.getCause() ); + if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_MISSING ) != 0 ) + { + return null; + } + } + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + Model model; + try + { + ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest(); + modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); + modelRequest.setProcessPlugins(false); + modelRequest.setTwoPhaseBuilding(false); + modelRequest.setSystemProperties(toProperties(session.getUserProperties(), + session.getSystemProperties())); + modelRequest.setModelCache(DefaultModelCache.newInstance(session)); + modelRequest.setModelResolver( + new DefaultModelResolver( + session, + trace.newChild(modelRequest), + request.getRequestContext(), + artifactResolver, + versionRangeResolver, + remoteRepositoryManager, + request.getRepositories()) + ); + if ( resolveResult.getRepository() instanceof WorkspaceRepository ) + { + modelRequest.setPomFile( pomArtifact.getFile() ); + } + else + { + modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) ); + } + + model = modelBuilder.build( modelRequest ).getEffectiveModel(); + } + catch ( ModelBuildingException e ) + { + for ( ModelProblem problem : e.getProblems() ) + { + if ( problem.getException() instanceof UnresolvableModelException ) + { + result.addException( problem.getException() ); + throw new ArtifactDescriptorException( result ); + } + } + invalidDescriptor( session, trace, artifact, e ); + if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 ) + { + return null; + } + result.addException( e ); + throw new ArtifactDescriptorException( result ); + } + + Relocation relocation = getRelocation( model ); + + if ( relocation != null ) + { + result.addRelocation( artifact ); + artifact = + new RelocatedArtifact( artifact, relocation.getGroupId(), relocation.getArtifactId(), + relocation.getVersion() ); + result.setArtifact( artifact ); + } + else + { + return model; + } + } + } + + private Properties toProperties( Map dominant, Map recessive ) + { + Properties props = new Properties(); + if ( recessive != null ) + { + props.putAll( recessive ); + } + if ( dominant != null ) + { + props.putAll( dominant ); + } + return props; + } + + private Relocation getRelocation( Model model ) + { + Relocation relocation = null; + DistributionManagement distMngt = model.getDistributionManagement(); + if ( distMngt != null ) + { + relocation = distMngt.getRelocation(); + } + return relocation; + } + + private void setArtifactProperties( ArtifactDescriptorResult result, Model model ) + { + String downloadUrl = null; + DistributionManagement distMngt = model.getDistributionManagement(); + if ( distMngt != null ) + { + downloadUrl = distMngt.getDownloadUrl(); + } + if ( downloadUrl != null && downloadUrl.length() > 0 ) + { + Artifact artifact = result.getArtifact(); + Map props = new HashMap( artifact.getProperties() ); + props.put( ArtifactProperties.DOWNLOAD_URL, downloadUrl ); + result.setArtifact( artifact.setProperties( props ) ); + } + } + + private Dependency convert( org.apache.maven.model.Dependency dependency, ArtifactTypeRegistry stereotypes ) + { + ArtifactType stereotype = stereotypes.get( dependency.getType() ); + if ( stereotype == null ) + { + stereotype = new DefaultArtifactType( dependency.getType() ); + } + + boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0; + + Map props = null; + if ( system ) + { + props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() ); + } + + Artifact artifact = + new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, + dependency.getVersion(), props, stereotype ); + + List exclusions = new ArrayList( dependency.getExclusions().size() ); + for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() ) + { + exclusions.add( convert( exclusion ) ); + } + + Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions ); + + return result; + } + + private Exclusion convert( org.apache.maven.model.Exclusion exclusion ) + { + return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" ); + } + + private void missingDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact, + Exception exception ) + { + RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_MISSING ); + event.setTrace( trace ); + event.setArtifact( artifact ); + event.setException( exception ); + + repositoryEventDispatcher.dispatch( event.build() ); + } + + private void invalidDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact, + Exception exception ) + { + RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_INVALID ); + event.setTrace( trace ); + event.setArtifact( artifact ); + event.setException( exception ); + + repositoryEventDispatcher.dispatch( event.build() ); + } + + private int getPolicy( RepositorySystemSession session, Artifact artifact, ArtifactDescriptorRequest request ) + { + ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy(); + if ( policy == null ) + { + return ArtifactDescriptorPolicy.STRICT; + } + return policy.getPolicy( session, new ArtifactDescriptorPolicyRequest( artifact, request.getRequestContext() ) ); + } + + public void setVersionRangeResolver(final VersionRangeResolver versionRangeResolver) { + this.versionRangeResolver = versionRangeResolver; + } +} \ No newline at end of file diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java new file mode 100644 index 000000000..32937677b --- /dev/null +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java @@ -0,0 +1,23 @@ +package org.apache.maven.repository.internal; + +/** + * Created by jsuereth on 12/20/14. + */ +public class SbtExtraProperties { + public static final String MAVEN_PACKAGING_KEY = "sbt.pom.packaging"; + public static final String SCALA_VERSION_KEY = "sbt.pom.scalaversion"; + public static final String SBT_VERSION_KEY = "sbt.pom.sbtversion"; + + public static final String POM_SCALA_VERSION = "scalaVersion"; + public static final String POM_SBT_VERSION = "sbtVersion"; + + public static final String LICENSE_COUNT_KEY = "license.count"; + + public static String makeLicenseName(int i) { + return "license." + i + ".name"; + } + public static String makeLicenseUrl(int i) { + return "license." + i + ".url"; + } + +} diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala new file mode 100644 index 000000000..23fe7630a --- /dev/null +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala @@ -0,0 +1,100 @@ +package org.apache.maven.repository.internal + +import org.apache.ivy.util.Message +import org.eclipse.aether.spi.connector.layout.{ RepositoryLayout, RepositoryLayoutFactory } +import org.eclipse.aether.RepositorySystemSession +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.transfer.NoRepositoryLayoutException +import org.eclipse.aether.metadata.Metadata +import org.eclipse.aether.spi.connector.layout.RepositoryLayout.Checksum +import org.eclipse.aether.artifact.Artifact +import java.net.URI + +import scala.util.matching.Regex + +/** A factory which knows how to create repository layouts which can find sbt plugins. */ +class SbtPluginLayoutFactory extends RepositoryLayoutFactory { + def newInstance(session: RepositorySystemSession, repository: RemoteRepository): RepositoryLayout = { + repository.getContentType match { + case SbtRepositoryLayout.LAYOUT_NAME => + SbtRepositoryLayout + case _ => throw new NoRepositoryLayoutException(repository, "Not an sbt-plugin repository") + } + } + def getPriority: Float = 100.0f +} + +object SbtRepositoryLayout extends RepositoryLayout { + + val LAYOUT_NAME = "sbt-plugin" + + // get location is ALMOST the same for Metadata + artifact... but subtle differences are important. + + def getLocation(artifact: Artifact, upload: Boolean): URI = { + import collection.JavaConverters._ + val sbtVersion = Option(artifact.getProperties.get(SbtExtraProperties.POM_SBT_VERSION)) + val scalaVersion = Option(artifact.getProperties.get(SbtExtraProperties.POM_SCALA_VERSION)) + val path = new StringBuilder(128) + path.append(artifact.getGroupId.replace('.', '/')).append('/') + (sbtVersion zip scalaVersion).headOption match { + case Some((sbt, scala)) => + if (artifact.getArtifactId contains "_sbt_") { + // TODO - Write this handler. + val SbtNameVersionSplit(name, sbt2) = artifact.getArtifactId + path.append(name).append('_').append(scala).append('_').append(sbt).append('/') + } else path.append(artifact.getArtifactId).append('_').append(scala).append('_').append(sbt).append('/') + case None => + // TODO - Should we automatically append the _ here if it's not there? Probably not for now. + path.append(artifact.getArtifactId).append('/') + } + path.append(artifact.getBaseVersion).append('/') + sbtVersion match { + case Some(_) if artifact.getArtifactId contains "_sbt_" => + val SbtNameVersionSplit(name, sbt2) = artifact.getArtifactId + path.append(name).append('-').append(artifact.getVersion) + case None => path.append(artifact.getArtifactId).append('-').append(artifact.getVersion) + } + + if (artifact.getClassifier != null && !artifact.getClassifier.trim.isEmpty) { + path.append("-").append(artifact.getClassifier) + } + if (artifact.getExtension.length > 0) { + path.append('.').append(artifact.getExtension) + } + URI.create(path.toString()) + } + + // Trickery for disambiguating sbt plugins in maven repositories. + val SbtNameVersionSplit = new Regex("(.*)_sbt_(.*)") + + def getLocation(metadata: Metadata, upload: Boolean): URI = { + val sbtVersion = Option(metadata.getProperties.get(SbtExtraProperties.POM_SBT_VERSION)) + val scalaVersion = Option(metadata.getProperties.get(SbtExtraProperties.POM_SCALA_VERSION)) + val path = new StringBuilder(128) + path.append(metadata.getGroupId.replace('.', '/')).append('/') + (sbtVersion zip scalaVersion).headOption match { + case Some((sbt, scala)) => + if (metadata.getArtifactId contains "_sbt_") { + val SbtNameVersionSplit(name, sbt2) = metadata.getArtifactId + path.append(name).append('_').append(scala).append('_').append(sbt).append('/') + // TODO - Write this handler. + } else path.append(metadata.getArtifactId).append('_').append(scala).append('_').append(sbt).append('/') + case None => + // TODO - Should we automatically append the _ here? Proabbly not for now. + path.append(metadata.getArtifactId).append('/') + } + if (metadata.getVersion.length > 0) + path.append(metadata.getVersion).append('/') + path.append(metadata.getType) + URI.create(path.toString) + } + + // TODO - This should be the same as configured from Ivy... + def getChecksums(artifact: Artifact, upload: Boolean, location: URI): java.util.List[Checksum] = + getChecksums(location) + def getChecksums(metadata: Metadata, upload: Boolean, location: URI): java.util.List[Checksum] = + getChecksums(location) + + private def getChecksums(location: URI): java.util.List[Checksum] = + java.util.Arrays.asList(Checksum.forLocation(location, "SHA-1"), Checksum.forLocation(location, "MD5")) +} \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 35cfb669f..9c7545eb9 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -94,24 +94,37 @@ private[sbt] object ConvertResolver { } } + private[sbt] val USE_AETHER_PROPERTY = "sbt.use.aether" + private def isUseAetherForResolution(settings: IvySettings): Boolean = + settings.getVariable(USE_AETHER_PROPERTY) == "true" + /** Converts the given sbt resolver into an Ivy resolver..*/ def apply(r: Resolver, settings: IvySettings, log: Logger) = { r match { case repo: MavenRepository => { - val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns() { // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) + if (isUseAetherForResolution(settings)) { + repo match { + case cache: MavenCache => new org.apache.ivy.plugins.resolver.MavenCacheRepositoryResolver(cache, settings) + case _ => new org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver(repo, settings) } + } else { + val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) + final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + def setPatterns() { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + } + val resolver = new PluginCapableResolver + resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } - val resolver = new PluginCapableResolver - resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver + } // TODO: HTTP repository is no longer recommended. #1541 // Remove `JavaNet1Repository` when we bump up the API. diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 202216700..d639532a7 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -13,6 +13,7 @@ import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern +@deprecated("0.13.8", "We now use an Aether-based pom parser.") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) @@ -26,6 +27,7 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module override def getType() = delegate.getType() override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) } +@deprecated("0.13.8", "We now use an Aether-based pom parser.") object CustomPomParser { // Evil hackery to override the default maven pom mappings. diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 32f2f6440..d2d0388ee 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -14,19 +14,20 @@ import java.util.{ Collection, Collections => CS, Date } import CS.singleton import org.apache.ivy.Ivy +import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.{ IvyPatternHelper, LogOptions, IvyContext } -import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } +import org.apache.ivy.core.cache.{ ResolutionCacheManager, CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } import org.apache.ivy.core.module.descriptor.{ OverrideDependencyDescriptorMediator } import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } -import org.apache.ivy.core.resolve.{ IvyNode, ResolveData, ResolvedModuleRevision, ResolveEngine } +import org.apache.ivy.core.resolve._ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.sort.SortEngine import org.apache.ivy.plugins.latest.{ LatestStrategy, LatestRevisionStrategy, ArtifactInfo } import org.apache.ivy.plugins.matcher.PatternMatcher -import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorParser +import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorParser } import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, BasicResolver } import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.plugins.version.ExactVersionMatcher @@ -68,9 +69,12 @@ final class IvySbt(val configuration: IvyConfiguration) { private lazy val settings: IvySettings = { val is = new IvySettings + is.setBaseDir(baseDirectory) is.setCircularDependencyStrategy(configuration.updateOptions.circularDependencyLevel.ivyStrategy) CustomPomParser.registerDefault + is.setVariable(ConvertResolver.USE_AETHER_PROPERTY, s"${configuration.updateOptions.aetherResolution}") + configuration match { case e: ExternalIvyConfiguration => IvySbt.addResolvers(e.extraResolvers, is, configuration.log) @@ -104,6 +108,7 @@ final class IvySbt(val configuration: IvyConfiguration) { super.bind() } } + i.setSettings(settings) i.bind() i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index eba0cd94d..3bc3520fd 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -330,6 +330,8 @@ class MakePom(val log: Logger) { val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { + case m: org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver if m.repo.root != DefaultMavenRepository.root => + MavenRepository(m.repo.name, m.repo.root) :: Nil case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => MavenRepository(m.getName, m.getRoot) :: Nil case _ => Nil diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/ivy/src/main/scala/sbt/Resolver.scala index 406c27e78..ce3a2830f 100644 --- a/ivy/src/main/scala/sbt/Resolver.scala +++ b/ivy/src/main/scala/sbt/Resolver.scala @@ -30,8 +30,23 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver { } } sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver + +/** An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts. */ sealed case class MavenRepository(name: String, root: String) extends Resolver { override def toString = name + ": " + root + def isCache: Boolean = false +} + +/** + * An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because + * the metadata is different (see Aether ML discussion). + */ +final class MavenCache(name: String, val rootFile: File) extends MavenRepository(name, rootFile.toURI.toURL.toString) { + override val toString = "cache:" + name + ": " + rootFile.getAbsolutePath + override def isCache: Boolean = true +} +object MavenCache { + def apply(name: String, rootFile: File): MavenCache = new MavenCache(name, rootFile) } final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { @@ -334,8 +349,9 @@ object Resolver { loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse new File(Path.userHome, ".m2/repository") } - def publishMavenLocal = Resolver.file("publish-m2-local", mavenLocalDir) - def mavenLocal = MavenRepository("Maven2 Local", mavenLocalDir.toURI.toString) + // TODO - should this just be the *exact* same as mavenLocal? probably... + def publishMavenLocal: MavenCache = new MavenCache("publish-m2-local", mavenLocalDir) + def mavenLocal: MavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index 1d4688481..e13fed72f 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -17,7 +17,13 @@ final class UpdateOptions private[sbt] ( /** If set to true, use consolidated resolution. */ val consolidatedResolution: Boolean, /** If set to true, use cached resolution. */ - val cachedResolution: Boolean) { + val cachedResolution: Boolean, + /** If set to true, use aether for resolving maven artifacts. */ + val aetherResolution: Boolean) { + + /** Enables Aether for dependency resolution. */ + def withAetherResolution(aetherResolution: Boolean): UpdateOptions = + copy(aetherResolution = aetherResolution) def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) @@ -35,11 +41,13 @@ final class UpdateOptions private[sbt] ( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, - cachedResolution: Boolean = this.cachedResolution): UpdateOptions = + cachedResolution: Boolean = this.cachedResolution, + aetherResolution: Boolean = this.aetherResolution): UpdateOptions = new UpdateOptions(circularDependencyLevel, latestSnapshots, consolidatedResolution, - cachedResolution) + cachedResolution, + aetherResolution) override def equals(o: Any): Boolean = o match { case o: UpdateOptions => @@ -65,5 +73,7 @@ object UpdateOptions { circularDependencyLevel = CircularDependencyLevel.Warn, latestSnapshots = false, consolidatedResolution = false, - cachedResolution = false) + cachedResolution = false, + // TODO - Disable this before release, but make sure test suite passes with it on. + aetherResolution = true) } diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index a4d60c997..13c2642ec 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -12,7 +12,7 @@ import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } import org.apache.ivy.plugins.latest.LatestStrategy import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } import org.apache.ivy.plugins.repository.url.URLResource -import org.apache.ivy.plugins.resolver.{ ChainResolver, BasicResolver, DependencyResolver } +import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } @@ -155,34 +155,39 @@ private[sbt] case class SbtChainResolver( val sorted = if (useLatest) (foundRevisions.sortBy { case (rmr, resolver) => + Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") // Just issue warning about issues with publication date, and fake one on it for now. - rmr.getDescriptor.getPublicationDate match { - case null => + Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { + case None => (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { case (null, _) => // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file if (dd.isChanging) Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + 0L case (ivf, dmd: DefaultModuleDescriptor) => val lmd = new java.util.Date(ivf.getLastModified) Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") dmd.setPublicationDate(lmd) + ivf.getLastModified case _ => Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + 0L } - case _ => // All other cases ok - } - rmr.getDescriptor.getPublicationDate match { - case null => 0L - case d => d.getTime + case Some(date) => // All other cases ok + date.getTime } }).reverse.headOption map { case (rmr, resolver) => + Message.warn(s"Choosing ${resolver} for ${rmr.getId}") // Now that we know the real latest revision, let's force Ivy to use it val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { case None if resolver.getName == "inter-project" => // do nothing - case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") + case None if resolver.isInstanceOf[AbstractMavenRepositoryResolver] => + // do nothing for now.... + // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... + case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") case Some(artifactRef) => val systemMd = toSystem(rmr.getDescriptor) getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, @@ -210,6 +215,9 @@ private[sbt] case class SbtChainResolver( } // Ivy seem to not want to use the module descriptor found at the latest resolver private[this] def reparseModuleDescriptor(dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, rmr: ResolvedModuleRevision): ResolvedModuleRevision = + // TODO - Redownloading/parsing the ivy file is not really the best way to make this correct. + // We should figure out a better alternative, or directly attack the resolvers Ivy uses to + // give them correct behavior around -SNAPSHOT. Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile => ivyFile.getResource match { case r: FileResource => @@ -222,7 +230,10 @@ private[sbt] case class SbtChainResolver( } case _ => None } - } getOrElse rmr + } getOrElse { + Message.warn(s"Unable to reparse ${dd.getDependencyRevisionId} from $resolver, using ${rmr.getPublicationDate}") + rmr + } /** Ported from BasicResolver#findFirstAirfactRef. */ private[this] def findFirstArtifactRef(md: ModuleDescriptor, dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver): Option[ResolvedResource] = { diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 09d7da7a2..1be01ab25 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -4,6 +4,8 @@ import Path._, Configurations._ import java.io.File import org.specs2._ import cross.CrossVersionUtil +import sbt.PublishConfiguration +import sbt.ivyint.SbtChainResolver trait BaseIvySpecification extends Specification { def currentBase: File = new File(".") @@ -12,6 +14,8 @@ trait BaseIvySpecification extends Specification { def currentDependency: File = currentBase / "target" / "dependency" def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) lazy val log = ConsoleLogger() + + def configurations = Seq(Compile, Test, Runtime) def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions()): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => @@ -28,21 +32,24 @@ trait BaseIvySpecification extends Specification { module = moduleId, moduleInfo = ModuleInfo("foo"), dependencies = deps, - configurations = Seq(Compile, Test, Runtime), + configurations = configurations, ivyScala = ivyScala) val ivySbt = new IvySbt(mkIvyConfiguration(uo)) new ivySbt.Module(moduleSetting) } + def resolvers: Seq[Resolver] = Seq(DefaultMavenRepository) + + def chainResolver = ChainedResolver("sbt-chain", resolvers) + def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = new IvyPaths(currentBase, Some(currentTarget)) - val rs = Seq(DefaultMavenRepository) val other = Nil - val moduleConfs = Seq(ModuleConfiguration("*", DefaultMavenRepository)) + val moduleConfs = Seq(ModuleConfiguration("*", chainResolver)) val off = false val check = Nil val resCacheDir = currentTarget / "resolution-cache" - new InlineIvyConfiguration(paths, rs, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) + new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { @@ -58,4 +65,18 @@ trait BaseIvySpecification extends Specification { case Left(w) => throw w.resolveException } + + def mkPublishConfiguration(resolver: Resolver, artifacts: Map[Artifact, File]): PublishConfiguration = { + new PublishConfiguration( + ivyFile = None, + resolverName = resolver.name, + artifacts = artifacts, + checksums = Seq(), + logging = UpdateLogging.Full, + overwrite = true) + } + + def ivyPublish(module: IvySbt#Module, config: PublishConfiguration) = { + IvyActions.publish(module, config, log) + } } diff --git a/ivy/src/test/scala/MavenResolutionSpec.scala b/ivy/src/test/scala/MavenResolutionSpec.scala new file mode 100644 index 000000000..f7b46895d --- /dev/null +++ b/ivy/src/test/scala/MavenResolutionSpec.scala @@ -0,0 +1,291 @@ +package sbt + +import java.io.FileInputStream + +import org.specs2._ + +class MavenResolutionSpec extends BaseIvySpecification { + def is = args(sequential = true) ^ s2""".stripMargin + + This is a specification to check the maven resolution + + Resolving a maven dependency should + handle sbt plugins $resolveSbtPlugins + use ivy for conflict resolution $resolveMajorConflicts + handle cross configuration deps $resolveCrossConfigurations + publish with maven-metadata $publishMavenMetadata + resolve transitive maven dependencies $resolveTransitiveMavenDependency + resolve intransitive maven dependencies $resolveIntransitiveMavenDependency + handle transitive configuration shifts $resolveTransitiveConfigurationMavenDependency + resolve source and doc $resolveSourceAndJavadoc + resolve nonstandard (jdk5) classifier $resolveNonstandardClassifier + Resolve pom artifact dependencies $resolvePomArtifactAndDependencies + Fail if JAR artifact is not found w/ POM $failIfMainArtifactMissing + Fail if POM.xml is not found $failIfPomMissing + resolve publication date for -SNAPSHOT $resolveSnapshotPubDate + + """ // */ + + // TODO - test latest.integration and .+ + + def akkaActor = ModuleID("com.typesafe.akka", "akka-actor_2.11", "2.3.8", Some("compile")) + def akkaActorTestkit = ModuleID("com.typesafe.akka", "akka-testkit_2.11", "2.3.8", Some("test")) + def testngJdk5 = ModuleID("org.testng", "testng", "5.7", Some("compile")).classifier("jdk15") + def jmxri = ModuleID("com.sun.jmx", "jmxri", "1.2.1", Some("compile")) + def scalaLibraryAll = ModuleID("org.scala-lang", "scala-library-all", "2.11.4", Some("compile")) + def scalaCompiler = ModuleID("org.scala-lang", "scala-compiler", "2.8.1", Some("scala-tool->default(compile)")) + def scalaContinuationPlugin = ModuleID("org.scala-lang.plugins", "continuations", "2.8.1", Some("plugin->default(compile)")) + def sbtPlugin = + ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). + extra(CustomPomParser.SbtVersionKey -> "0.13", CustomPomParser.ScalaVersionKey -> "2.10"). + copy(crossVersion = CrossVersion.Disabled) + def oldSbtPlugin = + ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). + extra(CustomPomParser.SbtVersionKey -> "0.12", CustomPomParser.ScalaVersionKey -> "2.9.2"). + copy(crossVersion = CrossVersion.Disabled) + def majorConflictLib = ModuleID("com.joestelmach", "natty", "0.3", Some("compile")) + // TODO - This snapshot and resolver should be something we own/control so it doesn't disappear on us. + def testSnapshot = ModuleID("com.typesafe", "config", "0.4.9-SNAPSHOT", Some("compile")) + val SnapshotResolver = MavenRepository("some-snapshots", "https://oss.sonatype.org/content/repositories/snapshots/") + + override def resolvers = Seq(DefaultMavenRepository, SnapshotResolver, Resolver.publishMavenLocal) + import Configurations.{ Compile, Test, Runtime, CompilerPlugin, ScalaTool } + override def configurations = Seq(Compile, Test, Runtime, CompilerPlugin, ScalaTool) + + import ShowLines._ + + def defaultUpdateOptions = UpdateOptions().withAetherResolution(true) + + def resolveMajorConflicts = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), + Seq(majorConflictLib), None, defaultUpdateOptions) + val report = ivyUpdate(m) // must not(throwAn[IllegalStateException]) + val jars = + for { + conf <- report.configurations + if conf.configuration == Compile.name + m <- conf.modules + if (m.module.name contains "stringtemplate") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + jars must haveSize(1) + } + + def resolveCrossConfigurations = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), + Seq(scalaCompiler, scalaContinuationPlugin), None, defaultUpdateOptions) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + if conf.configuration == ScalaTool.name + m <- conf.modules + if (m.module.name contains "scala-compiler") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + jars must haveSize(1) + } + + def resolveSbtPlugins = { + + def sha(f: java.io.File): String = sbt.Hash.toHex(sbt.Hash(f)) + def findSbtIdeaJars(dep: ModuleID, name: String) = { + val m = module(ModuleID("com.example", name, "0.1.0", Some("compile")), Seq(dep), None, defaultUpdateOptions) + val report = ivyUpdate(m) + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if (m.module.name contains "sbt-idea") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield (f, sha(f)) + } + + val oldJars = findSbtIdeaJars(oldSbtPlugin, "old") + System.err.println(s"${oldJars.mkString("\n")}") + val newJars = findSbtIdeaJars(sbtPlugin, "new") + System.err.println(s"${newJars.mkString("\n")}") + (newJars must haveSize(1)) and (oldJars must haveSize(1)) and (oldJars.map(_._2) must not(containTheSameElementsAs(newJars.map(_._2)))) + } + + def resolveSnapshotPubDate = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(testSnapshot), Some("2.10.2"), defaultUpdateOptions.withLatestSnapshots(true)) + val report = ivyUpdate(m) + val pubTime = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if m.module.revision endsWith "-SNAPSHOT" + date <- m.publicationDate + } yield date + (pubTime must haveSize(1)) + } + + def resolvePomArtifactAndDependencies = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(scalaLibraryAll), Some("2.10.2"), defaultUpdateOptions) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if (m.module.name == "scala-library") || (m.module.name contains "parser") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + jars must haveSize(2) + } + + def failIfPomMissing = { + // TODO - we need the jar to not exist too. + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(ModuleID("org.scala-sbt", "does-not-exist", "1.0", Some("compile"))), Some("2.10.2"), defaultUpdateOptions) + ivyUpdate(m) must throwAn[Exception] + } + + def failIfMainArtifactMissing = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(jmxri), Some("2.10.2"), defaultUpdateOptions) + ivyUpdate(m) must throwAn[Exception] + } + + def resolveNonstandardClassifier = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(testngJdk5), Some("2.10.2"), defaultUpdateOptions) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if m.module.name == "testng" + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + (report.configurations must haveSize(configurations.size)) and + (jars must haveSize(1)) + (jars.forall(_.exists) must beTrue) + + } + + def resolveTransitiveMavenDependency = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActor), Some("2.10.2"), defaultUpdateOptions) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if m.module.name == "scala-library" + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + (report.configurations must haveSize(configurations.size)) and + (jars must not(beEmpty)) and + (jars.forall(_.exists) must beTrue) + + } + + def resolveIntransitiveMavenDependency = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActorTestkit.intransitive()), Some("2.10.2"), defaultUpdateOptions) + val report = ivyUpdate(m) + val transitiveJars = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if (m.module.name contains "akka-actor") && !(m.module.name contains "testkit") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + val directJars = + for { + conf <- report.configurations + if conf.configuration == "compile" + m <- conf.modules + if (m.module.name contains "akka-actor") && (m.module.name contains "testkit") + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + (report.configurations must haveSize(configurations.size)) and + (transitiveJars must beEmpty) and (directJars.forall(_.exists) must beTrue) + } + + def resolveTransitiveConfigurationMavenDependency = { + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActorTestkit), Some("2.10.2"), defaultUpdateOptions) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + if conf.configuration == "test" + m <- conf.modules + if m.module.name contains "akka-actor" + (a, f) <- m.artifacts + if a.extension == "jar" + } yield f + (report.configurations must haveSize(configurations.size)) and + (jars must not(beEmpty)) and + (jars.forall(_.exists) must beTrue) + + } + + def resolveSourceAndJavadoc = { + val m = module( + ModuleID("com.example", "foo", "0.1.0", Some("sources")), + Seq(akkaActor.artifacts(Artifact(akkaActor.name, "javadoc"), Artifact(akkaActor.name, "sources"))), + Some("2.10.2"), + defaultUpdateOptions + ) + val report = ivyUpdate(m) + val jars = + for { + conf <- report.configurations + // We actually injected javadoc/sources into the compile scope, due to how we did the request. + // SO, we report that here. + if conf.configuration == "compile" + m <- conf.modules + (a, f) <- m.artifacts + if (f.getName contains "sources") || (f.getName contains "javadoc") + } yield f + (report.configurations must haveSize(configurations.size)) and + (jars must haveSize(2)) + } + + def publishMavenMetadata = { + val m = module( + ModuleID("com.example", "test-it", "1.0-SNAPSHOT", Some("compile")), + Seq(), + None, + defaultUpdateOptions.withLatestSnapshots(true) + ) + sbt.IO.withTemporaryDirectory { dir => + val pomFile = new java.io.File(dir, "pom.xml") + sbt.IO.write(pomFile, + """ + | + | com.example + | test-it + | 1.0-SNAPSHOT + | + """.stripMargin) + val jarFile = new java.io.File(dir, "test-it-1.0-SNAPSHOT.jar") + sbt.IO.touch(jarFile) + System.err.println(s"DEBUGME - Publishing $m to ${Resolver.publishMavenLocal}") + ivyPublish(m, mkPublishConfiguration( + Resolver.publishMavenLocal, + Map( + Artifact("test-it-1.0-SNAPSHOT.jar") -> pomFile, + Artifact("test-it-1.0-SNAPSHOT.pom", "pom", "pom") -> jarFile + ))) + } + val baseLocalMavenDir: java.io.File = Resolver.publishMavenLocal.rootFile + val allFiles: Seq[java.io.File] = sbt.PathFinder(new java.io.File(baseLocalMavenDir, "com/example/test-it")).***.get + val metadataFiles = allFiles.filter(_.getName contains "maven-metadata-local") + // TODO - maybe we check INSIDE the metadata, or make sure we can get a publication date on resolve... + // We end up with 4 files, two mavne-metadata files, and 2 maven-metadata-local files. + metadataFiles must haveSize(2) + } + +} + From b93627cd6c6156d88313204b5c1b6adfe868a2ff Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 9 Jan 2015 11:11:37 -0500 Subject: [PATCH 0382/1030] Fix upload/copy semantics to handle non-file based uploads. --- .../MavenRepositorySystemFactory.scala | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala index 367143a57..1946dc0da 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala @@ -97,7 +97,20 @@ class HttpTransport(repository: RemoteRepository) extends AbstractTransporter { URLHandlerRegistry.getDefault.download(toURL(out), out.getDataFile, null) } override def implPut(put: PutTask): Unit = { - URLHandlerRegistry.getDefault.upload(put.getDataFile, toURL(put), null) + val to = toURL(put) + Option(put.getDataFile) match { + case Some(file) => URLHandlerRegistry.getDefault.upload(file, to, null) + case None => + // TODO - Ivy does not support uploading not from a file. This isn't very efficient in ANY way, + // so if we rewrite the URL handler for Ivy we should fix this as well. + sbt.IO.withTemporaryFile("tmp", "upload") { file => + val in = put.newInputStream() + try sbt.IO.transfer(in, file) + finally in.close() + URLHandlerRegistry.getDefault.upload(file, to, null) + } + } + } override def classify(err: Throwable): Int = err match { @@ -128,8 +141,15 @@ class FileTransport(repository: RemoteRepository) extends AbstractTransporter { } override def implPut(put: PutTask): Unit = { val to = toFile(put) - val from = put.getDataFile - sbt.IO.copyFile(from, to, true) + Option(put.getDataFile) match { + case Some(from) => + sbt.IO.copyFile(from, to, true) + case None => + // Here it's most likely a SHA or somethign where we read from memory. + val in = put.newInputStream + try sbt.IO.transfer(in, to) + finally in.close() + } } override def classify(err: Throwable): Int = err match { From 651f92e40c4f3df28875a529b6b1efcdba1f4fb8 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 9 Jan 2015 11:14:27 -0500 Subject: [PATCH 0383/1030] Appropriately transfer sbt-plugin transitive 'extra attribute' properties. * Propogate the extra dependnecy attribute out of pom files into Aether * Use the extra depednency attributes to ensure transitive plugins can be resolved. * Add TODOs for further cleanup work. --- .../resolver/MavenRepositoryResolver.scala | 26 ++++++++-- .../PomExtraDependencyAttributes.scala | 47 +++++++++++++++++++ .../internal/SbtArtifactDescriptorReader.java | 4 +- .../internal/SbtExtraProperties.java | 3 +- 4 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala index 253830e6e..84411bf52 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter import org.apache.ivy.plugins.resolver.MavenRepositoryResolver.JarPackaging import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.Message -import org.apache.maven.repository.internal.{ SbtRepositoryLayout, SbtExtraProperties } +import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes, SbtRepositoryLayout, SbtExtraProperties } import org.eclipse.aether.{ RepositorySystemSession, RepositorySystem } import org.eclipse.aether.artifact.{ DefaultArtifact => AetherArtifact } import org.eclipse.aether.metadata.{ Metadata, DefaultMetadata } @@ -327,8 +327,7 @@ abstract class AbstractMavenRepositoryResolver(settings: IvySettings) extends Ab rmr } catch { case e: org.eclipse.aether.resolution.ArtifactDescriptorException => - Message.warn(s"Failed to read descriptor ${dd} from ${getName}, ${e.getMessage}") - e.printStackTrace(System.err) + Message.info(s"Failed to read descriptor ${dd} from ${getName}, ${e.getMessage}") rd.getCurrentResolvedModuleRevision case e: MavenResolutionException => Message.debug(s"Resolution Exception from ${getName}, ${e.getMessage}, returning: ${rd.getCurrentResolvedModuleRevision}") @@ -456,10 +455,29 @@ abstract class AbstractMavenRepositoryResolver(settings: IvySettings) extends Ab /** Adds the list of dependencies this artifact has on other artifacts. */ def addDependenciesFromAether(result: AetherDescriptorResult, md: DefaultModuleDescriptor) { + // First we construct a map of any extra attributes we must append to dependencies. + // This is necessary for transitive maven-based sbt plugin dependencies, where we need to + // attach the sbtVersion/scalaVersion to the dependency id otherwise we'll fail to resolve the + // dependency correctly. + val extraAttributes = PomExtraDependencyAttributes.readFromAether(result.getProperties) for (d <- result.getDependencies.asScala) { // TODO - Is this correct for changing detection. We should use the Ivy mechanism configured... val isChanging = d.getArtifact.getVersion.endsWith("-SNAPSHOT") - val drid = ModuleRevisionId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId, d.getArtifact.getVersion) + val drid = { + val tmp = ModuleRevisionId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId, d.getArtifact.getVersion) + extraAttributes get tmp match { + case Some(props) => + Message.debug(s"Found $tmp w/ extra attributes ${props.mkString(",")}") + ModuleRevisionId.newInstance( + d.getArtifact.getGroupId, + d.getArtifact.getArtifactId, + d.getArtifact.getVersion, + props.asJava + ) + case _ => tmp + } + } + // Note: The previous maven integration ALWAYS set force to true for dependnecies. If we do not do this, for some // reason, Ivy will create dummy nodes when doing dependnecy mediation (e.g. dependencyManagement of one pom overrides version of a dependency) // which was leading to "data not found" exceptions as Ivy would pick the correct IvyNode in the dependency tree but never load it with data.... diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala new file mode 100644 index 000000000..573791420 --- /dev/null +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala @@ -0,0 +1,47 @@ +package org.apache.maven.repository.internal + +import java.util.Properties + +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.util.extendable.ExtendableItem +import sbt.CustomPomParser + +object PomExtraDependencyAttributes { + // TODO - Move custom pom parser extra attribtues code into this class, rather than relying on + // custom pom parser (so we can deprecate it completely). + import CustomPomParser.{ ExtraAttributesKey, simplify, filterCustomExtra, readDependencyExtra } + + /** + * Reads the extra dependency attributes out of a maven property. + * @param props The properties from an Aether resolution. + * @return + * A map of module id to extra dependency attributes associated with dependencies on that module. + */ + def readFromAether(props: java.util.Map[String, AnyRef]): Map[ModuleRevisionId, Map[String, String]] = { + import collection.JavaConverters._ + (props.asScala get ExtraAttributesKey) match { + case None => Map.empty + case Some(str) => + def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include = true)) + (for { + (id, props) <- readDependencyExtra(str.toString).map(processDep) + } yield id -> props).toMap + } + } + + /** + * Mutates the to collection with the extra depdendency attributes from the incoming pom properties list. + * + * @param from The properties directly off a maven POM file + * @param to The aaether properties where we can write whatever we want. + * + * TODO - maybe we can just parse this directly here. Note the `readFromAether` method uses + * whatever we set here. + */ + def transferDependencyExtraAttributes(from: Properties, to: java.util.Map[String, AnyRef]): Unit = { + Option(from.getProperty(ExtraAttributesKey, null)) match { + case Some(str) => to.put(ExtraAttributesKey, str) + case None => + } + } +} diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java index 316cee911..c816145e9 100644 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java @@ -228,6 +228,7 @@ public class SbtArtifactDescriptorReader if ( model != null ) { + ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); for ( Repository r : model.getRepositories() ) @@ -282,7 +283,8 @@ public class SbtArtifactDescriptorReader properties.put(SbtExtraProperties.SCALA_VERSION_KEY, mprops.getProperty(SbtExtraProperties.POM_SCALA_VERSION)); } - // TODO - Add extra attributes, e.g. sbtVersion + scalaVersion. + // SBT-Added - Here we inject the additional dependency attributes (for transitive plugin resolution). + PomExtraDependencyAttributes.transferDependencyExtraAttributes(model.getProperties(), properties); result.setProperties( properties); diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java index 32937677b..55385f9f0 100644 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java @@ -1,5 +1,7 @@ package org.apache.maven.repository.internal; + + /** * Created by jsuereth on 12/20/14. */ @@ -19,5 +21,4 @@ public class SbtExtraProperties { public static String makeLicenseUrl(int i) { return "license." + i + ".url"; } - } From 038fb98c7fb77bae5a99aebc8cf46c97d2ceeadc Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 9 Jan 2015 14:04:24 -0500 Subject: [PATCH 0384/1030] Migrate pom extra attributes out of CustomPomParser for deprecation. --- .../resolver/MavenRepositoryResolver.scala | 6 +- .../PomExtraDependencyAttributes.scala | 72 +++++++++++++++++-- .../internal/SbtExtraProperties.java | 5 +- ivy/src/main/scala/sbt/CustomPomParser.scala | 47 ++++-------- ivy/src/main/scala/sbt/MakePom.scala | 9 ++- ivy/src/main/scala/sbt/ModuleID.scala | 4 +- ivy/src/test/scala/MavenResolutionSpec.scala | 5 +- 7 files changed, 101 insertions(+), 47 deletions(-) diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala index 84411bf52..6ff019c6a 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala @@ -29,7 +29,7 @@ import org.eclipse.aether.resolution.{ import org.eclipse.aether.deployment.{ DeployRequest => AetherDeployRequest } import org.eclipse.aether.installation.{ InstallRequest => AetherInstallRequest } import org.apache.ivy.core.cache.{ ModuleDescriptorWriter, ArtifactOrigin } -import sbt.{ CustomPomParser, MavenCache, MavenRepository } +import sbt.{ MavenCache, MavenRepository } import scala.collection.JavaConverters._ object MavenRepositoryResolver { @@ -336,11 +336,11 @@ abstract class AbstractMavenRepositoryResolver(settings: IvySettings) extends Ab } def getSbtVersion(dd: ModuleRevisionId): Option[String] = - Option(dd.getExtraAttribute(CustomPomParser.SbtVersionKey)) + Option(dd.getExtraAttribute(PomExtraDependencyAttributes.SbtVersionKey)) def getArtifactProperties(dd: ModuleRevisionId): java.util.Map[String, String] = { val m = new java.util.HashMap[String, String] - Option(dd.getExtraAttribute(CustomPomParser.ScalaVersionKey)) foreach { sv => + Option(dd.getExtraAttribute(PomExtraDependencyAttributes.ScalaVersionKey)) foreach { sv => m.put(SbtExtraProperties.POM_SCALA_VERSION, sv) } getSbtVersion(dd) foreach { sv => diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala index 573791420..4c2ead5d1 100644 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala @@ -1,16 +1,29 @@ package org.apache.maven.repository.internal import java.util.Properties +import java.util.regex.Pattern +import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.util.extendable.ExtendableItem -import sbt.CustomPomParser +/** + * This class contains all the logic for dealing with the extra attributes in pom files relating to extra attributes + * on dependency declarations. + * + * Specifically, if we have a dependency on an sbt plugin, there are two properties that need to propogate: + * - `sbtVersion` + * - `scalaVersion` + * + * These need to exist on the *dependency declaration*. Maven/Aether has no way to inject these into + * the section of pom files, so we use Ivy's Extra attribute hackery to inject a lookup table + * of extra attributes by dependency id into POM files and later we read these back. + */ object PomExtraDependencyAttributes { - // TODO - Move custom pom parser extra attribtues code into this class, rather than relying on - // custom pom parser (so we can deprecate it completely). - import CustomPomParser.{ ExtraAttributesKey, simplify, filterCustomExtra, readDependencyExtra } + val ExtraAttributesKey = "extraDependencyAttributes" + val SbtVersionKey = "sbtVersion" + val ScalaVersionKey = "scalaVersion" /** * Reads the extra dependency attributes out of a maven property. * @param props The properties from an Aether resolution. @@ -44,4 +57,55 @@ object PomExtraDependencyAttributes { case None => } } + + /** + * Reads the extra dependency information out of Ivy's notion of POM properties and returns + * the map of ID -> Extra Properties. + */ + def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String, String]] = + (m get ExtraAttributesKey) match { + case None => Map.empty + case Some(str) => + def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include = true)) + readDependencyExtra(str).map(processDep).toMap + } + + def qualifiedExtra(item: ExtendableItem): Map[String, String] = { + import collection.JavaConverters._ + item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap + } + def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = + (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) + + def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) + + // Reduces the id to exclude custom extra attributes + // This makes the id suitable as a key to associate a dependency parsed from a element + // with the extra attributes from the section + def simplify(id: ModuleRevisionId): ModuleRevisionId = { + import collection.JavaConverters._ + ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include = false).asJava) + } + + /** parses the sequence of dependencies with extra attribute information, with one dependency per line */ + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = + LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) + + private[this] val LinesP = Pattern.compile("(?m)^") + + /** + * Creates the "extra" property values for DependencyDescriptors that can be written into a maven pom + * so we don't loose the information. + * @param s + * @return + */ + def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = + s.flatMap { dd => + val revId = dd.getDependencyRevisionId + if (filterCustomExtra(revId, include = true).isEmpty) + Nil + else + revId.encodeToString :: Nil + } + } diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java index 55385f9f0..5570d4fac 100644 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java +++ b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java @@ -3,15 +3,18 @@ package org.apache.maven.repository.internal; /** - * Created by jsuereth on 12/20/14. + * Extra properties we dump from Aether into the properties list. */ public class SbtExtraProperties { + public static final String MAVEN_PACKAGING_KEY = "sbt.pom.packaging"; public static final String SCALA_VERSION_KEY = "sbt.pom.scalaversion"; public static final String SBT_VERSION_KEY = "sbt.pom.sbtversion"; + public static final String POM_INFO_KEY_PREFIX = "info."; public static final String POM_SCALA_VERSION = "scalaVersion"; public static final String POM_SBT_VERSION = "sbtVersion"; + public static final String POM_API_KEY = "info.apiURL"; public static final String LICENSE_COUNT_KEY = "license.count"; diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index d639532a7..d931cefe6 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -13,6 +13,8 @@ import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern +import org.apache.maven.repository.internal.{ SbtExtraProperties, PomExtraDependencyAttributes } + @deprecated("0.13.8", "We now use an Aether-based pom parser.") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = @@ -34,15 +36,16 @@ object CustomPomParser { ReplaceMavenConfigurationMappings.init() /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ - val InfoKeyPrefix = "info." - val ApiURLKey = "info.apiURL" + val InfoKeyPrefix = SbtExtraProperties.POM_INFO_KEY_PREFIX + val ApiURLKey = SbtExtraProperties.POM_API_KEY - val SbtVersionKey = "sbtVersion" - val ScalaVersionKey = "scalaVersion" - val ExtraAttributesKey = "extraDependencyAttributes" + val SbtVersionKey = PomExtraDependencyAttributes.SbtVersionKey + val ScalaVersionKey = PomExtraDependencyAttributes.ScalaVersionKey + val ExtraAttributesKey = PomExtraDependencyAttributes.ExtraAttributesKey private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) // packagings that should be jars, but that Ivy doesn't handle as jars + // TODO - move this elsewhere. val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar") val default = new CustomPomParser(PomModuleDescriptorParser.getInstance, defaultTransform) @@ -125,46 +128,24 @@ object CustomPomParser { } private[this] def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String, String]] = - (m get ExtraAttributesKey) match { - case None => Map.empty - case Some(str) => - def processDep(m: ModuleRevisionId) = (simplify(m), filterCustomExtra(m, include = true)) - readDependencyExtra(str).map(processDep).toMap - } + PomExtraDependencyAttributes.getDependencyExtra(m) - def qualifiedExtra(item: ExtendableItem): Map[String, String] = - { - import collection.JavaConverters._ - item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap - } + def qualifiedExtra(item: ExtendableItem): Map[String, String] = PomExtraDependencyAttributes.qualifiedExtra(item) def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = - s.flatMap { dd => - val revId = dd.getDependencyRevisionId - if (filterCustomExtra(revId, include = true).isEmpty) - Nil - else - revId.encodeToString :: Nil - } + PomExtraDependencyAttributes.writeDependencyExtra(s) // parses the sequence of dependencies with extra attribute information, with one dependency per line - def readDependencyExtra(s: String): Seq[ModuleRevisionId] = - LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = PomExtraDependencyAttributes.readDependencyExtra(s) - private[this] val LinesP = Pattern.compile("(?m)^") - - def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) + def qualifiedIsExtra(k: String): Boolean = PomExtraDependencyAttributes.qualifiedIsExtra(k) // Reduces the id to exclude custom extra attributes // This makes the id suitable as a key to associate a dependency parsed from a element // with the extra attributes from the section - def simplify(id: ModuleRevisionId): ModuleRevisionId = - { - import collection.JavaConverters._ - ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include = false).asJava) - } + def simplify(id: ModuleRevisionId): ModuleRevisionId = PomExtraDependencyAttributes.simplify(id) private[this] def addExtra(dep: DependencyDescriptor, extra: Map[ModuleRevisionId, Map[String, String]]): DependencyDescriptor = { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 3bc3520fd..13ca70f1b 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -8,6 +8,9 @@ package sbt import java.io.File + +import org.apache.maven.repository.internal.PomExtraDependencyAttributes + // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation import scala.xml.{ Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute } @@ -119,12 +122,12 @@ class MakePom(val log: Logger) { def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { val extra = IvySbt.getExtraAttributes(module) - val depExtra = CustomPomParser.writeDependencyExtra(dependencies).mkString("\n") - val allExtra = if (depExtra.isEmpty) extra else extra.updated(CustomPomParser.ExtraAttributesKey, depExtra) + val depExtra = PomExtraDependencyAttributes.writeDependencyExtra(dependencies).mkString("\n") + val allExtra = if (depExtra.isEmpty) extra else extra.updated(PomExtraDependencyAttributes.ExtraAttributesKey, depExtra) if (allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) } def makeProperties(extra: Map[String, String]): NodeSeq = { - def _extraAttributes(k: String) = if (k == CustomPomParser.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null + def _extraAttributes(k: String) = if (k == PomExtraDependencyAttributes.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null { for ((key, value) <- extra) yield ({ value }).copy(label = key, attributes = _extraAttributes(key)) } diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index 178940666..bf734f5f7 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -5,6 +5,8 @@ package sbt import java.net.URL +import org.apache.maven.repository.internal.SbtExtraProperties + final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = organization + ":" + name + ":" + revision + @@ -15,7 +17,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ - def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(CustomPomParser.InfoKeyPrefix)) + def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtExtraProperties.POM_INFO_KEY_PREFIX)) @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else CrossVersion.Disabled) diff --git a/ivy/src/test/scala/MavenResolutionSpec.scala b/ivy/src/test/scala/MavenResolutionSpec.scala index f7b46895d..8015e78a8 100644 --- a/ivy/src/test/scala/MavenResolutionSpec.scala +++ b/ivy/src/test/scala/MavenResolutionSpec.scala @@ -2,6 +2,7 @@ package sbt import java.io.FileInputStream +import org.apache.maven.repository.internal.PomExtraDependencyAttributes import org.specs2._ class MavenResolutionSpec extends BaseIvySpecification { @@ -37,11 +38,11 @@ class MavenResolutionSpec extends BaseIvySpecification { def scalaContinuationPlugin = ModuleID("org.scala-lang.plugins", "continuations", "2.8.1", Some("plugin->default(compile)")) def sbtPlugin = ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). - extra(CustomPomParser.SbtVersionKey -> "0.13", CustomPomParser.ScalaVersionKey -> "2.10"). + extra(PomExtraDependencyAttributes.SbtVersionKey -> "0.13", PomExtraDependencyAttributes.ScalaVersionKey -> "2.10"). copy(crossVersion = CrossVersion.Disabled) def oldSbtPlugin = ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). - extra(CustomPomParser.SbtVersionKey -> "0.12", CustomPomParser.ScalaVersionKey -> "2.9.2"). + extra(PomExtraDependencyAttributes.SbtVersionKey -> "0.12", PomExtraDependencyAttributes.ScalaVersionKey -> "2.9.2"). copy(crossVersion = CrossVersion.Disabled) def majorConflictLib = ModuleID("com.joestelmach", "natty", "0.3", Some("compile")) // TODO - This snapshot and resolver should be something we own/control so it doesn't disappear on us. From 7bbacce172fd44ffd70ed20ab61dd1d650646b5b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 8 Jan 2015 18:02:59 -0500 Subject: [PATCH 0385/1030] Turn Aether integration into sbt-maven-resolver --- .../resolver/MavenRepositoryResolver.scala | 674 ------------------ .../MavenRepositorySystemFactory.scala | 160 ----- .../internal/SbtArtifactDescriptorReader.java | 558 --------------- .../internal/SbtExtraProperties.java | 27 - .../internal/SbtRepositoryLayout.scala | 100 --- ivy/src/main/scala/sbt/ConvertResolver.scala | 51 +- ivy/src/main/scala/sbt/Ivy.scala | 3 +- ivy/src/main/scala/sbt/MakePom.scala | 3 +- ivy/src/main/scala/sbt/UpdateOptions.scala | 27 +- .../sbt/ivyint/CustomMavenResolver.scala | 11 + .../scala/sbt/ivyint/SbtChainResolver.scala | 2 +- 11 files changed, 55 insertions(+), 1561 deletions(-) delete mode 100644 ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala delete mode 100644 ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala delete mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java delete mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java delete mode 100644 ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala create mode 100644 ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala deleted file mode 100644 index 6ff019c6a..000000000 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositoryResolver.scala +++ /dev/null @@ -1,674 +0,0 @@ -package org.apache.ivy.plugins.resolver - -import java.io.{ File, IOException } -import java.text.ParseException -import java.util.Date -import org.apache.ivy.core.IvyContext -import org.apache.ivy.core.module.descriptor._ -import org.apache.ivy.core.module.id.{ ModuleId, ArtifactId, ModuleRevisionId } -import org.apache.ivy.core.report.{ ArtifactDownloadReport, DownloadStatus, MetadataArtifactDownloadReport, DownloadReport } -import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData, DownloadOptions } -import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.plugins.matcher.ExactPatternMatcher -import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorBuilder, ReplaceMavenConfigurationMappings } -import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter -import org.apache.ivy.plugins.resolver.MavenRepositoryResolver.JarPackaging -import org.apache.ivy.plugins.resolver.util.ResolvedResource -import org.apache.ivy.util.Message -import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes, SbtRepositoryLayout, SbtExtraProperties } -import org.eclipse.aether.{ RepositorySystemSession, RepositorySystem } -import org.eclipse.aether.artifact.{ DefaultArtifact => AetherArtifact } -import org.eclipse.aether.metadata.{ Metadata, DefaultMetadata } -import org.eclipse.aether.resolution.{ - ArtifactDescriptorRequest => AetherDescriptorRequest, - ArtifactDescriptorResult => AetherDescriptorResult, - MetadataRequest => AetherMetadataRequest, - ArtifactRequest => AetherArtifactRequest, - ArtifactResolutionException -} -import org.eclipse.aether.deployment.{ DeployRequest => AetherDeployRequest } -import org.eclipse.aether.installation.{ InstallRequest => AetherInstallRequest } -import org.apache.ivy.core.cache.{ ModuleDescriptorWriter, ArtifactOrigin } -import sbt.{ MavenCache, MavenRepository } -import scala.collection.JavaConverters._ - -object MavenRepositoryResolver { - val MAVEN_METADATA_XML = "maven-metadata.xml" - val CLASSIFIER_ATTRIBUTE = "e:classifier" - - val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar", "jar", "bundle") - - object JarPackaging { - def unapply(in: String): Boolean = JarPackagings.contains(in) - } - - // Example: 2014 12 18 09 33 56 - val LAST_UPDATE_FORMAT = new java.text.SimpleDateFormat("yyyyMMddhhmmss") - def parseTimeString(in: String): Option[Long] = - try Some(LAST_UPDATE_FORMAT.parse(in).getTime) - catch { - case _: java.text.ParseException => None - } - - val DEFAULT_ARTIFACT_CONFIGURATION = "master" - -} - -/** - * A resolver instance which can resolve from a REMOTE maven repository. - * - * Note: This creates its *own* local cache directory for cache metadata. using its name. - * - */ -class MavenRemoteRepositoryResolver(val repo: MavenRepository, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { - setName(repo.name) - override def toString = s"${repo.name}: ${repo.root}" - protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl - // Note: All maven repository resolvers will use the SAME maven cache. - // We're not sure if we care whether or not this means that the wrong resolver may report finding an artifact. - // The key is not to duplicate files repeatedly across many caches. - private val localRepo = new java.io.File(settings.getDefaultIvyUserDir, s"maven-cache") - sbt.IO.createDirectory(localRepo) - protected val session = MavenRepositorySystemFactory.newSessionImpl(system, localRepo) - private val aetherRepository = { - new org.eclipse.aether.repository.RemoteRepository.Builder(repo.name, SbtRepositoryLayout.LAYOUT_NAME, repo.root).build() - } - // TODO - Check if isUseCacheOnly is used correctly. - private def isUseCacheOnly: Boolean = - Option(IvyContext.getContext).flatMap(x => Option(x.getResolveData)).flatMap(x => Option(x.getOptions)).map(_.isUseCacheOnly).getOrElse(false) - protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest = - if (isUseCacheOnly) request else request.addRepository(aetherRepository) - protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest = - if (isUseCacheOnly) request else request.addRepository(aetherRepository) - /** Actually publishes aether artifacts. */ - protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit = { - val request = new AetherDeployRequest() - request.setRepository(aetherRepository) - artifacts foreach request.addArtifact - system.deploy(session, request) - } - protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] = { - val metadataRequest = new AetherMetadataRequest() - metadataRequest.setMetadata( - new DefaultMetadata( - mrid.getOrganisation, - mrid.getName, - mrid.getRevision, - MavenRepositoryResolver.MAVEN_METADATA_XML, - Metadata.Nature.RELEASE_OR_SNAPSHOT)) - if (!isUseCacheOnly) metadataRequest.setRepository(aetherRepository) - val metadataResultOpt = - try system.resolveMetadata(session, java.util.Arrays.asList(metadataRequest)).asScala.headOption - catch { - case e: org.eclipse.aether.resolution.ArtifactResolutionException => None - } - try metadataResultOpt match { - case Some(md) if md.isResolved => - import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader - import org.codehaus.plexus.util.ReaderFactory - val readMetadata = { - val reader = ReaderFactory.newXmlReader(md.getMetadata.getFile) - try new MetadataXpp3Reader().read(reader, false) - finally reader.close() - } - val timestampOpt = - for { - v <- Option(readMetadata.getVersioning) - sp <- Option(v.getSnapshot) - ts <- Option(sp.getTimestamp) - t <- MavenRepositoryResolver.parseTimeString(ts) - } yield t - val lastUpdatedOpt = - for { - v <- Option(readMetadata.getVersioning) - lu <- Option(v.getLastUpdated) - d <- MavenRepositoryResolver.parseTimeString(lu) - } yield d - // TODO - Only look at timestamp *IF* the version is for a snapshot. - timestampOpt orElse lastUpdatedOpt - case _ => None - } - } -} - -/** - * A resolver instance which can resolve from a maven CACHE. - * - * Note: This should never hit somethign remote, as it just looks in the maven cache for things already resolved. - */ -class MavenCacheRepositoryResolver(val repo: MavenCache, settings: IvySettings) extends AbstractMavenRepositoryResolver(settings) { - setName(repo.name) - protected val system = MavenRepositorySystemFactory.newRepositorySystemImpl - sbt.IO.createDirectory(repo.rootFile) - protected val session = MavenRepositorySystemFactory.newSessionImpl(system, repo.rootFile) - protected def setRepository(request: AetherMetadataRequest): AetherMetadataRequest = request - protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest = request - protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest = request - protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit = { - val request = new AetherInstallRequest() - artifacts foreach request.addArtifact - system.install(session, request) - } - // TODO - Share this with non-local repository code, since it's MOSTLY the same. - protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] = { - val metadataRequest = new AetherMetadataRequest() - metadataRequest.setMetadata( - new DefaultMetadata( - mrid.getOrganisation, - mrid.getName, - mrid.getRevision, - MavenRepositoryResolver.MAVEN_METADATA_XML, - Metadata.Nature.RELEASE_OR_SNAPSHOT)) - val metadataResultOpt = - try system.resolveMetadata(session, java.util.Arrays.asList(metadataRequest)).asScala.headOption - catch { - case e: org.eclipse.aether.resolution.ArtifactResolutionException => None - } - try metadataResultOpt match { - case Some(md) if md.isResolved => - import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader - import org.codehaus.plexus.util.ReaderFactory - val readMetadata = { - val reader = ReaderFactory.newXmlReader(md.getMetadata.getFile) - try new MetadataXpp3Reader().read(reader, false) - finally reader.close() - } - val timestampOpt = - for { - v <- Option(readMetadata.getVersioning) - sp <- Option(v.getSnapshot) - ts <- Option(sp.getTimestamp) - t <- MavenRepositoryResolver.parseTimeString(ts) - } yield t - val lastUpdatedOpt = - for { - v <- Option(readMetadata.getVersioning) - lu <- Option(v.getLastUpdated) - d <- MavenRepositoryResolver.parseTimeString(lu) - } yield d - // TODO - Only look at timestamp *IF* the version is for a snapshot. - timestampOpt orElse lastUpdatedOpt - case _ => None - } - } - override def toString = s"${repo.name}: ${repo.root}" -} - -/** An exception we can throw if we encounter issues. */ -class MavenResolutionException(msg: String) extends RuntimeException(msg) {} - -abstract class AbstractMavenRepositoryResolver(settings: IvySettings) extends AbstractResolver { - - /** Our instance of the aether repository system. */ - protected val system: RepositorySystem - /** - * Our instance of the aether repository system session. - * - * TODO - We may want to tie this into an IvyContext. - */ - protected val session: RepositorySystemSession - - /** Determine the publication time of a module. The mechanism may differ if the repository is remote vs. local. */ - protected def getPublicationTime(mrid: ModuleRevisionId): Option[Long] - /** Inject necessary repositories into a descriptor request. */ - protected def addRepositories(request: AetherDescriptorRequest): AetherDescriptorRequest - protected def addRepositories(request: AetherArtifactRequest): AetherArtifactRequest - - /** Actually publishes aether artifacts. */ - protected def publishArtifacts(artifacts: Seq[AetherArtifact]): Unit - - // TOOD - deal with packaging here. - private def aetherArtifactIdFromMrid(mrid: ModuleRevisionId): String = - getSbtVersion(mrid) match { - case Some(sbt) => s"${mrid.getName}_sbt_$sbt" - case None => mrid.getName - } - private def aetherCoordsFromMrid(mrid: ModuleRevisionId): String = - s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:${mrid.getRevision}" - - private def aetherCoordsFromMrid(mrid: ModuleRevisionId, packaging: String): String = - s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:$packaging:${mrid.getRevision}" - - private def aetherCoordsFromMrid(mrid: ModuleRevisionId, packaging: String, extension: String): String = - s"${mrid.getOrganisation}:${aetherArtifactIdFromMrid(mrid)}:$extension:$packaging:${mrid.getRevision}" - - // Handles appending licenses to the module descriptor fromthe pom. - private def addLicenseInfo(md: DefaultModuleDescriptor, map: java.util.Map[String, AnyRef]) = { - val count = map.get(SbtExtraProperties.LICENSE_COUNT_KEY) match { - case null => 0 - case x: java.lang.Integer => x.intValue - case x: String => x.toInt - case _ => 0 - } - for { - i <- 0 until count - name <- Option(map.get(SbtExtraProperties.makeLicenseName(i))).map(_.toString) - url <- Option(map.get(SbtExtraProperties.makeLicenseUrl(i))).map(_.toString) - } md.addLicense(new License(name, url)) - } - - // This grabs the dependency for Ivy. - override def getDependency(dd: DependencyDescriptor, rd: ResolveData): ResolvedModuleRevision = { - val context = IvyContext.pushNewCopyContext - try { - // TODO - Check to see if we're asking for latest.* version, and if so, we should run a latest version query - // first and use that result to return the metadata/final module. - Message.debug(s"Requesting conf [${dd.getModuleConfigurations.mkString(",")}] from Aether module ${dd.getDependencyRevisionId} in resolver ${getName}") - val request = new AetherDescriptorRequest() - val coords = aetherCoordsFromMrid(dd.getDependencyRevisionId) - Message.debug(s"Aether about to resolve [$coords]...") - request.setArtifact(new AetherArtifact(coords, getArtifactProperties(dd.getDependencyRevisionId))) - addRepositories(request) - val result = system.readArtifactDescriptor(session, request) - val packaging = getPackagingFromPomProperties(result.getProperties) - Message.debug(s"Aether resolved ${dd.getDependencyId} w/ packaging ${packaging}") - - // TODO - better pub date if we have no metadata. - val lastModifiedTime = getPublicationTime(dd.getDependencyRevisionId) getOrElse 0L - - // Construct a new Ivy module descriptor - val desc: ModuleDescriptor = { - // TODO - Better detection of snapshot and handling latest.integration/latest.snapshot - val status = - if (dd.getDependencyRevisionId.getRevision.endsWith("-SNAPSHOT")) "integration" - else "release" - val md = - new DefaultModuleDescriptor(dd.getDependencyRevisionId, status, null /* pubDate */ , false) - //DefaultModuleDescriptor.newDefaultInstance(dd.getDependencyRevisionId) - // Here we add the standard configurations - for (config <- PomModuleDescriptorBuilder.MAVEN2_CONFIGURATIONS) { - md.addConfiguration(config) - } - - // Here we look into the artifacts specified from the dependency descriptor *and* those that are defaulted, - // and append them to the appropriate configurations. - addArtifactsFromPom(dd, packaging, md, lastModifiedTime) - // Here we add dependencies. - addDependenciesFromAether(result, md) - // Here we use pom.xml Dependency management section to create Ivy dependency mediators. - addManagedDependenciesFromAether(result, md) - // TODO - Add excludes? - - // Here we rip out license info. - addLicenseInfo(md, result.getProperties) - md.addExtraInfo(SbtExtraProperties.MAVEN_PACKAGING_KEY, packaging) - Message.debug(s"Setting publication date to ${new Date(lastModifiedTime)}") - // TODO - Figure out the differences between these items. - md.setPublicationDate(new Date(lastModifiedTime)) - md.setLastModified(lastModifiedTime) - md.setResolvedPublicationDate(new Date(lastModifiedTime)) - md.check() - // TODO - do we need the toSystem? - toSystem(md) - } - - // Here we need to pretend we downloaded the pom.xml file - val pom = DefaultArtifact.newPomArtifact(dd.getDependencyRevisionId, new java.util.Date(lastModifiedTime)) - val madr = new MetadataArtifactDownloadReport(pom) - madr.setSearched(true) - madr.setDownloadStatus(DownloadStatus.SUCCESSFUL) // TODO - Figure this things out for this report. - val rmr = new ResolvedModuleRevision(this, this, desc, madr, false /* Force */ ) - - // TODO - Here we cache the transformed pom.xml into an ivy.xml in the cache because ChainResolver will be looking at it. - // This doesn't appear to really work correctly. - // However, I think the chain resolver doesn't use this instance anyway. Ideally we don't put anything - // in the ivy cache, but this should be "ok". - getRepositoryCacheManager.originalToCachedModuleDescriptor(this, - null /* ivyRef. Just passed back to us. */ , - pom, - rmr, - new ModuleDescriptorWriter() { - def write(originalMdResource: ResolvedResource, md: ModuleDescriptor, src: File, dest: File): Unit = { - // a basic ivy file is written containing default data - XmlModuleDescriptorWriter.write(md, dest); - } - } - ) - rmr - } catch { - case e: org.eclipse.aether.resolution.ArtifactDescriptorException => - Message.info(s"Failed to read descriptor ${dd} from ${getName}, ${e.getMessage}") - rd.getCurrentResolvedModuleRevision - case e: MavenResolutionException => - Message.debug(s"Resolution Exception from ${getName}, ${e.getMessage}, returning: ${rd.getCurrentResolvedModuleRevision}") - rd.getCurrentResolvedModuleRevision - } finally IvyContext.popContext() - } - - def getSbtVersion(dd: ModuleRevisionId): Option[String] = - Option(dd.getExtraAttribute(PomExtraDependencyAttributes.SbtVersionKey)) - - def getArtifactProperties(dd: ModuleRevisionId): java.util.Map[String, String] = { - val m = new java.util.HashMap[String, String] - Option(dd.getExtraAttribute(PomExtraDependencyAttributes.ScalaVersionKey)) foreach { sv => - m.put(SbtExtraProperties.POM_SCALA_VERSION, sv) - } - getSbtVersion(dd) foreach { sv => - m.put(SbtExtraProperties.POM_SBT_VERSION, sv) - } - m - } - - final def checkJarArtifactExists(dd: DependencyDescriptor): Boolean = { - // TODO - We really want this to be as fast/efficient as possible! - val request = new AetherArtifactRequest() - val art = new AetherArtifact( - aetherCoordsFromMrid(dd.getDependencyRevisionId, "jar"), - getArtifactProperties(dd.getDependencyRevisionId)) - request.setArtifact(art) - addRepositories(request) - try { - val result = system.resolveArtifact(session, request) - result.isResolved && !result.isMissing - } catch { - case e: ArtifactResolutionException => - // Ignore, as we're just working around issues with pom.xml's with no jars or POM packaging - Message.debug(s"Could not find $art in ${getName}") - false - } - } - - /** Determines which artifacts are associated with this maven module and appends them to the descriptor. */ - def addArtifactsFromPom(dd: DependencyDescriptor, packaging: String, md: DefaultModuleDescriptor, lastModifiedTime: Long): Unit = { - Message.debug(s"Calculating artifacts for ${dd.getDependencyId} w/ packaging $packaging") - // Here we add in additional artifact requests, which ALLWAYS have to be explicit since - // Maven/Aether doesn't include all known artifacts in a pom.xml - // TODO - This does not appear to be working correctly. - if (dd.getAllDependencyArtifacts.isEmpty) { - val artifactId = s"${dd.getDependencyId.getName}-${dd.getDependencyRevisionId.getRevision}" - // Add the artifacts we know about the module - packaging match { - case "pom" => - // THere we have to attempt to download the JAR and see if it comes, if not, we can punt. - // This is because sometimes pom-packaging attaches a JAR. - if (checkJarArtifactExists(dd)) { - val defaultArt = - new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), artifactId, packaging, "jar") - md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) - } - case JarPackaging() => - // Here we fail the resolution. This is an issue when pom.xml files exist with no JAR, which happens - // on maven central for some reason on old artifacts. - if (!checkJarArtifactExists(dd)) - throw new MavenResolutionException(s"Failed to find JAR file associated with $dd") - // Assume for now everything else is a jar. - val defaultArt = - new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), artifactId, packaging, "jar") - // TODO - Unfortunately we have to try to download the JAR file HERE and then fail resolution if we cannot find it. - // This is because sometime a pom.xml exists with no JARs. - md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) - case _ => // Ignore, we have no idea what this artifact is. - Message.warn(s"Not adding artifacts for resolution because we don't understand packaging: $packaging") - } - - } else { - // NOTE: this means that someone is requested specific artifacts from us. What we need to do is *only* download the - // requested artifacts rather than the default "jar". What's odd, is that pretty much this almost ALWAYS happens. - // but in some circumstances, the above logic is checked. - // Additionally, we may want to somehow merge the "defined" artifacts from maven with the requested ones here, rather - // than having completely separate logic. For now, this appears to work the same way it was before. - // Since we aren't accurately guessing what maven files are meant to be included as artifacts ANYWAY, this - // is probably the right way to go. - for (requestedArt <- dd.getAllDependencyArtifacts) { - getClassifier(requestedArt) match { - case None => - // This is the default artifact. We do need to add this, and to the default configuration. - val defaultArt = - new DefaultArtifact(md.getModuleRevisionId, new Date(lastModifiedTime), requestedArt.getName, requestedArt.getType, requestedArt.getExt) - md.addArtifact(MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION, defaultArt) - case Some(scope) => - Message.debug(s"Adding additional artifact in $scope, $requestedArt") - // TODO - more Extra attributes? - val mda = - new MDArtifact( - md, - requestedArt.getName, - requestedArt.getType, - requestedArt.getExt, - requestedArt.getUrl, - requestedArt.getExtraAttributes) - md.addArtifact(getConfiguration(scope), mda) - } - } - } - } - - /** Adds the dependency mediators required based on the managed dependency instances from this pom. */ - def addManagedDependenciesFromAether(result: AetherDescriptorResult, md: DefaultModuleDescriptor) { - for (d <- result.getManagedDependencies.asScala) { - - if (d.getArtifact.getArtifactId == "stringtemplate") { - Message.warn(s"Found managed stringtemplate in $md !") - } - - md.addDependencyDescriptorMediator( - ModuleId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId), - ExactPatternMatcher.INSTANCE, - new OverrideDependencyDescriptorMediator(null, d.getArtifact.getVersion) { - override def mediate(dd: DependencyDescriptor): DependencyDescriptor = { - super.mediate(dd) - } - }) - - } - } - - /** Adds the list of dependencies this artifact has on other artifacts. */ - def addDependenciesFromAether(result: AetherDescriptorResult, md: DefaultModuleDescriptor) { - // First we construct a map of any extra attributes we must append to dependencies. - // This is necessary for transitive maven-based sbt plugin dependencies, where we need to - // attach the sbtVersion/scalaVersion to the dependency id otherwise we'll fail to resolve the - // dependency correctly. - val extraAttributes = PomExtraDependencyAttributes.readFromAether(result.getProperties) - for (d <- result.getDependencies.asScala) { - // TODO - Is this correct for changing detection. We should use the Ivy mechanism configured... - val isChanging = d.getArtifact.getVersion.endsWith("-SNAPSHOT") - val drid = { - val tmp = ModuleRevisionId.newInstance(d.getArtifact.getGroupId, d.getArtifact.getArtifactId, d.getArtifact.getVersion) - extraAttributes get tmp match { - case Some(props) => - Message.debug(s"Found $tmp w/ extra attributes ${props.mkString(",")}") - ModuleRevisionId.newInstance( - d.getArtifact.getGroupId, - d.getArtifact.getArtifactId, - d.getArtifact.getVersion, - props.asJava - ) - case _ => tmp - } - } - - // Note: The previous maven integration ALWAYS set force to true for dependnecies. If we do not do this, for some - // reason, Ivy will create dummy nodes when doing dependnecy mediation (e.g. dependencyManagement of one pom overrides version of a dependency) - // which was leading to "data not found" exceptions as Ivy would pick the correct IvyNode in the dependency tree but never load it with data.... - val dd = new DefaultDependencyDescriptor(md, drid, /* force */ true, isChanging, true) {} - - // TODO - Configuration mappings (are we grabbing scope correctly, or should the default not always be compile?) - val scope = Option(d.getScope).filterNot(_.isEmpty).getOrElse("compile") - val mapping = ReplaceMavenConfigurationMappings.addMappings(dd, scope, d.isOptional) - // TODO - include rules and exclude rules. - Message.debug(s"Adding maven transitive dependency ${md.getModuleRevisionId} -> ${dd}") - // TODO - Unify this borrowed Java code into something a bit friendlier. - // Now we add the artifact.... - if ((d.getArtifact.getClassifier != null) || ((d.getArtifact.getExtension != null) && !("jar" == d.getArtifact.getExtension))) { - val tpe: String = - if (d.getArtifact.getExtension != null) d.getArtifact.getExtension - else "jar" - val ext: String = tpe match { - case "test-jar" => "jar" - case JarPackaging() => "jar" - case other => other - } - // Here we add the classifier, hopefully correctly... - val extraAtt = new java.util.HashMap[String, AnyRef]() - if (d.getArtifact.getClassifier != null) { - extraAtt.put("m:classifier", d.getArtifact.getClassifier) - } - val depArtifact: DefaultDependencyArtifactDescriptor = - new DefaultDependencyArtifactDescriptor(dd, dd.getDependencyId.getName, tpe, ext, null, extraAtt) - val optionalizedScope: String = if (d.isOptional) "optional" else scope - // TOOD - We may need to fix the configuration mappings here. - dd.addDependencyArtifact(optionalizedScope, depArtifact) - } - // TODO - is toSystem call correct? - md.addDependency(dd) - - if (d.getArtifact.getArtifactId == "stringtemplate") { - Message.warn(s"Found stringtemplate dependency! $dd") - } - } - } - - // This method appears to be deprecated/unused in all of Ivy so we do not implement it. - override def findIvyFileRef(dd: DependencyDescriptor, rd: ResolveData): ResolvedResource = { - Message.error(s"Looking for ivy file ref, method not implemented! MavenRepositoryResolver($getName) will always return null.") - null - } - - private def getPackagingFromPomProperties(props: java.util.Map[String, AnyRef]): String = - if (props.containsKey(SbtExtraProperties.MAVEN_PACKAGING_KEY)) - props.get(SbtExtraProperties.MAVEN_PACKAGING_KEY).toString - else "jar" - - override def download(artifacts: Array[Artifact], dopts: DownloadOptions): DownloadReport = { - // TODO - Status reports on download and possibly parallel downloads - val report = new DownloadReport - val requests = - for (a <- artifacts) yield { - val request = new AetherArtifactRequest - val aetherArt = - getClassifier(a) match { - case None | Some("") => - new AetherArtifact( - aetherCoordsFromMrid(a.getModuleRevisionId), - getArtifactProperties(a.getModuleRevisionId)) - case Some(other) => new AetherArtifact( - aetherCoordsFromMrid(a.getModuleRevisionId, other, a.getExt), - getArtifactProperties(a.getModuleRevisionId)) - } - Message.debug(s"Requesting download of [$aetherArt]") - request.setArtifact(aetherArt) - addRepositories(request) - request - } - val (aetherResults, failed) = - try { - (system.resolveArtifacts(session, requests.toList.asJava).asScala, false) - } catch { - case e: org.eclipse.aether.resolution.ArtifactResolutionException => - Message.error(s"Failed to resolve artifacts from ${getName}, ${e.getMessage}") - (e.getResults.asScala, true) - } - for ((result, art) <- aetherResults zip artifacts) { - Message.debug(s"Aether resolved artifact result: $result") - val adr = new ArtifactDownloadReport(art) - adr.setDownloadDetails(result.toString) - // TODO - Fill this out with a real estimate on time... - adr.setDownloadTimeMillis(0L) - // TODO - what is artifact origin actuallyused for? - adr.setArtifactOrigin(new ArtifactOrigin( - art, - true, - getName)) - if (result.isMissing) { - adr.setDownloadStatus(DownloadStatus.FAILED) - adr.setDownloadDetails(ArtifactDownloadReport.MISSING_ARTIFACT) - } else if (!result.isResolved) { - adr.setDownloadStatus(DownloadStatus.FAILED) - adr.setDownloadDetails(result.toString) - // TODO - we should set download status to NO in the event we don't care about an artifact... - } else { - val file = result.getArtifact.getFile - Message.debug(s"Succesffully downloaded: $file") - adr.setLocalFile(file) - adr.setSize(file.length) - adr.setDownloadStatus(DownloadStatus.SUCCESSFUL) - } - report.addArtifactReport(adr) - } - report - } - - case class PublishTransaction(module: ModuleRevisionId, artifacts: Seq[(Artifact, File)]) - private var currentTransaction: Option[PublishTransaction] = None - - override def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean): Unit = { - currentTransaction match { - case Some(t) => throw new IllegalStateException(s"Publish Transaction already open for [$getName]") - case None => currentTransaction = Some(PublishTransaction(module, Nil)) - } - } - override def abortPublishTransaction(): Unit = { - currentTransaction = None - } - - def getClassifier(art: Artifact): Option[String] = - // TODO - Do we need to look anywere else? - Option(art.getExtraAttribute("classifier")) - - def getClassifier(art: org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor): Option[String] = - art.getType match { - case "doc" | "javadoc" => Some("javadoc") - case "src" | "source" => Some("sources") - case "test-jar" | "test" => Some("tests") - case _ => - // Look for extra attributes - art.getExtraAttribute(MavenRepositoryResolver.CLASSIFIER_ATTRIBUTE) match { - case null => None - case c => Some(c) - } - } - - def getConfiguration(classifier: String): String = - classifier match { - // TODO - choice of configuration actually depends on whether or not the artifact is - // REQUESTED by the user, in which case it should be on master. - // Currently, we don't actually look for sources/javadoc/test artifacts at all, - // which means any artifact is in the master configuration, but we should - // fix this for better integration into the maven ecosystem from ivy. - //case "sources" => "sources" - //case "javadoc" => "javadoc" - case other => MavenRepositoryResolver.DEFAULT_ARTIFACT_CONFIGURATION - } - - override def commitPublishTransaction(): Unit = { - // TODO - actually send all artifacts to aether - currentTransaction match { - case Some(t) => - Message.debug(s"Publishing module ${t.module}, with artifact count = ${t.artifacts.size}") - val artifacts = - for ((art, file) <- t.artifacts) yield { - Message.debug(s" - Publishing $art (${art.getType})(${art.getExtraAttribute("classifier")}) in [${art.getConfigurations.mkString(",")}] from $file") - new AetherArtifact( - t.module.getOrganisation, - aetherArtifactIdFromMrid(t.module), - getClassifier(art).orNull, - art.getExt, - t.module.getRevision, - getArtifactProperties(t.module), - file - ) - } - publishArtifacts(artifacts) - // TODO - Any kind of validity checking? - currentTransaction = None - case None => throw new IllegalStateException(s"Publish Transaction already open for [$getName]") - } - } - - override def publish(art: Artifact, file: File, overwrite: Boolean): Unit = { - currentTransaction match { - case Some(t) => - val allArts = t.artifacts ++ List(art -> file) - currentTransaction = Some(t.copy(artifacts = allArts)) - case None => - throw new IllegalStateException(("MavenRepositories require transactional publish")) - } - } - - override def equals(a: Any): Boolean = - a match { - case x: AbstractMavenRepositoryResolver => x.getName == getName - case _ => false - } -} diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala b/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala deleted file mode 100644 index 1946dc0da..000000000 --- a/ivy/src/main/scala/org/apache/ivy/plugins/resolver/MavenRepositorySystemFactory.scala +++ /dev/null @@ -1,160 +0,0 @@ -package org.apache.ivy.plugins.resolver - -import java.net.URI - -import org.apache.ivy.plugins.repository.Resource -import org.apache.ivy.plugins.repository.url.URLResource -import org.apache.ivy.util.Message -import org.apache.ivy.util.url.URLHandlerRegistry -import org.eclipse.aether.artifact.Artifact -import org.eclipse.aether.impl.{ MetadataGeneratorFactory, ArtifactDescriptorReader, RepositoryConnectorProvider, DefaultServiceLocator } -import org.eclipse.aether.metadata.Metadata -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory -import org.eclipse.aether.spi.connector.layout.{ RepositoryLayoutFactory, RepositoryLayoutProvider, RepositoryLayout } -import org.eclipse.aether.spi.connector.layout.RepositoryLayout.Checksum -import org.eclipse.aether.{ - RepositorySystem, - RepositorySystemSession -} - -import org.eclipse.aether.repository.{ RemoteRepository, LocalRepository } -import org.eclipse.aether.RepositorySystemSession -import org.apache.maven.repository.internal._ -import org.eclipse.aether.spi.connector.transport._ -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory -import java.io.File - -/** Helper methods for dealing with starting up Aether. */ -object MavenRepositorySystemFactory { - def newRepositorySystemImpl: RepositorySystem = { - // For now we just log Aether instantiation issues. These should probably cause fatal errors. - val locator = MavenRepositorySystemUtils.newServiceLocator() - locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler { - override def serviceCreationFailed(tpe: Class[_], impl: Class[_], exception: Throwable): Unit = { - Message.error(s"Failed to create $tpe, of class $impl") - } - }) - // Here we register the Ivy <-> Aether transport bridge - locator.addService(classOf[TransporterFactory], classOf[MyTransportFactory]) - // This connects the download mechanism to our transports. Why is it needed? no clue. - locator.addService(classOf[RepositoryConnectorFactory], classOf[BasicRepositoryConnectorFactory]) - - // Plugins cause issues here, as their layout is super odd. Here we inject a new plugin layout - locator.addService(classOf[RepositoryLayoutFactory], classOf[SbtPluginLayoutFactory]) - - // Here we add the metadata services so aether will automatically add maven-metadata.xml files. - locator.addService(classOf[MetadataGeneratorFactory], classOf[SnapshotMetadataGeneratorFactory]) - locator.addService(classOf[MetadataGeneratorFactory], classOf[VersionsMetadataGeneratorFactory]) - - // Add our hook for parsing pom.xml files. - locator.setService(classOf[ArtifactDescriptorReader], classOf[SbtArtifactDescriptorReader]) - // Finally, use the DI to create our repository system. - locator.getService(classOf[RepositorySystem]) - } - def newSessionImpl(system: RepositorySystem, localRepoDir: File): RepositorySystemSession = { - val session = MavenRepositorySystemUtils.newSession() - val localRepo = new LocalRepository(localRepoDir) - session setLocalRepositoryManager (system.newLocalRepositoryManager(session, localRepo)) - // Here we set a descriptor policy that FORCES the pom.xml to exist, otherwise Ivy's resolution - // algorithm freaks out. What we could do is also do the ivy lame-thing of checking for a JAR - // instead of a pom.xml, but let's see if this is actually a problem in practice. - val descriptorPolicy = new org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy( - /* ignoreMissing */ false, /* ignoreInvalid. */ true) - session.setArtifactDescriptorPolicy(descriptorPolicy) - session - } - - def defaultLocalRepo: java.io.File = { - new java.io.File(s"${sys.props("user.home")}/.m2/repository") - } -} -/** Override aether's default transport with Ivy-ones. */ -class MyTransportFactory extends TransporterFactory { - override def newInstance(session: RepositorySystemSession, repository: RemoteRepository): Transporter = - repository.getProtocol match { - case "http" | "https" => new HttpTransport(repository) - case "file" => new FileTransport(repository) - case other => throw new IllegalArgumentException(s"Unsupported transport protocol: $other") - } - override def getPriority: Float = 1.0f -} - -/** Aether Http <-> Ivy Http adapter. Aether's is better, but Ivy's has configuration hooks in sbt. */ -class HttpTransport(repository: RemoteRepository) extends AbstractTransporter { - class NotFoundException(msg: String) extends Exception(msg) - private def toURL(task: TransportTask): java.net.URL = - try new java.net.URL(s"${repository.getUrl}/${task.getLocation.toASCIIString}") - catch { - case e: IllegalArgumentException => throw new IllegalArgumentException(s" URL (${task.getLocation}) is not absolute.") - } - private def toResource(task: TransportTask): Resource = new URLResource(toURL(task)) - override def implPeek(peek: PeekTask): Unit = { - if (!toResource(peek).exists()) throw new NotFoundException(s"Could not find ${peek.getLocation}") - } - override def implClose(): Unit = () - override def implGet(out: GetTask): Unit = { - if (!toResource(out).exists()) throw new NotFoundException(s"Could not find ${out.getLocation}") - URLHandlerRegistry.getDefault.download(toURL(out), out.getDataFile, null) - } - override def implPut(put: PutTask): Unit = { - val to = toURL(put) - Option(put.getDataFile) match { - case Some(file) => URLHandlerRegistry.getDefault.upload(file, to, null) - case None => - // TODO - Ivy does not support uploading not from a file. This isn't very efficient in ANY way, - // so if we rewrite the URL handler for Ivy we should fix this as well. - sbt.IO.withTemporaryFile("tmp", "upload") { file => - val in = put.newInputStream() - try sbt.IO.transfer(in, file) - finally in.close() - URLHandlerRegistry.getDefault.upload(file, to, null) - } - } - - } - override def classify(err: Throwable): Int = - err match { - // TODO - Implement - case _: NotFoundException => Transporter.ERROR_NOT_FOUND - case _ => Transporter.ERROR_OTHER - } -} - -class FileTransport(repository: RemoteRepository) extends AbstractTransporter { - class NotFoundException(msg: String) extends Exception(msg) - private def toURL(task: TransportTask): java.net.URL = - try new java.net.URL(s"${repository.getUrl}/${task.getLocation.toASCIIString}") - catch { - case e: IllegalArgumentException => throw new IllegalArgumentException(s" URL (${task.getLocation}) is not absolute.") - } - private def toResource(task: TransportTask): Resource = new URLResource(toURL(task)) - private def toFile(task: TransportTask): java.io.File = - new java.io.File(toURL(task).toURI) - override def implPeek(peek: PeekTask): Unit = { - if (!toFile(peek).exists()) throw new NotFoundException(s"Could not find ${peek.getLocation}") - } - override def implClose(): Unit = () - override def implGet(out: GetTask): Unit = { - val from = toFile(out) - if (!from.exists()) throw new NotFoundException(s"Could not find ${out.getLocation}") - sbt.IO.copyFile(from, out.getDataFile, true) - } - override def implPut(put: PutTask): Unit = { - val to = toFile(put) - Option(put.getDataFile) match { - case Some(from) => - sbt.IO.copyFile(from, to, true) - case None => - // Here it's most likely a SHA or somethign where we read from memory. - val in = put.newInputStream - try sbt.IO.transfer(in, to) - finally in.close() - } - } - override def classify(err: Throwable): Int = - err match { - // TODO - Implement - case _: NotFoundException => Transporter.ERROR_NOT_FOUND - case _ => Transporter.ERROR_OTHER - } -} \ No newline at end of file diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java deleted file mode 100644 index c816145e9..000000000 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtArtifactDescriptorReader.java +++ /dev/null @@ -1,558 +0,0 @@ -package org.apache.maven.repository.internal; - -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.apache.maven.model.DependencyManagement; -import org.apache.maven.model.DistributionManagement; -import org.apache.maven.model.License; -import org.apache.maven.model.Model; -import org.apache.maven.model.Prerequisites; -import org.apache.maven.model.Relocation; -import org.apache.maven.model.Repository; -import org.apache.maven.model.building.DefaultModelBuilderFactory; -import org.apache.maven.model.building.DefaultModelBuildingRequest; -import org.apache.maven.model.building.FileModelSource; -import org.apache.maven.model.building.ModelBuilder; -import org.apache.maven.model.building.ModelBuildingException; -import org.apache.maven.model.building.ModelBuildingRequest; -import org.apache.maven.model.building.ModelProblem; -import org.apache.maven.model.resolution.UnresolvableModelException; -import org.codehaus.plexus.component.annotations.Component; -import org.codehaus.plexus.component.annotations.Requirement; -import org.eclipse.aether.RepositoryException; -import org.eclipse.aether.RepositoryEvent.EventType; -import org.eclipse.aether.RepositoryEvent; -import org.eclipse.aether.RepositorySystemSession; -import org.eclipse.aether.RequestTrace; -import org.eclipse.aether.artifact.Artifact; -import org.eclipse.aether.artifact.ArtifactProperties; -import org.eclipse.aether.artifact.ArtifactType; -import org.eclipse.aether.artifact.ArtifactTypeRegistry; -import org.eclipse.aether.artifact.DefaultArtifact; -import org.eclipse.aether.artifact.DefaultArtifactType; -import org.eclipse.aether.graph.Dependency; -import org.eclipse.aether.graph.Exclusion; -import org.eclipse.aether.impl.*; -import org.eclipse.aether.repository.WorkspaceRepository; -import org.eclipse.aether.resolution.ArtifactDescriptorException; -import org.eclipse.aether.resolution.ArtifactDescriptorPolicy; -import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest; -import org.eclipse.aether.resolution.ArtifactDescriptorRequest; -import org.eclipse.aether.resolution.ArtifactDescriptorResult; -import org.eclipse.aether.resolution.ArtifactRequest; -import org.eclipse.aether.resolution.ArtifactResolutionException; -import org.eclipse.aether.resolution.ArtifactResult; -import org.eclipse.aether.resolution.VersionRequest; -import org.eclipse.aether.resolution.VersionResolutionException; -import org.eclipse.aether.resolution.VersionResult; -import org.eclipse.aether.spi.locator.Service; -import org.eclipse.aether.spi.locator.ServiceLocator; -import org.eclipse.aether.spi.log.Logger; -import org.eclipse.aether.spi.log.LoggerFactory; -import org.eclipse.aether.spi.log.NullLoggerFactory; -import org.eclipse.aether.transfer.ArtifactNotFoundException; - -/** - * A hacked version of maven's default artifact descriptor reader which we use in place of the standard aether adapter. - * - * This adds the following to the parsing of maven files: - * - * Additonal properties: - * - * - `sbt.pom.packaging` - The pom.packaging value. - * - * - * @author Benjamin Bentmann - * @author Josh Suereth - Adapted for sbt - */ -@Named -@Component( role = ArtifactDescriptorReader.class ) -public class SbtArtifactDescriptorReader - implements ArtifactDescriptorReader, Service -{ - - @SuppressWarnings( "unused" ) - @Requirement( role = LoggerFactory.class ) - private Logger logger = NullLoggerFactory.LOGGER; - - @Requirement - private RemoteRepositoryManager remoteRepositoryManager; - - @Requirement - private VersionResolver versionResolver; - - @Requirement - private VersionRangeResolver versionRangeResolver; - - @Requirement - private ArtifactResolver artifactResolver; - - @Requirement - private RepositoryEventDispatcher repositoryEventDispatcher; - - @Requirement - private ModelBuilder modelBuilder; - - public SbtArtifactDescriptorReader() - { - // enable no-arg constructor - } - - @Inject - SbtArtifactDescriptorReader( RemoteRepositoryManager remoteRepositoryManager, VersionResolver versionResolver, - ArtifactResolver artifactResolver, ModelBuilder modelBuilder, - RepositoryEventDispatcher repositoryEventDispatcher, LoggerFactory loggerFactory ) - { - setRemoteRepositoryManager( remoteRepositoryManager ); - setVersionResolver( versionResolver ); - setArtifactResolver( artifactResolver ); - setModelBuilder( modelBuilder ); - setLoggerFactory( loggerFactory ); - setRepositoryEventDispatcher( repositoryEventDispatcher ); - } - - public void initService( ServiceLocator locator ) - { - setLoggerFactory(locator.getService(LoggerFactory.class)); - setRemoteRepositoryManager(locator.getService(RemoteRepositoryManager.class)); - setVersionResolver(locator.getService(VersionResolver.class)); - setArtifactResolver(locator.getService(ArtifactResolver.class)); - setRepositoryEventDispatcher(locator.getService(RepositoryEventDispatcher.class)); - setVersionRangeResolver(locator.getService(VersionRangeResolver.class)); - modelBuilder = locator.getService( ModelBuilder.class ); - if ( modelBuilder == null ) - { - setModelBuilder( new DefaultModelBuilderFactory().newInstance() ); - } - } - - public SbtArtifactDescriptorReader setLoggerFactory( LoggerFactory loggerFactory ) - { - this.logger = NullLoggerFactory.getSafeLogger( loggerFactory, getClass() ); - return this; - } - - void setLogger( LoggerFactory loggerFactory ) - { - // plexus support - setLoggerFactory( loggerFactory ); - } - - public SbtArtifactDescriptorReader setRemoteRepositoryManager( RemoteRepositoryManager remoteRepositoryManager ) - { - if ( remoteRepositoryManager == null ) - { - throw new IllegalArgumentException( "remote repository manager has not been specified" ); - } - this.remoteRepositoryManager = remoteRepositoryManager; - return this; - } - - public SbtArtifactDescriptorReader setVersionResolver( VersionResolver versionResolver ) - { - if ( versionResolver == null ) - { - throw new IllegalArgumentException( "version resolver has not been specified" ); - } - this.versionResolver = versionResolver; - return this; - } - - public SbtArtifactDescriptorReader setArtifactResolver( ArtifactResolver artifactResolver ) - { - if ( artifactResolver == null ) - { - throw new IllegalArgumentException( "artifact resolver has not been specified" ); - } - this.artifactResolver = artifactResolver; - return this; - } - - public SbtArtifactDescriptorReader setRepositoryEventDispatcher( RepositoryEventDispatcher repositoryEventDispatcher ) - { - if ( repositoryEventDispatcher == null ) - { - throw new IllegalArgumentException( "repository event dispatcher has not been specified" ); - } - this.repositoryEventDispatcher = repositoryEventDispatcher; - return this; - } - - public SbtArtifactDescriptorReader setModelBuilder( ModelBuilder modelBuilder ) - { - if ( modelBuilder == null ) - { - throw new IllegalArgumentException( "model builder has not been specified" ); - } - this.modelBuilder = modelBuilder; - return this; - } - - public ArtifactDescriptorResult readArtifactDescriptor( RepositorySystemSession session, - ArtifactDescriptorRequest request ) - throws ArtifactDescriptorException - { - ArtifactDescriptorResult result = new ArtifactDescriptorResult( request ); - - Model model = loadPom( session, request, result ); - - if ( model != null ) - { - - ArtifactTypeRegistry stereotypes = session.getArtifactTypeRegistry(); - - for ( Repository r : model.getRepositories() ) - { - result.addRepository( ArtifactDescriptorUtils.toRemoteRepository( r ) ); - } - - for ( org.apache.maven.model.Dependency dependency : model.getDependencies() ) - { - result.addDependency( convert( dependency, stereotypes ) ); - } - - DependencyManagement mngt = model.getDependencyManagement(); - if ( mngt != null ) - { - for ( org.apache.maven.model.Dependency dependency : mngt.getDependencies() ) - { - result.addManagedDependency( convert( dependency, stereotypes ) ); - } - } - - Map properties = new LinkedHashMap(); - - Prerequisites prerequisites = model.getPrerequisites(); - if ( prerequisites != null ) - { - properties.put( "prerequisites.maven", prerequisites.getMaven() ); - } - - List licenses = model.getLicenses(); - properties.put( SbtExtraProperties.LICENSE_COUNT_KEY, licenses.size() ); - for ( int i = 0; i < licenses.size(); i++ ) - { - License license = licenses.get( i ); - properties.put( SbtExtraProperties.makeLicenseName(i), license.getName() ); - properties.put( SbtExtraProperties.makeLicenseUrl(i), license.getUrl() ); - properties.put( "license." + i + ".comments", license.getComments() ); - properties.put( "license." + i + ".distribution", license.getDistribution() ); - } - - // SBT ADDED - Here we push in the pom packaging type for Ivy expectations. - final String packaging = - (model.getPackaging() == null) ? "jar" : model.getPackaging(); - properties.put(SbtExtraProperties.MAVEN_PACKAGING_KEY, packaging); - // SBT ADDED - Here we inject the sbt/scala version we parse out of the pom. - final Properties mprops = model.getProperties(); - if(mprops.containsKey(SbtExtraProperties.POM_SBT_VERSION)) { - final String sbtVersion = mprops.getProperty(SbtExtraProperties.POM_SBT_VERSION); - properties.put(SbtExtraProperties.SBT_VERSION_KEY, sbtVersion); - } - if(mprops.containsKey(SbtExtraProperties.POM_SCALA_VERSION)) { - properties.put(SbtExtraProperties.SCALA_VERSION_KEY, mprops.getProperty(SbtExtraProperties.POM_SCALA_VERSION)); - } - - // SBT-Added - Here we inject the additional dependency attributes (for transitive plugin resolution). - PomExtraDependencyAttributes.transferDependencyExtraAttributes(model.getProperties(), properties); - - result.setProperties( properties); - - setArtifactProperties( result, model ); - } - - return result; - } - - // SBT FIX - We make sure that artifact properties are copied over here, so we can find sbt-plugin POM files. - public static Artifact toPomArtifact(Artifact artifact) { - Artifact pomArtifact = artifact; - if(artifact.getClassifier().length() > 0 || !"pom".equals(artifact.getExtension())) { - // TODO - only copy over sbt-important properties. - pomArtifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), "pom", artifact.getVersion()).setProperties(artifact.getProperties()); - } - return pomArtifact; - } - - private Model loadPom( RepositorySystemSession session, ArtifactDescriptorRequest request, - ArtifactDescriptorResult result ) - throws ArtifactDescriptorException - { - RequestTrace trace = RequestTrace.newChild( request.getTrace(), request ); - - Set visited = new LinkedHashSet(); - for ( Artifact artifact = request.getArtifact();; ) - { - // SBT FIX - we need to use our own variant here to preserve extra attributes. - // Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact( artifact ); - Artifact pomArtifact = toPomArtifact(artifact); - try - { - VersionRequest versionRequest = - new VersionRequest( artifact, request.getRepositories(), request.getRequestContext() ); - versionRequest.setTrace( trace ); - VersionResult versionResult = versionResolver.resolveVersion( session, versionRequest ); - - artifact = artifact.setVersion( versionResult.getVersion() ); - - versionRequest = - new VersionRequest( pomArtifact, request.getRepositories(), request.getRequestContext() ); - versionRequest.setTrace( trace ); - versionResult = versionResolver.resolveVersion( session, versionRequest ); - - pomArtifact = pomArtifact.setVersion( versionResult.getVersion() ); - } - catch ( VersionResolutionException e ) - { - result.addException( e ); - throw new ArtifactDescriptorException( result ); - } - - if ( !visited.add( artifact.getGroupId() + ':' + artifact.getArtifactId() + ':' + artifact.getBaseVersion() ) ) - { - RepositoryException exception = - new RepositoryException( "Artifact relocations form a cycle: " + visited ); - invalidDescriptor( session, trace, artifact, exception ); - if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 ) - { - return null; - } - result.addException( exception ); - throw new ArtifactDescriptorException( result ); - } - - ArtifactResult resolveResult; - try - { - ArtifactRequest resolveRequest = - new ArtifactRequest( pomArtifact, request.getRepositories(), request.getRequestContext() ); - resolveRequest.setTrace( trace ); - resolveResult = artifactResolver.resolveArtifact( session, resolveRequest ); - pomArtifact = resolveResult.getArtifact(); - result.setRepository( resolveResult.getRepository() ); - } - catch ( ArtifactResolutionException e ) - { - if ( e.getCause() instanceof ArtifactNotFoundException ) - { - missingDescriptor( session, trace, artifact, (Exception) e.getCause() ); - if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_MISSING ) != 0 ) - { - return null; - } - } - result.addException( e ); - throw new ArtifactDescriptorException( result ); - } - - Model model; - try - { - ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest(); - modelRequest.setValidationLevel( ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL ); - modelRequest.setProcessPlugins(false); - modelRequest.setTwoPhaseBuilding(false); - modelRequest.setSystemProperties(toProperties(session.getUserProperties(), - session.getSystemProperties())); - modelRequest.setModelCache(DefaultModelCache.newInstance(session)); - modelRequest.setModelResolver( - new DefaultModelResolver( - session, - trace.newChild(modelRequest), - request.getRequestContext(), - artifactResolver, - versionRangeResolver, - remoteRepositoryManager, - request.getRepositories()) - ); - if ( resolveResult.getRepository() instanceof WorkspaceRepository ) - { - modelRequest.setPomFile( pomArtifact.getFile() ); - } - else - { - modelRequest.setModelSource( new FileModelSource( pomArtifact.getFile() ) ); - } - - model = modelBuilder.build( modelRequest ).getEffectiveModel(); - } - catch ( ModelBuildingException e ) - { - for ( ModelProblem problem : e.getProblems() ) - { - if ( problem.getException() instanceof UnresolvableModelException ) - { - result.addException( problem.getException() ); - throw new ArtifactDescriptorException( result ); - } - } - invalidDescriptor( session, trace, artifact, e ); - if ( ( getPolicy( session, artifact, request ) & ArtifactDescriptorPolicy.IGNORE_INVALID ) != 0 ) - { - return null; - } - result.addException( e ); - throw new ArtifactDescriptorException( result ); - } - - Relocation relocation = getRelocation( model ); - - if ( relocation != null ) - { - result.addRelocation( artifact ); - artifact = - new RelocatedArtifact( artifact, relocation.getGroupId(), relocation.getArtifactId(), - relocation.getVersion() ); - result.setArtifact( artifact ); - } - else - { - return model; - } - } - } - - private Properties toProperties( Map dominant, Map recessive ) - { - Properties props = new Properties(); - if ( recessive != null ) - { - props.putAll( recessive ); - } - if ( dominant != null ) - { - props.putAll( dominant ); - } - return props; - } - - private Relocation getRelocation( Model model ) - { - Relocation relocation = null; - DistributionManagement distMngt = model.getDistributionManagement(); - if ( distMngt != null ) - { - relocation = distMngt.getRelocation(); - } - return relocation; - } - - private void setArtifactProperties( ArtifactDescriptorResult result, Model model ) - { - String downloadUrl = null; - DistributionManagement distMngt = model.getDistributionManagement(); - if ( distMngt != null ) - { - downloadUrl = distMngt.getDownloadUrl(); - } - if ( downloadUrl != null && downloadUrl.length() > 0 ) - { - Artifact artifact = result.getArtifact(); - Map props = new HashMap( artifact.getProperties() ); - props.put( ArtifactProperties.DOWNLOAD_URL, downloadUrl ); - result.setArtifact( artifact.setProperties( props ) ); - } - } - - private Dependency convert( org.apache.maven.model.Dependency dependency, ArtifactTypeRegistry stereotypes ) - { - ArtifactType stereotype = stereotypes.get( dependency.getType() ); - if ( stereotype == null ) - { - stereotype = new DefaultArtifactType( dependency.getType() ); - } - - boolean system = dependency.getSystemPath() != null && dependency.getSystemPath().length() > 0; - - Map props = null; - if ( system ) - { - props = Collections.singletonMap( ArtifactProperties.LOCAL_PATH, dependency.getSystemPath() ); - } - - Artifact artifact = - new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(), dependency.getClassifier(), null, - dependency.getVersion(), props, stereotype ); - - List exclusions = new ArrayList( dependency.getExclusions().size() ); - for ( org.apache.maven.model.Exclusion exclusion : dependency.getExclusions() ) - { - exclusions.add( convert( exclusion ) ); - } - - Dependency result = new Dependency( artifact, dependency.getScope(), dependency.isOptional(), exclusions ); - - return result; - } - - private Exclusion convert( org.apache.maven.model.Exclusion exclusion ) - { - return new Exclusion( exclusion.getGroupId(), exclusion.getArtifactId(), "*", "*" ); - } - - private void missingDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact, - Exception exception ) - { - RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_MISSING ); - event.setTrace( trace ); - event.setArtifact( artifact ); - event.setException( exception ); - - repositoryEventDispatcher.dispatch( event.build() ); - } - - private void invalidDescriptor( RepositorySystemSession session, RequestTrace trace, Artifact artifact, - Exception exception ) - { - RepositoryEvent.Builder event = new RepositoryEvent.Builder( session, EventType.ARTIFACT_DESCRIPTOR_INVALID ); - event.setTrace( trace ); - event.setArtifact( artifact ); - event.setException( exception ); - - repositoryEventDispatcher.dispatch( event.build() ); - } - - private int getPolicy( RepositorySystemSession session, Artifact artifact, ArtifactDescriptorRequest request ) - { - ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy(); - if ( policy == null ) - { - return ArtifactDescriptorPolicy.STRICT; - } - return policy.getPolicy( session, new ArtifactDescriptorPolicyRequest( artifact, request.getRequestContext() ) ); - } - - public void setVersionRangeResolver(final VersionRangeResolver versionRangeResolver) { - this.versionRangeResolver = versionRangeResolver; - } -} \ No newline at end of file diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java deleted file mode 100644 index 5570d4fac..000000000 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtExtraProperties.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.apache.maven.repository.internal; - - - -/** - * Extra properties we dump from Aether into the properties list. - */ -public class SbtExtraProperties { - - public static final String MAVEN_PACKAGING_KEY = "sbt.pom.packaging"; - public static final String SCALA_VERSION_KEY = "sbt.pom.scalaversion"; - public static final String SBT_VERSION_KEY = "sbt.pom.sbtversion"; - - public static final String POM_INFO_KEY_PREFIX = "info."; - public static final String POM_SCALA_VERSION = "scalaVersion"; - public static final String POM_SBT_VERSION = "sbtVersion"; - public static final String POM_API_KEY = "info.apiURL"; - - public static final String LICENSE_COUNT_KEY = "license.count"; - - public static String makeLicenseName(int i) { - return "license." + i + ".name"; - } - public static String makeLicenseUrl(int i) { - return "license." + i + ".url"; - } -} diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala b/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala deleted file mode 100644 index 23fe7630a..000000000 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/SbtRepositoryLayout.scala +++ /dev/null @@ -1,100 +0,0 @@ -package org.apache.maven.repository.internal - -import org.apache.ivy.util.Message -import org.eclipse.aether.spi.connector.layout.{ RepositoryLayout, RepositoryLayoutFactory } -import org.eclipse.aether.RepositorySystemSession -import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.transfer.NoRepositoryLayoutException -import org.eclipse.aether.metadata.Metadata -import org.eclipse.aether.spi.connector.layout.RepositoryLayout.Checksum -import org.eclipse.aether.artifact.Artifact -import java.net.URI - -import scala.util.matching.Regex - -/** A factory which knows how to create repository layouts which can find sbt plugins. */ -class SbtPluginLayoutFactory extends RepositoryLayoutFactory { - def newInstance(session: RepositorySystemSession, repository: RemoteRepository): RepositoryLayout = { - repository.getContentType match { - case SbtRepositoryLayout.LAYOUT_NAME => - SbtRepositoryLayout - case _ => throw new NoRepositoryLayoutException(repository, "Not an sbt-plugin repository") - } - } - def getPriority: Float = 100.0f -} - -object SbtRepositoryLayout extends RepositoryLayout { - - val LAYOUT_NAME = "sbt-plugin" - - // get location is ALMOST the same for Metadata + artifact... but subtle differences are important. - - def getLocation(artifact: Artifact, upload: Boolean): URI = { - import collection.JavaConverters._ - val sbtVersion = Option(artifact.getProperties.get(SbtExtraProperties.POM_SBT_VERSION)) - val scalaVersion = Option(artifact.getProperties.get(SbtExtraProperties.POM_SCALA_VERSION)) - val path = new StringBuilder(128) - path.append(artifact.getGroupId.replace('.', '/')).append('/') - (sbtVersion zip scalaVersion).headOption match { - case Some((sbt, scala)) => - if (artifact.getArtifactId contains "_sbt_") { - // TODO - Write this handler. - val SbtNameVersionSplit(name, sbt2) = artifact.getArtifactId - path.append(name).append('_').append(scala).append('_').append(sbt).append('/') - } else path.append(artifact.getArtifactId).append('_').append(scala).append('_').append(sbt).append('/') - case None => - // TODO - Should we automatically append the _ here if it's not there? Probably not for now. - path.append(artifact.getArtifactId).append('/') - } - path.append(artifact.getBaseVersion).append('/') - sbtVersion match { - case Some(_) if artifact.getArtifactId contains "_sbt_" => - val SbtNameVersionSplit(name, sbt2) = artifact.getArtifactId - path.append(name).append('-').append(artifact.getVersion) - case None => path.append(artifact.getArtifactId).append('-').append(artifact.getVersion) - } - - if (artifact.getClassifier != null && !artifact.getClassifier.trim.isEmpty) { - path.append("-").append(artifact.getClassifier) - } - if (artifact.getExtension.length > 0) { - path.append('.').append(artifact.getExtension) - } - URI.create(path.toString()) - } - - // Trickery for disambiguating sbt plugins in maven repositories. - val SbtNameVersionSplit = new Regex("(.*)_sbt_(.*)") - - def getLocation(metadata: Metadata, upload: Boolean): URI = { - val sbtVersion = Option(metadata.getProperties.get(SbtExtraProperties.POM_SBT_VERSION)) - val scalaVersion = Option(metadata.getProperties.get(SbtExtraProperties.POM_SCALA_VERSION)) - val path = new StringBuilder(128) - path.append(metadata.getGroupId.replace('.', '/')).append('/') - (sbtVersion zip scalaVersion).headOption match { - case Some((sbt, scala)) => - if (metadata.getArtifactId contains "_sbt_") { - val SbtNameVersionSplit(name, sbt2) = metadata.getArtifactId - path.append(name).append('_').append(scala).append('_').append(sbt).append('/') - // TODO - Write this handler. - } else path.append(metadata.getArtifactId).append('_').append(scala).append('_').append(sbt).append('/') - case None => - // TODO - Should we automatically append the _ here? Proabbly not for now. - path.append(metadata.getArtifactId).append('/') - } - if (metadata.getVersion.length > 0) - path.append(metadata.getVersion).append('/') - path.append(metadata.getType) - URI.create(path.toString) - } - - // TODO - This should be the same as configured from Ivy... - def getChecksums(artifact: Artifact, upload: Boolean, location: URI): java.util.List[Checksum] = - getChecksums(location) - def getChecksums(metadata: Metadata, upload: Boolean, location: URI): java.util.List[Checksum] = - getChecksums(location) - - private def getChecksums(location: URI): java.util.List[Checksum] = - java.util.Arrays.asList(Checksum.forLocation(location, "SHA-1"), Checksum.forLocation(location, "MD5")) -} \ No newline at end of file diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 9c7545eb9..26abec09c 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -19,6 +19,8 @@ import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } private[sbt] object ConvertResolver { + import UpdateOptions.ResolverConverter + /** * This class contains all the reflective lookups used in the * checksum-friendly URL publishing shim. @@ -94,37 +96,34 @@ private[sbt] object ConvertResolver { } } - private[sbt] val USE_AETHER_PROPERTY = "sbt.use.aether" - private def isUseAetherForResolution(settings: IvySettings): Boolean = - settings.getVariable(USE_AETHER_PROPERTY) == "true" + /** Converts the given sbt resolver into an Ivy resolver. */ + @deprecated("0.13.8", "Use the variant with updateOptions") + def apply(r: Resolver, settings: IvySettings, log: Logger): DependencyResolver = + apply(r, settings, UpdateOptions(), log) - /** Converts the given sbt resolver into an Ivy resolver..*/ - def apply(r: Resolver, settings: IvySettings, log: Logger) = - { + /** Converts the given sbt resolver into an Ivy resolver. */ + def apply(r: Resolver, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = + (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) + + /** The default implementation of converter. */ + lazy val defaultConvert: ResolverConverter = { + case (r, settings, log) => r match { case repo: MavenRepository => { - if (isUseAetherForResolution(settings)) { - repo match { - case cache: MavenCache => new org.apache.ivy.plugins.resolver.MavenCacheRepositoryResolver(cache, settings) - case _ => new org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver(repo, settings) + val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) + final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + def setPatterns() { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) } - } else { - val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns() { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - } - val resolver = new PluginCapableResolver - resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver } - + val resolver = new PluginCapableResolver + resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } // TODO: HTTP repository is no longer recommended. #1541 // Remove `JavaNet1Repository` when we bump up the API. @@ -176,7 +175,7 @@ private[sbt] object ConvertResolver { case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) case repo: RawRepository => repo.resolver } - } + } private sealed trait DescriptorRequired extends BasicResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index d2d0388ee..be86d1131 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -73,7 +73,6 @@ final class IvySbt(val configuration: IvyConfiguration) { is.setBaseDir(baseDirectory) is.setCircularDependencyStrategy(configuration.updateOptions.circularDependencyLevel.ivyStrategy) CustomPomParser.registerDefault - is.setVariable(ConvertResolver.USE_AETHER_PROPERTY, s"${configuration.updateOptions.aetherResolution}") configuration match { case e: ExternalIvyConfiguration => @@ -289,7 +288,7 @@ private[sbt] object IvySbt { def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = { - def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, log)) + def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, updateOptions, log)) val (projectResolvers, rest) = resolvers.partition(_.name == "inter-project") if (projectResolvers.isEmpty) new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) else { diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 13ca70f1b..fc15a3cd9 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -20,6 +20,7 @@ import org.apache.ivy.Ivy import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } +import ivyint.CustomRemoteMavenResolver class MakePom(val log: Logger) { @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") @@ -333,7 +334,7 @@ class MakePom(val log: Logger) { val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { - case m: org.apache.ivy.plugins.resolver.MavenRemoteRepositoryResolver if m.repo.root != DefaultMavenRepository.root => + case m: CustomRemoteMavenResolver if m.repo.root != DefaultMavenRepository.root => MavenRepository(m.repo.name, m.repo.root) :: Nil case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => MavenRepository(m.getName, m.getRoot) :: Nil diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/ivy/src/main/scala/sbt/UpdateOptions.scala index e13fed72f..3a710026c 100644 --- a/ivy/src/main/scala/sbt/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/UpdateOptions.scala @@ -1,6 +1,8 @@ package sbt import java.io.File +import org.apache.ivy.plugins.resolver.DependencyResolver +import org.apache.ivy.core.settings.IvySettings /** * Represents configurable options for update task. @@ -18,13 +20,8 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, /** If set to true, use cached resolution. */ val cachedResolution: Boolean, - /** If set to true, use aether for resolving maven artifacts. */ - val aetherResolution: Boolean) { - - /** Enables Aether for dependency resolution. */ - def withAetherResolution(aetherResolution: Boolean): UpdateOptions = - copy(aetherResolution = aetherResolution) - + /** Extention point for an alternative resolver converter. */ + val resolverConverter: UpdateOptions.ResolverConverter) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = @@ -36,24 +33,28 @@ final class UpdateOptions private[sbt] ( def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = copy(cachedResolution = cachedResoluton, consolidatedResolution = cachedResolution) + /** Extention point for an alternative resolver converter. */ + def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = + copy(resolverConverter = resolverConverter) private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, - aetherResolution: Boolean = this.aetherResolution): UpdateOptions = + resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter): UpdateOptions = new UpdateOptions(circularDependencyLevel, latestSnapshots, consolidatedResolution, cachedResolution, - aetherResolution) + resolverConverter) override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && this.latestSnapshots == o.latestSnapshots && - this.cachedResolution == o.cachedResolution + this.cachedResolution == o.cachedResolution && + this.resolverConverter == o.resolverConverter case _ => false } @@ -63,17 +64,19 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.circularDependencyLevel.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## + hash = hash * 31 + this.resolverConverter.## hash } } object UpdateOptions { + type ResolverConverter = PartialFunction[(Resolver, IvySettings, Logger), DependencyResolver] + def apply(): UpdateOptions = new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, latestSnapshots = false, consolidatedResolution = false, cachedResolution = false, - // TODO - Disable this before release, but make sure test suite passes with it on. - aetherResolution = true) + resolverConverter = PartialFunction.empty) } diff --git a/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala b/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala new file mode 100644 index 000000000..e3e41148e --- /dev/null +++ b/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala @@ -0,0 +1,11 @@ +package sbt +package ivyint + +import org.apache.ivy.plugins.resolver.DependencyResolver + +// These are placeholder traits for sbt-aether-resolver +trait CustomMavenResolver extends DependencyResolver { +} +trait CustomRemoteMavenResolver extends CustomMavenResolver { + def repo: MavenRepository +} diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 13c2642ec..08c8f00e7 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -184,7 +184,7 @@ private[sbt] case class SbtChainResolver( val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { case None if resolver.getName == "inter-project" => // do nothing - case None if resolver.isInstanceOf[AbstractMavenRepositoryResolver] => + case None if resolver.isInstanceOf[CustomMavenResolver] => // do nothing for now.... // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") From a02fe617927c2661f7e76c10a55c82662a390afd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 10 Jan 2015 22:55:50 -0500 Subject: [PATCH 0386/1030] Adjust tests. --- ivy/src/main/java/sbt/SbtExtraProperties.java | 25 ++ ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- ivy/src/main/scala/sbt/ModuleID.scala | 2 - ivy/src/test/scala/MavenResolutionSpec.scala | 292 ------------------ 4 files changed, 26 insertions(+), 295 deletions(-) create mode 100644 ivy/src/main/java/sbt/SbtExtraProperties.java delete mode 100644 ivy/src/test/scala/MavenResolutionSpec.scala diff --git a/ivy/src/main/java/sbt/SbtExtraProperties.java b/ivy/src/main/java/sbt/SbtExtraProperties.java new file mode 100644 index 000000000..bcc9b8189 --- /dev/null +++ b/ivy/src/main/java/sbt/SbtExtraProperties.java @@ -0,0 +1,25 @@ +package sbt; + +/** + * Extra properties we dump from Aether into the properties list. + */ +public class SbtExtraProperties { + + public static final String MAVEN_PACKAGING_KEY = "sbt.pom.packaging"; + public static final String SCALA_VERSION_KEY = "sbt.pom.scalaversion"; + public static final String SBT_VERSION_KEY = "sbt.pom.sbtversion"; + + public static final String POM_INFO_KEY_PREFIX = "info."; + public static final String POM_SCALA_VERSION = "scalaVersion"; + public static final String POM_SBT_VERSION = "sbtVersion"; + public static final String POM_API_KEY = "info.apiURL"; + + public static final String LICENSE_COUNT_KEY = "license.count"; + + public static String makeLicenseName(int i) { + return "license." + i + ".name"; + } + public static String makeLicenseUrl(int i) { + return "license." + i + ".url"; + } +} diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index d931cefe6..c9e660833 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -13,7 +13,7 @@ import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern -import org.apache.maven.repository.internal.{ SbtExtraProperties, PomExtraDependencyAttributes } +import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes } @deprecated("0.13.8", "We now use an Aether-based pom parser.") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index bf734f5f7..4b244df44 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -5,8 +5,6 @@ package sbt import java.net.URL -import org.apache.maven.repository.internal.SbtExtraProperties - final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = organization + ":" + name + ":" + revision + diff --git a/ivy/src/test/scala/MavenResolutionSpec.scala b/ivy/src/test/scala/MavenResolutionSpec.scala deleted file mode 100644 index 8015e78a8..000000000 --- a/ivy/src/test/scala/MavenResolutionSpec.scala +++ /dev/null @@ -1,292 +0,0 @@ -package sbt - -import java.io.FileInputStream - -import org.apache.maven.repository.internal.PomExtraDependencyAttributes -import org.specs2._ - -class MavenResolutionSpec extends BaseIvySpecification { - def is = args(sequential = true) ^ s2""".stripMargin - - This is a specification to check the maven resolution - - Resolving a maven dependency should - handle sbt plugins $resolveSbtPlugins - use ivy for conflict resolution $resolveMajorConflicts - handle cross configuration deps $resolveCrossConfigurations - publish with maven-metadata $publishMavenMetadata - resolve transitive maven dependencies $resolveTransitiveMavenDependency - resolve intransitive maven dependencies $resolveIntransitiveMavenDependency - handle transitive configuration shifts $resolveTransitiveConfigurationMavenDependency - resolve source and doc $resolveSourceAndJavadoc - resolve nonstandard (jdk5) classifier $resolveNonstandardClassifier - Resolve pom artifact dependencies $resolvePomArtifactAndDependencies - Fail if JAR artifact is not found w/ POM $failIfMainArtifactMissing - Fail if POM.xml is not found $failIfPomMissing - resolve publication date for -SNAPSHOT $resolveSnapshotPubDate - - """ // */ - - // TODO - test latest.integration and .+ - - def akkaActor = ModuleID("com.typesafe.akka", "akka-actor_2.11", "2.3.8", Some("compile")) - def akkaActorTestkit = ModuleID("com.typesafe.akka", "akka-testkit_2.11", "2.3.8", Some("test")) - def testngJdk5 = ModuleID("org.testng", "testng", "5.7", Some("compile")).classifier("jdk15") - def jmxri = ModuleID("com.sun.jmx", "jmxri", "1.2.1", Some("compile")) - def scalaLibraryAll = ModuleID("org.scala-lang", "scala-library-all", "2.11.4", Some("compile")) - def scalaCompiler = ModuleID("org.scala-lang", "scala-compiler", "2.8.1", Some("scala-tool->default(compile)")) - def scalaContinuationPlugin = ModuleID("org.scala-lang.plugins", "continuations", "2.8.1", Some("plugin->default(compile)")) - def sbtPlugin = - ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). - extra(PomExtraDependencyAttributes.SbtVersionKey -> "0.13", PomExtraDependencyAttributes.ScalaVersionKey -> "2.10"). - copy(crossVersion = CrossVersion.Disabled) - def oldSbtPlugin = - ModuleID("com.github.mpeltonen", "sbt-idea", "1.6.0", Some("compile")). - extra(PomExtraDependencyAttributes.SbtVersionKey -> "0.12", PomExtraDependencyAttributes.ScalaVersionKey -> "2.9.2"). - copy(crossVersion = CrossVersion.Disabled) - def majorConflictLib = ModuleID("com.joestelmach", "natty", "0.3", Some("compile")) - // TODO - This snapshot and resolver should be something we own/control so it doesn't disappear on us. - def testSnapshot = ModuleID("com.typesafe", "config", "0.4.9-SNAPSHOT", Some("compile")) - val SnapshotResolver = MavenRepository("some-snapshots", "https://oss.sonatype.org/content/repositories/snapshots/") - - override def resolvers = Seq(DefaultMavenRepository, SnapshotResolver, Resolver.publishMavenLocal) - import Configurations.{ Compile, Test, Runtime, CompilerPlugin, ScalaTool } - override def configurations = Seq(Compile, Test, Runtime, CompilerPlugin, ScalaTool) - - import ShowLines._ - - def defaultUpdateOptions = UpdateOptions().withAetherResolution(true) - - def resolveMajorConflicts = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), - Seq(majorConflictLib), None, defaultUpdateOptions) - val report = ivyUpdate(m) // must not(throwAn[IllegalStateException]) - val jars = - for { - conf <- report.configurations - if conf.configuration == Compile.name - m <- conf.modules - if (m.module.name contains "stringtemplate") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - jars must haveSize(1) - } - - def resolveCrossConfigurations = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), - Seq(scalaCompiler, scalaContinuationPlugin), None, defaultUpdateOptions) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - if conf.configuration == ScalaTool.name - m <- conf.modules - if (m.module.name contains "scala-compiler") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - jars must haveSize(1) - } - - def resolveSbtPlugins = { - - def sha(f: java.io.File): String = sbt.Hash.toHex(sbt.Hash(f)) - def findSbtIdeaJars(dep: ModuleID, name: String) = { - val m = module(ModuleID("com.example", name, "0.1.0", Some("compile")), Seq(dep), None, defaultUpdateOptions) - val report = ivyUpdate(m) - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if (m.module.name contains "sbt-idea") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield (f, sha(f)) - } - - val oldJars = findSbtIdeaJars(oldSbtPlugin, "old") - System.err.println(s"${oldJars.mkString("\n")}") - val newJars = findSbtIdeaJars(sbtPlugin, "new") - System.err.println(s"${newJars.mkString("\n")}") - (newJars must haveSize(1)) and (oldJars must haveSize(1)) and (oldJars.map(_._2) must not(containTheSameElementsAs(newJars.map(_._2)))) - } - - def resolveSnapshotPubDate = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(testSnapshot), Some("2.10.2"), defaultUpdateOptions.withLatestSnapshots(true)) - val report = ivyUpdate(m) - val pubTime = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if m.module.revision endsWith "-SNAPSHOT" - date <- m.publicationDate - } yield date - (pubTime must haveSize(1)) - } - - def resolvePomArtifactAndDependencies = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(scalaLibraryAll), Some("2.10.2"), defaultUpdateOptions) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if (m.module.name == "scala-library") || (m.module.name contains "parser") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - jars must haveSize(2) - } - - def failIfPomMissing = { - // TODO - we need the jar to not exist too. - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(ModuleID("org.scala-sbt", "does-not-exist", "1.0", Some("compile"))), Some("2.10.2"), defaultUpdateOptions) - ivyUpdate(m) must throwAn[Exception] - } - - def failIfMainArtifactMissing = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(jmxri), Some("2.10.2"), defaultUpdateOptions) - ivyUpdate(m) must throwAn[Exception] - } - - def resolveNonstandardClassifier = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(testngJdk5), Some("2.10.2"), defaultUpdateOptions) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if m.module.name == "testng" - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - (report.configurations must haveSize(configurations.size)) and - (jars must haveSize(1)) - (jars.forall(_.exists) must beTrue) - - } - - def resolveTransitiveMavenDependency = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActor), Some("2.10.2"), defaultUpdateOptions) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if m.module.name == "scala-library" - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - (report.configurations must haveSize(configurations.size)) and - (jars must not(beEmpty)) and - (jars.forall(_.exists) must beTrue) - - } - - def resolveIntransitiveMavenDependency = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActorTestkit.intransitive()), Some("2.10.2"), defaultUpdateOptions) - val report = ivyUpdate(m) - val transitiveJars = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if (m.module.name contains "akka-actor") && !(m.module.name contains "testkit") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - val directJars = - for { - conf <- report.configurations - if conf.configuration == "compile" - m <- conf.modules - if (m.module.name contains "akka-actor") && (m.module.name contains "testkit") - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - (report.configurations must haveSize(configurations.size)) and - (transitiveJars must beEmpty) and (directJars.forall(_.exists) must beTrue) - } - - def resolveTransitiveConfigurationMavenDependency = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(akkaActorTestkit), Some("2.10.2"), defaultUpdateOptions) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - if conf.configuration == "test" - m <- conf.modules - if m.module.name contains "akka-actor" - (a, f) <- m.artifacts - if a.extension == "jar" - } yield f - (report.configurations must haveSize(configurations.size)) and - (jars must not(beEmpty)) and - (jars.forall(_.exists) must beTrue) - - } - - def resolveSourceAndJavadoc = { - val m = module( - ModuleID("com.example", "foo", "0.1.0", Some("sources")), - Seq(akkaActor.artifacts(Artifact(akkaActor.name, "javadoc"), Artifact(akkaActor.name, "sources"))), - Some("2.10.2"), - defaultUpdateOptions - ) - val report = ivyUpdate(m) - val jars = - for { - conf <- report.configurations - // We actually injected javadoc/sources into the compile scope, due to how we did the request. - // SO, we report that here. - if conf.configuration == "compile" - m <- conf.modules - (a, f) <- m.artifacts - if (f.getName contains "sources") || (f.getName contains "javadoc") - } yield f - (report.configurations must haveSize(configurations.size)) and - (jars must haveSize(2)) - } - - def publishMavenMetadata = { - val m = module( - ModuleID("com.example", "test-it", "1.0-SNAPSHOT", Some("compile")), - Seq(), - None, - defaultUpdateOptions.withLatestSnapshots(true) - ) - sbt.IO.withTemporaryDirectory { dir => - val pomFile = new java.io.File(dir, "pom.xml") - sbt.IO.write(pomFile, - """ - | - | com.example - | test-it - | 1.0-SNAPSHOT - | - """.stripMargin) - val jarFile = new java.io.File(dir, "test-it-1.0-SNAPSHOT.jar") - sbt.IO.touch(jarFile) - System.err.println(s"DEBUGME - Publishing $m to ${Resolver.publishMavenLocal}") - ivyPublish(m, mkPublishConfiguration( - Resolver.publishMavenLocal, - Map( - Artifact("test-it-1.0-SNAPSHOT.jar") -> pomFile, - Artifact("test-it-1.0-SNAPSHOT.pom", "pom", "pom") -> jarFile - ))) - } - val baseLocalMavenDir: java.io.File = Resolver.publishMavenLocal.rootFile - val allFiles: Seq[java.io.File] = sbt.PathFinder(new java.io.File(baseLocalMavenDir, "com/example/test-it")).***.get - val metadataFiles = allFiles.filter(_.getName contains "maven-metadata-local") - // TODO - maybe we check INSIDE the metadata, or make sure we can get a publication date on resolve... - // We end up with 4 files, two mavne-metadata files, and 2 maven-metadata-local files. - metadataFiles must haveSize(2) - } - -} - From a0f6662500023cb0556ce81d1f8e43536eccfe83 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 12 Jan 2015 14:48:23 -0500 Subject: [PATCH 0387/1030] Refactoring code. * remove debugging statements * Move each class so it's one name-per-file * Migrate out of org.apache namespace into sbt.mavenint --- .../SbtPomExtraProperties.java} | 4 ++-- ivy/src/main/scala/sbt/CustomPomParser.scala | 7 +++---- ivy/src/main/scala/sbt/MakePom.scala | 2 +- ivy/src/main/scala/sbt/ModuleID.scala | 4 +++- .../mavenint}/PomExtraDependencyAttributes.scala | 8 ++++---- 5 files changed, 13 insertions(+), 12 deletions(-) rename ivy/src/main/java/sbt/{SbtExtraProperties.java => mavenint/SbtPomExtraProperties.java} (93%) rename ivy/src/main/scala/{org/apache/maven/repository/internal => sbt/mavenint}/PomExtraDependencyAttributes.scala (96%) diff --git a/ivy/src/main/java/sbt/SbtExtraProperties.java b/ivy/src/main/java/sbt/mavenint/SbtPomExtraProperties.java similarity index 93% rename from ivy/src/main/java/sbt/SbtExtraProperties.java rename to ivy/src/main/java/sbt/mavenint/SbtPomExtraProperties.java index bcc9b8189..fde6af15b 100644 --- a/ivy/src/main/java/sbt/SbtExtraProperties.java +++ b/ivy/src/main/java/sbt/mavenint/SbtPomExtraProperties.java @@ -1,9 +1,9 @@ -package sbt; +package sbt.mavenint; /** * Extra properties we dump from Aether into the properties list. */ -public class SbtExtraProperties { +public class SbtPomExtraProperties { public static final String MAVEN_PACKAGING_KEY = "sbt.pom.packaging"; public static final String SCALA_VERSION_KEY = "sbt.pom.scalaversion"; diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index c9e660833..d9ceff32a 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -12,8 +12,7 @@ import org.apache.ivy.util.extendable.ExtendableItem import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern - -import org.apache.maven.repository.internal.{ PomExtraDependencyAttributes } +import sbt.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } @deprecated("0.13.8", "We now use an Aether-based pom parser.") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { @@ -36,8 +35,8 @@ object CustomPomParser { ReplaceMavenConfigurationMappings.init() /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ - val InfoKeyPrefix = SbtExtraProperties.POM_INFO_KEY_PREFIX - val ApiURLKey = SbtExtraProperties.POM_API_KEY + val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX + val ApiURLKey = SbtPomExtraProperties.POM_API_KEY val SbtVersionKey = PomExtraDependencyAttributes.SbtVersionKey val ScalaVersionKey = PomExtraDependencyAttributes.ScalaVersionKey diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index fc15a3cd9..2cb7331e6 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -9,7 +9,7 @@ package sbt import java.io.File -import org.apache.maven.repository.internal.PomExtraDependencyAttributes +import sbt.mavenint.PomExtraDependencyAttributes // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index 4b244df44..c0e8670d5 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -5,6 +5,8 @@ package sbt import java.net.URL +import sbt.mavenint.SbtPomExtraProperties + final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = organization + ":" + name + ":" + revision + @@ -15,7 +17,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ - def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtExtraProperties.POM_INFO_KEY_PREFIX)) + def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)) @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else CrossVersion.Disabled) diff --git a/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala similarity index 96% rename from ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala rename to ivy/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala index 4c2ead5d1..ab87cae75 100644 --- a/ivy/src/main/scala/org/apache/maven/repository/internal/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala @@ -1,4 +1,4 @@ -package org.apache.maven.repository.internal +package sbt.mavenint import java.util.Properties import java.util.regex.Pattern @@ -31,7 +31,7 @@ object PomExtraDependencyAttributes { * A map of module id to extra dependency attributes associated with dependencies on that module. */ def readFromAether(props: java.util.Map[String, AnyRef]): Map[ModuleRevisionId, Map[String, String]] = { - import collection.JavaConverters._ + import scala.collection.JavaConverters._ (props.asScala get ExtraAttributesKey) match { case None => Map.empty case Some(str) => @@ -71,7 +71,7 @@ object PomExtraDependencyAttributes { } def qualifiedExtra(item: ExtendableItem): Map[String, String] = { - import collection.JavaConverters._ + import scala.collection.JavaConverters._ item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = @@ -83,7 +83,7 @@ object PomExtraDependencyAttributes { // This makes the id suitable as a key to associate a dependency parsed from a element // with the extra attributes from the section def simplify(id: ModuleRevisionId): ModuleRevisionId = { - import collection.JavaConverters._ + import scala.collection.JavaConverters._ ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include = false).asJava) } From c967653442e4def25fdcd89477131ed83927bd91 Mon Sep 17 00:00:00 2001 From: Indrajit Raychaudhuri Date: Sat, 17 Jan 2015 08:25:57 +0530 Subject: [PATCH 0388/1030] Fix params order in `@deprecated` --- ivy/src/main/scala/sbt/ConvertResolver.scala | 2 +- ivy/src/main/scala/sbt/CustomPomParser.scala | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 26abec09c..3771266aa 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -97,7 +97,7 @@ private[sbt] object ConvertResolver { } /** Converts the given sbt resolver into an Ivy resolver. */ - @deprecated("0.13.8", "Use the variant with updateOptions") + @deprecated("Use the variant with updateOptions", "0.13.8") def apply(r: Resolver, settings: IvySettings, log: Logger): DependencyResolver = apply(r, settings, UpdateOptions(), log) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index d9ceff32a..7b5664daf 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -14,7 +14,7 @@ import java.net.URL import java.util.regex.Pattern import sbt.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } -@deprecated("0.13.8", "We now use an Aether-based pom parser.") +@deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) @@ -28,7 +28,7 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module override def getType() = delegate.getType() override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) } -@deprecated("0.13.8", "We now use an Aether-based pom parser.") +@deprecated("We now use an Aether-based pom parser.", "0.13.8") object CustomPomParser { // Evil hackery to override the default maven pom mappings. @@ -65,7 +65,7 @@ object CustomPomParser { { val oldTransformedHashKey = "sbtTransformHash" val extraInfo = md.getExtraInfo - // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both + // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { case Some(TransformHash) => true @@ -205,4 +205,4 @@ object CustomPomParser { } dmd } -} \ No newline at end of file +} From 78881eefb3e6b55d388bbcc459425ed6a24c252f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 13 Feb 2015 16:59:20 -0500 Subject: [PATCH 0389/1030] Adds an hook treating InlineConfigurationWithExcludes structurally --- ivy/src/main/scala/sbt/IvyConfigurations.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/ivy/src/main/scala/sbt/IvyConfigurations.scala index 3c695f71a..ed8df9546 100644 --- a/ivy/src/main/scala/sbt/IvyConfigurations.scala +++ b/ivy/src/main/scala/sbt/IvyConfigurations.scala @@ -121,6 +121,8 @@ final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, d def withExcludes: InlineConfigurationWithExcludes = InlineConfigurationWithExcludes(this.module, this.moduleInfo, this.dependencies, this.overrides, Nil, this.ivyXML, this.configurations, this.defaultConfiguration, this.ivyScala, this.validate, this.conflictManager) + def withOverrides(overrides: Set[ModuleID]): ModuleSettings = + copy(overrides = overrides) } object InlineConfiguration { @deprecated("Use InlineConfigurationWithExcludes.explicitConfigurations.", "0.13.8") @@ -148,6 +150,8 @@ final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, val conflictManager: ConflictManager) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) + def withOverrides(overrides: Set[ModuleID]): ModuleSettings = + copy(overrides = overrides) private[sbt] def copy(module: ModuleID = this.module, moduleInfo: ModuleInfo = this.moduleInfo, From 23e20f72ba7f20fded26cd85e8bdb0765371cfe2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 23 Feb 2015 03:17:56 -0500 Subject: [PATCH 0390/1030] Fixes #1711, #1730. Cached resolution: fixes internal project Re-fixes cached resolution's internal dependency issue by recursively calling customResolve instead of including the transitive dependencies from internal dependencies into your own graph. Transformation of configuration still happens, but at the level of resolved graph (UpdateReport), which is much less granular, and hopefully less error-prone. --- .../CachedResolutionResolveEngine.scala | 166 ++++++++---------- 1 file changed, 73 insertions(+), 93 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 8915a192d..963c6a421 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -17,6 +17,7 @@ import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } +import Configurations.{ Compile, Test, Runtime, IntegrationTest } private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -37,104 +38,25 @@ private[sbt] class CachedResolutionResolveCache() { } def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector - def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[(DefaultModuleDescriptor, Boolean)] = + // Returns a vector of (module descriptor, changing, dd) + def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[(DefaultModuleDescriptor, Boolean, DependencyDescriptor)] = { log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") - val expanded = expandInternalDependencies(md0, data, prOpt, log) + // val expanded = expandInternalDependencies(md0, data, prOpt, log) val rootModuleConfigs = md0.getConfigurations.toArray.toVector - expanded map { dd => + directDependencies(md0) map { dd => val arts = dd.getAllDependencyArtifacts.toVector map { x => s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } - log.debug(s"::: expanded dd: $dd (artifacts: ${arts.mkString(",")})") + log.debug(s"::: dd: $dd (artifacts: ${arts.mkString(",")})") buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log) } } - // This expands out all internal dependencies and merge them into a single graph that consists - // only of external dependencies. - // The tricky part is the merger of configurations, even though in most cases we will only see compile->compile when it comes to internal deps. - // Theoretically, there could be a potential for test->test->runtime kind of situation. nextConfMap and remapConfigurations track - // the configuration chains transitively. - def expandInternalDependencies(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[DependencyDescriptor] = - { - log.debug(s"::: expanding internal dependencies of module descriptor ${md0.getModuleRevisionId}") - val rootModuleConfigs = md0.getConfigurations.toArray.toVector - val rootNode = new IvyNode(data, md0) - def expandInternalDeps(dep: DependencyDescriptor, confMap: Map[String, Array[String]]): Vector[DependencyDescriptor] = - internalDependency(dep) match { - case Some(internal) => - log.debug(s""":::: found internal dependency ${internal.getResolvedModuleRevisionId}""") - val allConfigurations: Vector[String] = confMap.values.flatten.toVector.distinct - val next = nextConfMap(dep, confMap) - // direct dependencies of an internal dependency - val directs0 = directDependencies(internal) - val directs = directs0 filter { dd => - allConfigurations exists { conf => dd.getDependencyConfigurations(conf).nonEmpty } - } - directs flatMap { dd => expandInternalDeps(dd, next) } - case _ => - Vector(remapConfigurations(dep, confMap, log)) - } - def internalDependency(dep: DependencyDescriptor): Option[ModuleDescriptor] = - prOpt match { - case Some(pr) => pr.getModuleDescriptor(dep.getDependencyRevisionId) - case _ => None - } - // This creates confMap. The key of the map is rootModuleConf for md0, the value is the dependency configs for dd. - def nextConfMap(dd: DependencyDescriptor, previous: Map[String, Array[String]]): Map[String, Array[String]] = - previous map { - case (rootModuleConf, vs) => - rootModuleConf -> (vs flatMap { conf => - dd.getDependencyConfigurations(conf) flatMap { confName => - if (confName == "*") Array(confName) - else rootNode.getRealConfs(confName) - } - }) - } - // The key of the confMap is rootModuleConf for md0, and the values are modules configuratons of dd0. - // For example if project Root depends on project B % "test", and project B depends on junit, - // confMap should contain Map("test", Array("compile")). - // This remaps junit dependency as junit % "test". - def remapConfigurations(dd0: DependencyDescriptor, confMap: Map[String, Array[String]], log: Logger): DependencyDescriptor = - { - log.debug(s""":::: remapping configuration of ${dd0} with ${confMap.toList map { case (k, v) => (k, v.toList) }}""") - val dd = new DefaultDependencyDescriptor(md0, dd0.getDependencyRevisionId, dd0.getDynamicConstraintDependencyRevisionId, - dd0.isForce, dd0.isChanging, dd0.isTransitive) - val moduleConfigurations = dd0.getModuleConfigurations.toVector - for { - moduleConf <- moduleConfigurations - (rootModuleConf, vs) <- confMap.toSeq - } if (vs contains moduleConf) { - log.debug(s""":::: ${dd0}: $moduleConf maps to $rootModuleConf""") - dd0.getDependencyConfigurations(moduleConf) foreach { conf => - dd.addDependencyConfiguration(rootModuleConf, conf) - } - dd0.getIncludeRules(moduleConf) foreach { rule => - dd.addIncludeRule(rootModuleConf, rule) - } - dd0.getExcludeRules(moduleConf) foreach { rule => - dd.addExcludeRule(rootModuleConf, rule) - } - dd0.getAllDependencyArtifacts foreach { dad0 => - (Option(dad0.getConfigurations) map { confs => confs.isEmpty || confs.contains(moduleConf) || confs.contains("*") }) match { - case Some(false) => // do nothing - case _ => - val dad = new DefaultDependencyArtifactDescriptor(dd, dad0.getName, dad0.getType, dad0.getExt, dad0.getUrl, dad0.getExtraAttributes) - dad.addConfiguration(rootModuleConf) - dd.addDependencyArtifact(rootModuleConf, dad) - } - } - } - log.debug(s""":::: remapped dd: $dd""") - dd - } - directDependencies(md0) flatMap { dep => - val initialMap = Map(dep.getModuleConfigurations map { rootModuleConf => - (rootModuleConf -> Array(rootModuleConf)) - }: _*) - expandInternalDeps(dep, initialMap) - } + def internalDependency(dd: DependencyDescriptor, prOpt: Option[ProjectResolver]): Option[ModuleDescriptor] = + prOpt match { + case Some(pr) => pr.getModuleDescriptor(dd.getDependencyRevisionId) + case _ => None } def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], - parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean) = + parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean, DependencyDescriptor) = { def excludeRuleString(rule: ExcludeRule): String = s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" @@ -179,7 +101,7 @@ private[sbt] class CachedResolutionResolveCache() { mes foreach { exclude => md1.addExcludeRule(exclude) } - (md1, IvySbt.isChanging(dd)) + (md1, IvySbt.isChanging(dd) || internalDependency(dd, prOpt).isDefined, dd) } def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { @@ -332,7 +254,20 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val options1 = new ResolveOptions(options0) val data = new ResolveData(this, options1) val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) - def doWork(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = + + def doWork(md: ModuleDescriptor, dd: DependencyDescriptor): Either[ResolveException, UpdateReport] = + cache.internalDependency(dd, projectResolver) match { + case Some(md1) => + log.debug(s":: call customResolve recursively: $dd") + customResolve(md1, missingOk, logicalClock, options0, depDir, log) match { + case Right(ur) => Right(remapInternalProject(new IvyNode(data, md1), ur, md0, dd, os, log)) + case Left(e) => Left(e) + } + case None => + log.debug(s":: call ivy resolution: $dd") + doWorkUsingIvy(md) + } + def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) var rr = withIvy(log) { ivy => @@ -354,9 +289,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } } val results = mds map { - case (md, changing) => + case (md, changing, dd) => cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { - doWork(md) + doWork(md, dd) } } val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) @@ -386,6 +321,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], resolveTime: Long, os: Vector[IvyOverride], log: Logger): UpdateReport = { + log.debug(s":: merging update reports") val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val rootModuleConfigs = md0.getConfigurations.toVector val cachedReports = reports filter { !_.stats.cached } @@ -415,6 +351,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector flatMap { case ((org, name), xs) => + log.debug(s""":::: $rootModuleConf: $org:$name""") if (xs.size < 2) xs else Vector(new OrganizationArtifactReport(org, name, mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log))) } @@ -511,6 +448,49 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { (surviving, evicted) } } + // Some of the configurations contain extends, so you can't simply call config. + def lookupConfig(name: String): Configuration = + name match { + case "compile" => Compile + case "test" => Test + case "runtime" => Runtime + case "it" => IntegrationTest + case x => Configurations.config(x) + } + def remapInternalProject(node: IvyNode, ur: UpdateReport, + md0: ModuleDescriptor, dd: DependencyDescriptor, + os: Vector[IvyOverride], log: Logger): UpdateReport = + { + // These are the configurations from the original project we want to resolve. + val rootModuleConfs = md0.getConfigurations.toArray.toVector + val configurations0 = ur.configurations.toVector + // This is how md looks from md0 via dd's mapping. + val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => + val remapped: Vector[String] = dd.getDependencyConfigurations(conf0.getName).toVector flatMap { conf => + node.getRealConfs(conf).toVector + } + conf0.getName -> remapped + }: _*) + // This emulates test-internal extending test configuration etc. + val remappedConfigs: Map[String, Vector[String]] = + (remappedConfigs0 /: rootModuleConfs) { (acc, c) => + val config = lookupConfig(c.getName) + val internal = Configurations.internalMap(config) + if (config != internal) { + val vs0 = acc.getOrElse(internal.name, Vector()) + val vs = acc.getOrElse(config.name, Vector()) + acc.updated(internal.name, (vs0 ++ vs).distinct) + } else acc + } + log.debug(s"::: remapped configs $remappedConfigs") + val configurations = rootModuleConfs map { conf0 => + val remappedCRs = configurations0 filter { cr => + remappedConfigs(conf0.getName) contains cr.configuration + } + mergeConfigurationReports(conf0.getName, remappedCRs, os, log) + } + new UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) + } } private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) extends IvyArtifactInfo { From b4e6d6d77bdae8bac43e1790f87687d8ea50e43f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 23 Feb 2015 04:16:36 -0500 Subject: [PATCH 0391/1030] Generalize the logic to all config inheritance --- .../CachedResolutionResolveEngine.scala | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 963c6a421..76b32e875 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -17,7 +17,7 @@ import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } -import Configurations.{ Compile, Test, Runtime, IntegrationTest } +import Configurations.{ System => _, _ } private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -448,19 +448,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { (surviving, evicted) } } - // Some of the configurations contain extends, so you can't simply call config. - def lookupConfig(name: String): Configuration = - name match { - case "compile" => Compile - case "test" => Test - case "runtime" => Runtime - case "it" => IntegrationTest - case x => Configurations.config(x) - } def remapInternalProject(node: IvyNode, ur: UpdateReport, md0: ModuleDescriptor, dd: DependencyDescriptor, os: Vector[IvyOverride], log: Logger): UpdateReport = { + def parentConfigs(c: String): Vector[String] = + Option(md0.getConfiguration(c)) match { + case Some(config) => + config.getExtends.toVector ++ + (config.getExtends.toVector flatMap parentConfigs) + case None => Vector() + } // These are the configurations from the original project we want to resolve. val rootModuleConfs = md0.getConfigurations.toArray.toVector val configurations0 = ur.configurations.toVector @@ -473,14 +471,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }: _*) // This emulates test-internal extending test configuration etc. val remappedConfigs: Map[String, Vector[String]] = - (remappedConfigs0 /: rootModuleConfs) { (acc, c) => - val config = lookupConfig(c.getName) - val internal = Configurations.internalMap(config) - if (config != internal) { - val vs0 = acc.getOrElse(internal.name, Vector()) - val vs = acc.getOrElse(config.name, Vector()) - acc.updated(internal.name, (vs0 ++ vs).distinct) - } else acc + (remappedConfigs0 /: rootModuleConfs) { (acc0, c) => + val ps = parentConfigs(c.getName) + (acc0 /: ps) { (acc, parent) => + val vs0 = acc.getOrElse(c.getName, Vector()) + val vs = acc.getOrElse(parent, Vector()) + acc.updated(c.getName, (vs0 ++ vs).distinct) + } } log.debug(s"::: remapped configs $remappedConfigs") val configurations = rootModuleConfs map { conf0 => From 38a8215ffa329f1a2c0080bb7ba3aec2fe2de4b6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Mar 2015 14:57:56 -0500 Subject: [PATCH 0392/1030] Transitively evict modules when callers are evicted. Fixes #1760 --- .../CachedResolutionResolveEngine.scala | 62 ++++++++++++++++--- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 76b32e875..202af05b0 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -18,6 +18,7 @@ import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } import Configurations.{ System => _, _ } +import annotation.tailrec private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -348,14 +349,59 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } map { _.module } new ConfigurationReport(rootModuleConf, modules, details, evicted) } + /** + * Returns a touple of (merged org + name combo, newly evicted modules) + */ def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = - (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector flatMap { - case ((org, name), xs) => - log.debug(s""":::: $rootModuleConf: $org:$name""") - if (xs.size < 2) xs - else Vector(new OrganizationArtifactReport(org, name, mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log))) + { + val pairs = (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector map { + case ((org, name), xs) => + log.debug(s""":::: $rootModuleConf: $org:$name""") + if (xs.size < 2) (xs.head, Vector()) + else + mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log) match { + case (survivor, newlyEvicted) => + (new OrganizationArtifactReport(org, name, survivor ++ newlyEvicted), newlyEvicted) + } + } + transitivelyEvict(rootModuleConf, pairs map { _._1 }, pairs flatMap { _._2 }, log) } - def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): Vector[ModuleReport] = + /** + * This transitively evicts any non-evicted modules whose only callers are newly evicted. + */ + @tailrec + private final def transitivelyEvict(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], + evicted0: Vector[ModuleReport], log: Logger): Vector[OrganizationArtifactReport] = + { + val em = evicted0 map { _.module } + def isTransitivelyEvicted(mr: ModuleReport): Boolean = + mr.callers forall { c => em contains { c.caller } } + // Ordering of the OrganizationArtifactReport matters + val pairs: Vector[(OrganizationArtifactReport, Vector[ModuleReport])] = reports0 map { oar => + val organization = oar.organization + val name = oar.name + val (affected, unaffected) = oar.modules.toVector partition { mr => + val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) + if (x) { + log.debug(s""":::: transitively evicted $rootModuleConf: $organization:$name""") + } + x + } + val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) } + if (affected.isEmpty) (oar, Vector()) + else + (new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted), newlyEvicted) + } + val reports = pairs map { _._1 } + val evicted = pairs flatMap { _._2 } + if (evicted.isEmpty) reports + else transitivelyEvict(rootModuleConf, reports, evicted, log) + } + /** + * Merges ModuleReports, which represents orgnization, name, and version. + * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). + */ + def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } @@ -370,10 +416,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { else Vector(mergeModuleReports(org, name, version, xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } - if (conflicts.size < 2) merged + if (conflicts.size < 2) (merged, Vector()) else resolveConflict(rootModuleConf, conflicts, os, log) match { case (survivor, evicted) => - survivor ++ evicted ++ (merged filter { m => m.evicted || m.problem.isDefined }) + (survivor ++ (merged filter { m => m.evicted || m.problem.isDefined }), evicted) } } /** From 77898b67bc123fe30c57d5139b19a02d1d2c3372 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 4 Mar 2015 07:45:00 +0000 Subject: [PATCH 0393/1030] Exempt scala-actors-migration from version checks. Fixes #1818. --- ivy/src/main/scala/sbt/IvyScala.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index b4299906f..061eddeb7 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -66,7 +66,11 @@ private object IvyScala { { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) - val mismatched = id.getOrganisation == Organization && depBinaryVersion != scalaBinaryVersion && dep.getModuleConfigurations.exists(configSet) + def isScalaLangOrg = id.getOrganisation == Organization + def isNotScalaActorsMigration = !(id.getName startsWith "scala-actors-migration") // Exception to the rule: sbt/sbt#1818 + def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion + def matchesOneOfTheConfigs = dep.getModuleConfigurations.exists(configSet) + val mismatched = isScalaLangOrg && isNotScalaActorsMigration && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some("Binary version (" + depBinaryVersion + ") for dependency " + id + "\n\tin " + module.getModuleRevisionId + @@ -111,4 +115,4 @@ private object IvyScala { configurationNames.foreach(rule.addConfiguration) rule } -} \ No newline at end of file +} From 597bcc489df2052b756bf2c4d36bcd63815f98ab Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 5 Mar 2015 17:27:23 -0500 Subject: [PATCH 0394/1030] Fixes typo --- .../main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 202af05b0..56a84fc8b 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -350,7 +350,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { new ConfigurationReport(rootModuleConf, modules, details, evicted) } /** - * Returns a touple of (merged org + name combo, newly evicted modules) + * Returns a tuple of (merged org + name combo, newly evicted modules) */ def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = { From ececf95919bac9a9dc754538d4374519dde5d24d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 6 Mar 2015 22:29:04 +0000 Subject: [PATCH 0395/1030] Exempt scala-pickling as well. --- ivy/src/main/scala/sbt/IvyScala.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index 061eddeb7..d2697e308 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -68,9 +68,10 @@ private object IvyScala { val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) def isScalaLangOrg = id.getOrganisation == Organization def isNotScalaActorsMigration = !(id.getName startsWith "scala-actors-migration") // Exception to the rule: sbt/sbt#1818 + def isNotScalaPickling = !(id.getName startsWith "scala-pickling") // Exception to the rule: sbt/sbt#1899 def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion def matchesOneOfTheConfigs = dep.getModuleConfigurations.exists(configSet) - val mismatched = isScalaLangOrg && isNotScalaActorsMigration && hasBinVerMismatch && matchesOneOfTheConfigs + val mismatched = isScalaLangOrg && isNotScalaActorsMigration && isNotScalaPickling && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some("Binary version (" + depBinaryVersion + ") for dependency " + id + "\n\tin " + module.getModuleRevisionId + From 1a65c774c308954cb9c914728b3b3d1e8118e41d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 4 Mar 2015 04:31:31 -0500 Subject: [PATCH 0396/1030] Implement pickler for UpdateReport. #1763 --- ivy/src/main/scala/sbt/Artifact.scala | 70 +++++++++ ivy/src/main/scala/sbt/Configuration.scala | 5 + ivy/src/main/scala/sbt/CrossVersion.scala | 37 +++++ ivy/src/main/scala/sbt/DatePicklers.scala | 35 +++++ ivy/src/main/scala/sbt/FileMapPicklers.scala | 22 +++ ivy/src/main/scala/sbt/IvyInterface.scala | 4 + ivy/src/main/scala/sbt/JsonUtil.scala | 84 ++--------- ivy/src/main/scala/sbt/ModuleID.scala | 3 + ivy/src/main/scala/sbt/PairPicklers.scala | 44 ++++++ ivy/src/main/scala/sbt/UpdateReport.scala | 146 ++++++++++++++----- ivy/src/test/scala/DMSerializationSpec.scala | 67 +++++++++ 11 files changed, 409 insertions(+), 108 deletions(-) create mode 100644 ivy/src/main/scala/sbt/DatePicklers.scala create mode 100644 ivy/src/main/scala/sbt/FileMapPicklers.scala create mode 100644 ivy/src/main/scala/sbt/PairPicklers.scala create mode 100644 ivy/src/test/scala/DMSerializationSpec.scala diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/ivy/src/main/scala/sbt/Artifact.scala index 325ef7b6b..f24c93267 100644 --- a/ivy/src/main/scala/sbt/Artifact.scala +++ b/ivy/src/main/scala/sbt/Artifact.scala @@ -5,6 +5,7 @@ package sbt import java.io.File import java.net.URL +import sbt.serialization._ final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String, String]) { def extra(attributes: (String, String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) @@ -71,4 +72,73 @@ object Artifact { def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) def classified(name: String, classifier: String): Artifact = Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) + + private val optStringPickler = implicitly[Pickler[Option[String]]] + private val optStringUnpickler = implicitly[Unpickler[Option[String]]] + private val vectorConfigurationPickler = implicitly[Pickler[Vector[Configuration]]] + private val vectorConfigurationUnpickler = implicitly[Unpickler[Vector[Configuration]]] + private val stringStringMapPickler = implicitly[Pickler[Map[String, String]]] + private val stringStringMapUnpickler = implicitly[Unpickler[Map[String, String]]] + + implicit val pickler: Pickler[Artifact] = new Pickler[Artifact] { + val tag = implicitly[FastTypeTag[Artifact]] + val stringTag = implicitly[FastTypeTag[String]] + val optionStringTag = implicitly[FastTypeTag[Option[String]]] + val vectorConfigurationTag = implicitly[FastTypeTag[Vector[Configuration]]] + val stringStringMapTag = implicitly[FastTypeTag[Map[String, String]]] + def pickle(a: Artifact, builder: PBuilder): Unit = { + builder.pushHints() + builder.hintTag(tag) + builder.beginEntry(a) + builder.putField("name", { b => + b.hintTag(stringTag) + stringPickler.pickle(a.name, b) + }) + builder.putField("type", { b => + b.hintTag(stringTag) + stringPickler.pickle(a.`type`, b) + }) + builder.putField("extension", { b => + b.hintTag(stringTag) + stringPickler.pickle(a.extension, b) + }) + builder.putField("classifier", { b => + b.hintTag(optionStringTag) + optStringPickler.pickle(a.classifier, b) + }) + builder.putField("configurations", { b => + b.hintTag(vectorConfigurationTag) + vectorConfigurationPickler.pickle(a.configurations.toVector, b) + }) + builder.putField("url", { b => + b.hintTag(optionStringTag) + optStringPickler.pickle(a.url map { _.toString }, b) + }) + builder.putField("extraAttributes", { b => + b.hintTag(stringStringMapTag) + stringStringMapPickler.pickle(a.extraAttributes, b) + }) + builder.endEntry() + builder.popHints() + } + } + implicit val unpickler: Unpickler[Artifact] = new Unpickler[Artifact] { + val tag = implicitly[FastTypeTag[Artifact]] + def unpickle(tpe: String, reader: PReader): Any = { + reader.pushHints() + reader.hintTag(tag) + reader.beginEntry() + val name = stringPickler.unpickleEntry(reader.readField("name")).asInstanceOf[String] + val tp = stringPickler.unpickleEntry(reader.readField("type")).asInstanceOf[String] + val extension = stringPickler.unpickleEntry(reader.readField("extension")).asInstanceOf[String] + val classifier = optStringUnpickler.unpickleEntry(reader.readField("classifier")).asInstanceOf[Option[String]] + val configurations = vectorConfigurationUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[Configuration]] + val u = optStringUnpickler.unpickleEntry(reader.readField("url")).asInstanceOf[Option[String]] map { new URL(_) } + val extraAttributes = stringStringMapUnpickler.unpickleEntry(reader.readField("extraAttributes")).asInstanceOf[Map[String, String]] + val result = Artifact(name, tp, extension, classifier, configurations, u, extraAttributes) + reader.endEntry() + reader.popHints() + result + } + } } diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala index 58b5073b8..d666b32bc 100644 --- a/ivy/src/main/scala/sbt/Configuration.scala +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -3,6 +3,8 @@ */ package sbt +import sbt.serialization._ + object Configurations { def config(name: String) = new Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations @@ -61,3 +63,6 @@ final case class Configuration(name: String, description: String, isPublic: Bool def hide = Configuration(name, description, false, extendsConfigs, transitive) override def toString = name } +object Configuration { + implicit val pickler: Pickler[Configuration] with Unpickler[Configuration] = PicklerUnpickler.generate[Configuration] +} diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/ivy/src/main/scala/sbt/CrossVersion.scala index da37da251..b17ac525c 100644 --- a/ivy/src/main/scala/sbt/CrossVersion.scala +++ b/ivy/src/main/scala/sbt/CrossVersion.scala @@ -1,6 +1,7 @@ package sbt import cross.CrossVersionUtil +import sbt.serialization._ final case class ScalaVersion(full: String, binary: String) @@ -35,6 +36,42 @@ object CrossVersion { override def toString = "Full" } + private val disabledTag = implicitly[FastTypeTag[Disabled.type]] + private val binaryTag = implicitly[FastTypeTag[Binary]] + private val fullTag = implicitly[FastTypeTag[Full]] + implicit val pickler: Pickler[CrossVersion] = new Pickler[CrossVersion] { + val tag = implicitly[FastTypeTag[CrossVersion]] + def pickle(a: CrossVersion, builder: PBuilder): Unit = { + builder.pushHints() + builder.hintTag(a match { + case Disabled => disabledTag + case x: Binary => binaryTag + case x: Full => fullTag + }) + builder.beginEntry(a) + builder.endEntry() + builder.popHints() + } + } + implicit val unpickler: Unpickler[CrossVersion] = new Unpickler[CrossVersion] { + val tag = implicitly[FastTypeTag[CrossVersion]] + def unpickle(tpe: String, reader: PReader): Any = { + reader.pushHints() + reader.hintTag(tag) + val tpeStr = reader.beginEntry() + val tpe = scala.pickling.FastTypeTag(tpeStr) + // sys.error(tpe.toString) + val result = tpe match { + case t if t == disabledTag => Disabled + case t if t == binaryTag => binary + case t if t == fullTag => full + } + reader.endEntry() + reader.popHints() + result + } + } + /** Cross-versions a module with the full version (typically the full Scala version). */ def full: CrossVersion = new Full(idFun) diff --git a/ivy/src/main/scala/sbt/DatePicklers.scala b/ivy/src/main/scala/sbt/DatePicklers.scala new file mode 100644 index 000000000..166f50f2d --- /dev/null +++ b/ivy/src/main/scala/sbt/DatePicklers.scala @@ -0,0 +1,35 @@ +package sbt + +import sbt.serialization._ +import java.{ util => ju } + +private[sbt] object DatePicklers { + private val longTag = implicitly[FastTypeTag[Long]] + implicit val datePickler: Pickler[ju.Date] = new Pickler[ju.Date] { + val tag = implicitly[FastTypeTag[ju.Date]] + def pickle(a: ju.Date, builder: PBuilder): Unit = { + builder.pushHints() + builder.hintTag(tag) + builder.beginEntry(a) + builder.putField("value", { b => + b.hintTag(longTag) + longPickler.pickle(a.getTime, b) + }) + builder.endEntry() + builder.popHints() + } + } + implicit val dateUnpickler: Unpickler[ju.Date] = new Unpickler[ju.Date] { + val tag = implicitly[FastTypeTag[ju.Date]] + def unpickle(tpe: String, reader: PReader): Any = { + reader.pushHints() + reader.hintTag(tag) + reader.beginEntry() + val a0 = longPickler.unpickleEntry(reader.readField("value")).asInstanceOf[Long] + val result = new ju.Date(a0) + reader.endEntry() + reader.popHints() + result + } + } +} diff --git a/ivy/src/main/scala/sbt/FileMapPicklers.scala b/ivy/src/main/scala/sbt/FileMapPicklers.scala new file mode 100644 index 000000000..8a7314118 --- /dev/null +++ b/ivy/src/main/scala/sbt/FileMapPicklers.scala @@ -0,0 +1,22 @@ +package sbt + +import java.io.File +import sbt.serialization._ +import java.net.URI + +object FileMapPicklers { + implicit def fileMapPickler[A: Pickler: Unpickler: FastTypeTag]: Pickler[Map[File, A]] with Unpickler[Map[File, A]] = new Pickler[Map[File, A]] with Unpickler[Map[File, A]] { + val tag = implicitly[FastTypeTag[Map[File, A]]] + val stringAMapPickler = implicitly[Pickler[Map[String, A]]] + val stringAMapUnpickler = implicitly[Unpickler[Map[String, A]]] + + def pickle(m: Map[File, A], builder: PBuilder): Unit = + stringAMapPickler.pickle(Map(m.toSeq map { case (k, v) => (k.toURI.toASCIIString, v) }: _*), builder) + + def unpickle(tpe: String, reader: PReader): Any = + Map(stringAMapUnpickler.unpickle(tpe, reader).asInstanceOf[Map[String, A]].toSeq map { + case (k, v) => + (new File(new URI(k)), v) + }: _*).asInstanceOf[Map[File, A]] + } +} diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/ivy/src/main/scala/sbt/IvyInterface.scala index e4c2e8e46..3b54c684c 100644 --- a/ivy/src/main/scala/sbt/IvyInterface.scala +++ b/ivy/src/main/scala/sbt/IvyInterface.scala @@ -8,6 +8,7 @@ import java.net.{ URI, URL } import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } import org.apache.ivy.util.url.CredentialsStore +import sbt.serialization._ /** Additional information about a project module */ final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { @@ -26,6 +27,9 @@ final case class Developer(id: String, name: String, email: String, url: URL) /** Rule to exclude unwanted dependencies pulled in transitively by a module. */ final case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) +object ExclusionRule { + implicit val pickler: Pickler[ExclusionRule] with Unpickler[ExclusionRule] = PicklerUnpickler.generate[ExclusionRule] +} final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration { diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index c1e03d1d5..ddd126555 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -2,22 +2,17 @@ package sbt import java.io.File import java.net.URL -import org.json4s._ import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor +import sbt.serialization._ private[sbt] object JsonUtil { def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { - import org.json4s._ - implicit val formats = native.Serialization.formats(NoTypeHints) + - new ConfigurationSerializer + - new ArtifactSerializer + - new FileSerializer + - new URLSerializer try { - val json = jawn.support.json4s.Parser.parseFromFile(path) - fromLite(json.get.extract[UpdateReportLite], cachedDescriptor) + val s = IO.read(path, IO.utf8) + val lite = fromJsonString[UpdateReportLite](s).get + fromLite(lite, cachedDescriptor) } catch { case e: Throwable => log.error("Unable to parse mini graph: " + path.toString) @@ -26,12 +21,7 @@ private[sbt] object JsonUtil { } def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { - implicit val formats = native.Serialization.formats(NoTypeHints) + - new ConfigurationSerializer + - new ArtifactSerializer + - new FileSerializer - import native.Serialization.write - val str = write(toLite(ur)) + val str = toJsonString(toLite(ur)) IO.write(graphPath, str, IO.utf8) } def toLite(ur: UpdateReport): UpdateReportLite = @@ -60,61 +50,11 @@ private[sbt] object JsonUtil { } private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) +private[sbt] object UpdateReportLite { + implicit val pickler: Pickler[UpdateReportLite] with Unpickler[UpdateReportLite] = PicklerUnpickler.generate[UpdateReportLite] +} + private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) - -private[sbt] class URLSerializer extends CustomSerializer[URL](format => ( - { - case JString(s) => new URL(s) - }, - { - case x: URL => JString(x.toString) - } -)) - -private[sbt] class FileSerializer extends CustomSerializer[File](format => ( - { - case JString(s) => new File(s) - }, - { - case x: File => JString(x.toString) - } -)) - -private[sbt] class ConfigurationSerializer extends CustomSerializer[Configuration](format => ( - { - case JString(s) => new Configuration(s) - }, - { - case x: Configuration => JString(x.name) - } -)) - -private[sbt] class ArtifactSerializer extends CustomSerializer[Artifact](format => ( - { - case json: JValue => - implicit val fmt = format - Artifact( - (json \ "name").extract[String], - (json \ "type").extract[String], - (json \ "extension").extract[String], - (json \ "classifier").extract[Option[String]], - (json \ "configurations").extract[List[Configuration]], - (json \ "url").extract[Option[URL]], - (json \ "extraAttributes").extract[Map[String, String]] - ) - }, - { - case x: Artifact => - import DefaultJsonFormats.{ OptionWriter, StringWriter, mapWriter } - val optStr = implicitly[Writer[Option[String]]] - val mw = implicitly[Writer[Map[String, String]]] - JObject(JField("name", JString(x.name)) :: - JField("type", JString(x.`type`)) :: - JField("extension", JString(x.extension)) :: - JField("classifier", optStr.write(x.classifier)) :: - JField("configurations", JArray(x.configurations.toList map { x => JString(x.name) })) :: - JField("url", optStr.write(x.url map { _.toString })) :: - JField("extraAttributes", mw.write(x.extraAttributes)) :: - Nil) - } -)) +private[sbt] object ConfigurationReportLite { + implicit val pickler: Pickler[ConfigurationReportLite] with Unpickler[ConfigurationReportLite] = PicklerUnpickler.generate[ConfigurationReportLite] +} diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/ivy/src/main/scala/sbt/ModuleID.scala index c0e8670d5..10647dcad 100644 --- a/ivy/src/main/scala/sbt/ModuleID.scala +++ b/ivy/src/main/scala/sbt/ModuleID.scala @@ -6,6 +6,7 @@ package sbt import java.net.URL import sbt.mavenint.SbtPomExtraProperties +import sbt.serialization._ final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = @@ -119,6 +120,8 @@ final case class ModuleID(organization: String, name: String, revision: String, def jar() = artifacts(Artifact(name)) } object ModuleID { + implicit val pickler: Pickler[ModuleID] with Unpickler[ModuleID] = PicklerUnpickler.generate[ModuleID] + /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) diff --git a/ivy/src/main/scala/sbt/PairPicklers.scala b/ivy/src/main/scala/sbt/PairPicklers.scala new file mode 100644 index 000000000..2229059f2 --- /dev/null +++ b/ivy/src/main/scala/sbt/PairPicklers.scala @@ -0,0 +1,44 @@ +package sbt + +import sbt.serialization._ + +private[sbt] object PairPicklers { + implicit def pairPickler[A1: FastTypeTag: Pickler: Unpickler, A2: FastTypeTag: Pickler: Unpickler](): Pickler[(A1, A2)] with Unpickler[(A1, A2)] = + new Pickler[(A1, A2)] with Unpickler[(A1, A2)] { + val a1Tag = implicitly[FastTypeTag[A1]] + val a2Tag = implicitly[FastTypeTag[A2]] + val tag = implicitly[FastTypeTag[(A1, A2)]] + val a1Pickler = implicitly[Pickler[A1]] + val a1Unpickler = implicitly[Unpickler[A1]] + val a2Pickler = implicitly[Pickler[A2]] + val a2Unpickler = implicitly[Unpickler[A2]] + + def pickle(a: (A1, A2), builder: PBuilder): Unit = { + builder.pushHints() + builder.hintTag(tag) + builder.beginEntry(a) + builder.putField("_1", { b => + b.hintTag(a1Tag) + a1Pickler.pickle(a._1, b) + }) + builder.putField("_2", { b => + b.hintTag(a2Tag) + a2Pickler.pickle(a._2, b) + }) + builder.endEntry() + builder.popHints() + } + + def unpickle(tpe: String, reader: PReader): Any = { + reader.pushHints() + reader.hintTag(tag) + reader.beginEntry() + val a0 = a1Unpickler.unpickleEntry(reader.readField("_1")).asInstanceOf[A1] + val a1 = a2Unpickler.unpickleEntry(reader.readField("_2")).asInstanceOf[A2] + val result = (a0, a1) + reader.endEntry() + reader.popHints() + result + } + } +} diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 9487febef..672f6abc1 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -6,41 +6,7 @@ package sbt import java.io.File import java.net.URL import java.{ util => ju } - -/** - * Provides information about dependency resolution. - * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. - * This means that for a given configuration, there should only be one revision for a given organization and module name. - * @param cachedDescriptor the location of the resolved module descriptor in the cache - * @param configurations a sequence containing one report for each configuration resolved. - * @param stats information about the update that produced this report - * @see sbt.RichUpdateReport - */ -final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File, Long]) { - @deprecated("Use the variant that provides timestamps of files.", "0.13.0") - def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = - this(cachedDescriptor, configurations, stats, Map.empty) - - override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString - - /** All resolved modules in all configurations. */ - def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct - - def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) - - /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ - def configuration(s: String) = configurations.find(_.configuration == s) - - /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ - def allConfigurations: Seq[String] = configurations.map(_.configuration) - - private[sbt] def withStats(us: UpdateStats): UpdateReport = - new UpdateReport(this.cachedDescriptor, - this.configurations, - us, - this.stamps) -} +import sbt.serialization._ /** * Provides information about resolution of a single configuration. @@ -71,6 +37,9 @@ final class ConfigurationReport( def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details, evicted) } +object ConfigurationReport { + implicit val pickler: Pickler[ConfigurationReport] with Unpickler[ConfigurationReport] = PicklerUnpickler.generate[ConfigurationReport] +} /** * OrganizationArtifactReport represents an organization+name entry in Ivy resolution report. @@ -93,6 +62,8 @@ final class OrganizationArtifactReport private[sbt] ( } } object OrganizationArtifactReport { + implicit val pickler: Pickler[OrganizationArtifactReport] with Unpickler[OrganizationArtifactReport] = PicklerUnpickler.generate[OrganizationArtifactReport] + def apply(organization: String, name: String, modules: Seq[ModuleReport]): OrganizationArtifactReport = new OrganizationArtifactReport(organization, name, modules) } @@ -188,6 +159,14 @@ object ModuleReport { def apply(module: ModuleID, artifacts: Seq[(Artifact, File)], missingArtifacts: Seq[Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map(), None, None, Nil, Nil, Nil) + + import PairPicklers._ + import DatePicklers._ + private implicit val afPairPickler: Pickler[(Artifact, File)] with Unpickler[(Artifact, File)] = + pairPickler[Artifact, File] + private implicit def tuplePickler2: Pickler[(String, Option[String])] with Unpickler[(String, Option[String])] = + pairPickler[String, Option[String]] + implicit val pickler: Pickler[ModuleReport] with Unpickler[ModuleReport] = PicklerUnpickler.generate[ModuleReport] } final class Caller( @@ -201,6 +180,44 @@ final class Caller( override def toString: String = s"$caller" } +object Caller { + implicit val pickler: Pickler[Caller] with Unpickler[Caller] = PicklerUnpickler.generate[Caller] +} + +/** + * Provides information about dependency resolution. + * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. + * This means that for a given configuration, there should only be one revision for a given organization and module name. + * @param cachedDescriptor the location of the resolved module descriptor in the cache + * @param configurations a sequence containing one report for each configuration resolved. + * @param stats information about the update that produced this report + * @see sbt.RichUpdateReport + */ +final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File, Long]) { + @deprecated("Use the variant that provides timestamps of files.", "0.13.0") + def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = + this(cachedDescriptor, configurations, stats, Map.empty) + + override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString + + /** All resolved modules in all configurations. */ + def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + + def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = + new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) + + /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ + def configuration(s: String) = configurations.find(_.configuration == s) + + /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ + def allConfigurations: Seq[String] = configurations.map(_.configuration) + + private[sbt] def withStats(us: UpdateStats): UpdateReport = + new UpdateReport(this.cachedDescriptor, + this.configurations, + us, + this.stamps) +} object UpdateReport { implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) @@ -271,7 +288,61 @@ object UpdateReport { new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } } + + import FileMapPicklers._ + private val vectorConfigurationReportPickler = implicitly[Pickler[Vector[ConfigurationReport]]] + private val vectorConfigurationReportUnpickler = implicitly[Unpickler[Vector[ConfigurationReport]]] + private val updateStatsPickler = implicitly[Pickler[UpdateStats]] + private val updateStatsUnpickler = implicitly[Unpickler[UpdateStats]] + private val flMapPickler = implicitly[Pickler[Map[File, Long]]] + private val flMapUnpickler = implicitly[Unpickler[Map[File, Long]]] + + implicit val pickler: Pickler[UpdateReport] with Unpickler[UpdateReport] = new Pickler[UpdateReport] with Unpickler[UpdateReport] { + val tag = implicitly[FastTypeTag[UpdateReport]] + val fileTag = implicitly[FastTypeTag[File]] + val vectorConfigurationReportTag = implicitly[FastTypeTag[Vector[ConfigurationReport]]] + val updateStatsTag = implicitly[FastTypeTag[UpdateStats]] + val flMapTag = implicitly[FastTypeTag[Map[File, Long]]] + def pickle(a: UpdateReport, builder: PBuilder): Unit = { + builder.pushHints() + builder.hintTag(tag) + builder.beginEntry(a) + builder.putField("cachedDescriptor", { b => + b.hintTag(fileTag) + filePickler.pickle(a.cachedDescriptor, b) + }) + builder.putField("configurations", { b => + b.hintTag(vectorConfigurationReportTag) + vectorConfigurationReportPickler.pickle(a.configurations.toVector, b) + }) + builder.putField("stats", { b => + b.hintTag(updateStatsTag) + updateStatsPickler.pickle(a.stats, b) + }) + builder.putField("stamps", { b => + b.hintTag(flMapTag) + flMapPickler.pickle(a.stamps, b) + }) + builder.endEntry() + builder.popHints() + } + + def unpickle(tpe: String, reader: PReader): Any = { + reader.pushHints() + reader.hintTag(tag) + reader.beginEntry() + val cachedDescriptor = filePickler.unpickleEntry(reader.readField("cachedDescriptor")).asInstanceOf[File] + val configurations = vectorConfigurationReportUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[ConfigurationReport]] + val stats = updateStatsUnpickler.unpickleEntry(reader.readField("stats")).asInstanceOf[UpdateStats] + val stamps = flMapUnpickler.unpickleEntry(reader.readField("stamps")).asInstanceOf[Map[File, Long]] + val result = new UpdateReport(cachedDescriptor, configurations, stats, stamps) + reader.endEntry() + reader.popHints() + result + } + } } + final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") private[sbt] def withCached(c: Boolean): UpdateStats = @@ -279,4 +350,7 @@ final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downl downloadTime = this.downloadTime, downloadSize = this.downloadSize, cached = c) -} \ No newline at end of file +} +object UpdateStats { + implicit val pickler: Pickler[UpdateStats] with Unpickler[UpdateStats] = PicklerUnpickler.generate[UpdateStats] +} diff --git a/ivy/src/test/scala/DMSerializationSpec.scala b/ivy/src/test/scala/DMSerializationSpec.scala new file mode 100644 index 000000000..bf62de10b --- /dev/null +++ b/ivy/src/test/scala/DMSerializationSpec.scala @@ -0,0 +1,67 @@ +package sbt + +import org.specs2._ +import matcher.MatchResult +import java.net.URL +import java.io.File +import sbt.serialization._ + +class DMSerializationSpec extends Specification { + def is = sequential ^ s2""" + + This is a specification to check the serialization of dependency graph. + + CrossVersion.full should + ${roundtripStr(CrossVersion.full: sbt.CrossVersion)} + CrossVersion.binary should + ${roundtripStr(CrossVersion.binary: sbt.CrossVersion)} + CrossVersion.Disabled should + ${roundtrip(CrossVersion.Disabled: sbt.CrossVersion)} + + Artifact("foo") should + ${roundtrip(Artifact("foo"))} + Artifact("foo", "sources") should + ${roundtrip(Artifact("foo", "sources"))} + Artifact.pom("foo") should + ${roundtrip(Artifact.pom("foo"))} + Artifact("foo", url("http://example.com/")) should + ${roundtrip(Artifact("foo", new URL("http://example.com/")))} + Artifact("foo").extra(("key", "value")) should + ${roundtrip(Artifact("foo").extra(("key", "value")))} + + ModuleID("org", "name", "1.0") should + ${roundtrip(ModuleID("org", "name", "1.0"))} + + ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) should + ${roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil))} + Organization artifact report should + ${roundtripStr(organizationArtifactReportExample)} + Configuration report should + ${roundtripStr(configurationReportExample)} + Update report should + ${roundtripStr(updateReportExample)} + """ + + lazy val updateReportExample = + new UpdateReport(new File("./foo"), Vector(configurationReportExample), + new UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) + lazy val configurationReportExample = + new ConfigurationReport("compile", Vector(moduleReportExample), + Vector(organizationArtifactReportExample), Nil) + lazy val organizationArtifactReportExample = + new OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) + lazy val moduleReportExample = + ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) + + def roundtrip[A: Pickler: Unpickler](a: A) = + roundtripBuilder(a) { _ must_== _ } + def roundtripStr[A: Pickler: Unpickler](a: A) = + roundtripBuilder(a) { _.toString must_== _.toString } + def roundtripBuilder[A: Pickler: Unpickler](a: A)(f: (A, A) => MatchResult[Any]): MatchResult[Any] = + { + val json = toJsonString(a) + println(json) + val obj = fromJsonString[A](json).get + f(a, obj) + } +} From b583c031bb6ac6040e749a522041622d45a6b510 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 4 Mar 2015 12:04:10 -0500 Subject: [PATCH 0397/1030] OOM handling. #1763 --- .../main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 56a84fc8b..4fbda057b 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -24,6 +24,7 @@ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) def sbtOrgTemp = "org.scala-sbt.temp" + def graphVersion = "0.13.8" } private[sbt] class CachedResolutionResolveCache() { @@ -88,7 +89,7 @@ private[sbt] class CachedResolutionResolveCache() { val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts.mkString(",")};$moduleLevel;""" - val sha1 = Hash.toHex(Hash(depsString)) + val sha1 = Hash.toHex(Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""")) val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { def targetModuleRevisionId: ModuleRevisionId = mrid } From 936c804c41e4f4520a36ac5beff96d97d87c1761 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 6 Mar 2015 19:58:04 -0500 Subject: [PATCH 0398/1030] Improve caching internal deps. #1763 Some heap optimization during merging too. YourKit showed that mergeOrganizationArtifactReports takes up huge amount of heap. --- .../CachedResolutionResolveEngine.scala | 176 ++++++++++-------- 1 file changed, 101 insertions(+), 75 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 4fbda057b..14d7af22a 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -5,6 +5,7 @@ import java.util.Date import java.net.URL import java.io.File import collection.concurrent +import collection.mutable import collection.immutable.ListMap import org.apache.ivy.Ivy import org.apache.ivy.core @@ -30,10 +31,13 @@ private[sbt] object CachedResolutionResolveCache { private[sbt] class CachedResolutionResolveCache() { import CachedResolutionResolveCache._ val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() + // Used for subproject + val projectReportCache: concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap() val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() val conflictCache: concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap() - val maxConflictCacheSize: Int = 10000 + val maxConflictCacheSize: Int = 1024 + val maxUpdateReportCacheSize: Int = 1024 def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { updateReportCache.clear @@ -172,6 +176,10 @@ private[sbt] class CachedResolutionResolveCache() { else staticGraphPath log.debug(s"saving minigraph to $gp") JsonUtil.writeUpdateReport(ur, gp) + // limit the update cache size + if (updateReportCache.size > maxUpdateReportCacheSize) { + updateReportCache.remove(updateReportCache.head._1) + } // don't cache dynamic graphs in memory. if (!changing) { updateReportCache(md.getModuleRevisionId) = Right(ur) @@ -207,6 +215,13 @@ private[sbt] class CachedResolutionResolveCache() { } } } + def getOrElseUpdateProjectReport(mrid: ModuleRevisionId, logicalClock: LogicalClock)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = + if (projectReportCache contains (mrid -> logicalClock)) projectReportCache((mrid, logicalClock)) + else { + val oldKeys = projectReportCache.keys filter { case (x, clk) => clk != logicalClock } + projectReportCache --= oldKeys + projectReportCache.getOrElseUpdate((mrid, logicalClock), f) + } } private[sbt] trait ArtificialModuleDescriptor { self: DefaultModuleDescriptor => @@ -246,64 +261,66 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * This returns sbt's UpdateReport structure. * missingOk allows sbt to call this with classifiers that may or may not exist, and grab the JARs. */ - def customResolve(md0: ModuleDescriptor, missingOk: Boolean, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = { - import Path._ - val start = System.currentTimeMillis - val miniGraphPath = depDir / "module" - val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) - val cache = cachedResolutionResolveCache - val os = cache.extractOverrides(md0) - val options1 = new ResolveOptions(options0) - val data = new ResolveData(this, options1) - val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) + def customResolve(md0: ModuleDescriptor, missingOk: Boolean, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = + cachedResolutionResolveCache.getOrElseUpdateProjectReport(md0.getModuleRevisionId, logicalClock) { + import Path._ + val start = System.currentTimeMillis + val miniGraphPath = depDir / "module" + val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) + val cache = cachedResolutionResolveCache + val os = cache.extractOverrides(md0) + val options1 = new ResolveOptions(options0) + val data = new ResolveData(this, options1) + val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) - def doWork(md: ModuleDescriptor, dd: DependencyDescriptor): Either[ResolveException, UpdateReport] = - cache.internalDependency(dd, projectResolver) match { - case Some(md1) => - log.debug(s":: call customResolve recursively: $dd") - customResolve(md1, missingOk, logicalClock, options0, depDir, log) match { - case Right(ur) => Right(remapInternalProject(new IvyNode(data, md1), ur, md0, dd, os, log)) - case Left(e) => Left(e) - } - case None => - log.debug(s":: call ivy resolution: $dd") - doWorkUsingIvy(md) - } - def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = - { - val options1 = new ResolveOptions(options0) - var rr = withIvy(log) { ivy => - ivy.resolve(md, options1) - } - if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) - else { - val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct - val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => - val m = IvyRetrieve.toModuleID(node.getId) - val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => - IvyRetrieve.toModuleID(x.getId) + def doWork(md: ModuleDescriptor, dd: DependencyDescriptor): Either[ResolveException, UpdateReport] = + cache.internalDependency(dd, projectResolver) match { + case Some(md1) => + log.debug(s":: call customResolve recursively: $dd") + customResolve(md1, missingOk, logicalClock, options0, depDir, log) match { + case Right(ur) => Right(remapInternalProject(new IvyNode(data, md1), ur, md0, dd, os, log)) + case Left(e) => Left(e) } - log.debug("- Unresolved path " + path.toString) - m -> path - }: _*) - val failed = failedPaths.keys.toSeq - Left(new ResolveException(messages, failed, failedPaths)) + case None => + log.debug(s":: call ivy resolution: $dd") + doWorkUsingIvy(md) } + def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = + { + val options1 = new ResolveOptions(options0) + var rr = withIvy(log) { ivy => + ivy.resolve(md, options1) + } + if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) + else { + val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct + val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => + val m = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => + IvyRetrieve.toModuleID(x.getId) + } + log.debug("- Unresolved path " + path.toString) + m -> path + }: _*) + val failed = failedPaths.keys.toSeq + Left(new ResolveException(messages, failed, failedPaths)) + } + } + val results = mds map { + case (md, changing, dd) => + cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + doWork(md, dd) + } } - val results = mds map { - case (md, changing, dd) => - cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { - doWork(md, dd) - } + val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) + val cacheManager = getSettings.getResolutionCacheManager + cacheManager.saveResolvedModuleDescriptor(md0) + val prop0 = "" + val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) + IO.write(ivyPropertiesInCache0, prop0) + uReport } - val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) - val cacheManager = getSettings.getResolutionCacheManager - cacheManager.saveResolvedModuleDescriptor(md0) - val prop0 = "" - val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) - IO.write(ivyPropertiesInCache0, prop0) - uReport - } + def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], missingOk: Boolean, resolveTime: Long, os: Vector[IvyOverride], log: Logger): Either[ResolveException, UpdateReport] = if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) @@ -334,6 +351,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } + // memory usage 62%, of which 58% is in mergeOrganizationArtifactReports def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], os: Vector[IvyOverride], log: Logger): ConfigurationReport = { // get the details right, and the rest could be derived @@ -353,35 +371,43 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { /** * Returns a tuple of (merged org + name combo, newly evicted modules) */ - def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = + def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Seq[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = { - val pairs = (reports0 groupBy { oar => (oar.organization, oar.name) }).toSeq.toVector map { - case ((org, name), xs) => - log.debug(s""":::: $rootModuleConf: $org:$name""") - if (xs.size < 2) (xs.head, Vector()) + val evicteds: mutable.ListBuffer[ModuleReport] = mutable.ListBuffer() + val results: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() + // group by takes up too much memory. trading space with time. + val orgNamePairs = (reports0 map { oar => (oar.organization, oar.name) }).distinct + orgNamePairs foreach { + case (organization, name) => + // hand rolling groupBy to avoid memory allocation + val xs = reports0 filter { oar => oar.organization == organization && oar.name == name } + if (xs.size == 0) () // do nothing + else if (xs.size == 1) results += xs.head else - mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log) match { + results += (mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log) match { case (survivor, newlyEvicted) => - (new OrganizationArtifactReport(org, name, survivor ++ newlyEvicted), newlyEvicted) - } + evicteds ++= newlyEvicted + new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) + }) } - transitivelyEvict(rootModuleConf, pairs map { _._1 }, pairs flatMap { _._2 }, log) + transitivelyEvict(rootModuleConf, results.toList.toVector, evicteds.toList, log) } /** * This transitively evicts any non-evicted modules whose only callers are newly evicted. */ @tailrec private final def transitivelyEvict(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], - evicted0: Vector[ModuleReport], log: Logger): Vector[OrganizationArtifactReport] = + evicted0: List[ModuleReport], log: Logger): Vector[OrganizationArtifactReport] = { val em = evicted0 map { _.module } def isTransitivelyEvicted(mr: ModuleReport): Boolean = mr.callers forall { c => em contains { c.caller } } + val evicteds: mutable.ListBuffer[ModuleReport] = mutable.ListBuffer() // Ordering of the OrganizationArtifactReport matters - val pairs: Vector[(OrganizationArtifactReport, Vector[ModuleReport])] = reports0 map { oar => + val reports: Vector[OrganizationArtifactReport] = reports0 map { oar => val organization = oar.organization val name = oar.name - val (affected, unaffected) = oar.modules.toVector partition { mr => + val (affected, unaffected) = oar.modules partition { mr => val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) if (x) { log.debug(s""":::: transitively evicted $rootModuleConf: $organization:$name""") @@ -389,22 +415,22 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { x } val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) } - if (affected.isEmpty) (oar, Vector()) - else - (new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted), newlyEvicted) + if (affected.isEmpty) oar + else { + evicteds ++= newlyEvicted + new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) + } } - val reports = pairs map { _._1 } - val evicted = pairs flatMap { _._2 } - if (evicted.isEmpty) reports - else transitivelyEvict(rootModuleConf, reports, evicted, log) + if (evicteds.isEmpty) reports + else transitivelyEvict(rootModuleConf, reports, evicteds.toList, log) } /** * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). */ - def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = + def mergeModuleReports(rootModuleConf: String, modules: Seq[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { - def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = { + def mergeModuleReports(org: String, name: String, version: String, xs: Seq[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } val allArtifacts = (xs flatMap { _.artifacts }).distinct From 8a0e8ef74eb4dbda4e66c65f08a7ee2c4cb98e19 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 6 Mar 2015 19:58:38 -0500 Subject: [PATCH 0399/1030] Write JSON to file without String. #1763 --- ivy/src/main/scala/sbt/JsonUtil.scala | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index ddd126555..88d7e1e90 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -10,8 +10,7 @@ private[sbt] object JsonUtil { def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { try { - val s = IO.read(path, IO.utf8) - val lite = fromJsonString[UpdateReportLite](s).get + val lite = fromJsonFile[UpdateReportLite](path).get fromLite(lite, cachedDescriptor) } catch { case e: Throwable => @@ -21,8 +20,8 @@ private[sbt] object JsonUtil { } def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { - val str = toJsonString(toLite(ur)) - IO.write(graphPath, str, IO.utf8) + IO.createDirectory(graphPath.getParentFile) + toJsonFile(toLite(ur), graphPath) } def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => From 3afb941ad293ed969218fcc0eaf3660aee23d630 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 9 Mar 2015 21:14:23 -0400 Subject: [PATCH 0400/1030] Remove custom picklers - sbt/serialization supports these --- ivy/src/main/scala/sbt/Artifact.scala | 2 +- ivy/src/main/scala/sbt/DatePicklers.scala | 35 ---------------- ivy/src/main/scala/sbt/FileMapPicklers.scala | 22 ---------- ivy/src/main/scala/sbt/PairPicklers.scala | 44 -------------------- ivy/src/main/scala/sbt/UpdateReport.scala | 8 ---- 5 files changed, 1 insertion(+), 110 deletions(-) delete mode 100644 ivy/src/main/scala/sbt/DatePicklers.scala delete mode 100644 ivy/src/main/scala/sbt/FileMapPicklers.scala delete mode 100644 ivy/src/main/scala/sbt/PairPicklers.scala diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/ivy/src/main/scala/sbt/Artifact.scala index f24c93267..4cafb0e67 100644 --- a/ivy/src/main/scala/sbt/Artifact.scala +++ b/ivy/src/main/scala/sbt/Artifact.scala @@ -126,7 +126,7 @@ object Artifact { val tag = implicitly[FastTypeTag[Artifact]] def unpickle(tpe: String, reader: PReader): Any = { reader.pushHints() - reader.hintTag(tag) + // reader.hintTag(tag) reader.beginEntry() val name = stringPickler.unpickleEntry(reader.readField("name")).asInstanceOf[String] val tp = stringPickler.unpickleEntry(reader.readField("type")).asInstanceOf[String] diff --git a/ivy/src/main/scala/sbt/DatePicklers.scala b/ivy/src/main/scala/sbt/DatePicklers.scala deleted file mode 100644 index 166f50f2d..000000000 --- a/ivy/src/main/scala/sbt/DatePicklers.scala +++ /dev/null @@ -1,35 +0,0 @@ -package sbt - -import sbt.serialization._ -import java.{ util => ju } - -private[sbt] object DatePicklers { - private val longTag = implicitly[FastTypeTag[Long]] - implicit val datePickler: Pickler[ju.Date] = new Pickler[ju.Date] { - val tag = implicitly[FastTypeTag[ju.Date]] - def pickle(a: ju.Date, builder: PBuilder): Unit = { - builder.pushHints() - builder.hintTag(tag) - builder.beginEntry(a) - builder.putField("value", { b => - b.hintTag(longTag) - longPickler.pickle(a.getTime, b) - }) - builder.endEntry() - builder.popHints() - } - } - implicit val dateUnpickler: Unpickler[ju.Date] = new Unpickler[ju.Date] { - val tag = implicitly[FastTypeTag[ju.Date]] - def unpickle(tpe: String, reader: PReader): Any = { - reader.pushHints() - reader.hintTag(tag) - reader.beginEntry() - val a0 = longPickler.unpickleEntry(reader.readField("value")).asInstanceOf[Long] - val result = new ju.Date(a0) - reader.endEntry() - reader.popHints() - result - } - } -} diff --git a/ivy/src/main/scala/sbt/FileMapPicklers.scala b/ivy/src/main/scala/sbt/FileMapPicklers.scala deleted file mode 100644 index 8a7314118..000000000 --- a/ivy/src/main/scala/sbt/FileMapPicklers.scala +++ /dev/null @@ -1,22 +0,0 @@ -package sbt - -import java.io.File -import sbt.serialization._ -import java.net.URI - -object FileMapPicklers { - implicit def fileMapPickler[A: Pickler: Unpickler: FastTypeTag]: Pickler[Map[File, A]] with Unpickler[Map[File, A]] = new Pickler[Map[File, A]] with Unpickler[Map[File, A]] { - val tag = implicitly[FastTypeTag[Map[File, A]]] - val stringAMapPickler = implicitly[Pickler[Map[String, A]]] - val stringAMapUnpickler = implicitly[Unpickler[Map[String, A]]] - - def pickle(m: Map[File, A], builder: PBuilder): Unit = - stringAMapPickler.pickle(Map(m.toSeq map { case (k, v) => (k.toURI.toASCIIString, v) }: _*), builder) - - def unpickle(tpe: String, reader: PReader): Any = - Map(stringAMapUnpickler.unpickle(tpe, reader).asInstanceOf[Map[String, A]].toSeq map { - case (k, v) => - (new File(new URI(k)), v) - }: _*).asInstanceOf[Map[File, A]] - } -} diff --git a/ivy/src/main/scala/sbt/PairPicklers.scala b/ivy/src/main/scala/sbt/PairPicklers.scala deleted file mode 100644 index 2229059f2..000000000 --- a/ivy/src/main/scala/sbt/PairPicklers.scala +++ /dev/null @@ -1,44 +0,0 @@ -package sbt - -import sbt.serialization._ - -private[sbt] object PairPicklers { - implicit def pairPickler[A1: FastTypeTag: Pickler: Unpickler, A2: FastTypeTag: Pickler: Unpickler](): Pickler[(A1, A2)] with Unpickler[(A1, A2)] = - new Pickler[(A1, A2)] with Unpickler[(A1, A2)] { - val a1Tag = implicitly[FastTypeTag[A1]] - val a2Tag = implicitly[FastTypeTag[A2]] - val tag = implicitly[FastTypeTag[(A1, A2)]] - val a1Pickler = implicitly[Pickler[A1]] - val a1Unpickler = implicitly[Unpickler[A1]] - val a2Pickler = implicitly[Pickler[A2]] - val a2Unpickler = implicitly[Unpickler[A2]] - - def pickle(a: (A1, A2), builder: PBuilder): Unit = { - builder.pushHints() - builder.hintTag(tag) - builder.beginEntry(a) - builder.putField("_1", { b => - b.hintTag(a1Tag) - a1Pickler.pickle(a._1, b) - }) - builder.putField("_2", { b => - b.hintTag(a2Tag) - a2Pickler.pickle(a._2, b) - }) - builder.endEntry() - builder.popHints() - } - - def unpickle(tpe: String, reader: PReader): Any = { - reader.pushHints() - reader.hintTag(tag) - reader.beginEntry() - val a0 = a1Unpickler.unpickleEntry(reader.readField("_1")).asInstanceOf[A1] - val a1 = a2Unpickler.unpickleEntry(reader.readField("_2")).asInstanceOf[A2] - val result = (a0, a1) - reader.endEntry() - reader.popHints() - result - } - } -} diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/ivy/src/main/scala/sbt/UpdateReport.scala index 672f6abc1..5a866632a 100644 --- a/ivy/src/main/scala/sbt/UpdateReport.scala +++ b/ivy/src/main/scala/sbt/UpdateReport.scala @@ -159,13 +159,6 @@ object ModuleReport { def apply(module: ModuleID, artifacts: Seq[(Artifact, File)], missingArtifacts: Seq[Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map(), None, None, Nil, Nil, Nil) - - import PairPicklers._ - import DatePicklers._ - private implicit val afPairPickler: Pickler[(Artifact, File)] with Unpickler[(Artifact, File)] = - pairPickler[Artifact, File] - private implicit def tuplePickler2: Pickler[(String, Option[String])] with Unpickler[(String, Option[String])] = - pairPickler[String, Option[String]] implicit val pickler: Pickler[ModuleReport] with Unpickler[ModuleReport] = PicklerUnpickler.generate[ModuleReport] } @@ -289,7 +282,6 @@ object UpdateReport { } } - import FileMapPicklers._ private val vectorConfigurationReportPickler = implicitly[Pickler[Vector[ConfigurationReport]]] private val vectorConfigurationReportUnpickler = implicitly[Unpickler[Vector[ConfigurationReport]]] private val updateStatsPickler = implicitly[Pickler[UpdateStats]] From a50fcab1f8c75b5e1f31bf06b57a4e79c654db38 Mon Sep 17 00:00:00 2001 From: Max Worgan Date: Mon, 23 Mar 2015 14:16:05 +0000 Subject: [PATCH 0401/1030] Inserted brackets to developer xml renders correctly --- ivy/src/main/scala/sbt/MakePom.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index dde1f40ef..de75756cd 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -109,13 +109,15 @@ class MakePom(val log: Logger) { { if (moduleInfo.developers.nonEmpty) { - moduleInfo.developers.map{ developer: Developer => - - { developer.id } - { developer.name } - { developer.email } - { developer.url } - + { + moduleInfo.developers.map { developer: Developer => + + { developer.id } + { developer.name } + { developer.email } + { developer.url } + + } } } else NodeSeq.Empty From df959cf0d4f58da82bf13a8423390a41673e7440 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Tue, 24 Mar 2015 16:12:51 -0400 Subject: [PATCH 0402/1030] Migrate to using the sbt/launcher module, rather than having the code embedded. * Remove launch/* code/tests, as these are in the sbt/launcher project. * Create a new project which will resolve launcher module from sonatype-snapshots, and repackage it for the currently building version of sbt. * Remove ComponentManagerTest which was relying DIRECTLY on launcher classes. We'll need to reconfigure this shortly to enable the tests again. Remaining TODOs - * Update resolvers so people can find the launcher. * Add ComponentManagerTest back. * Re-publish the sbt-launch.jar in the location it used to be published. --- ivy/src/test/scala/ComponentManagerTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index 1995bb304..a4c720ed2 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -7,6 +7,11 @@ import IO.{ createDirectory, delete, touch, withTemporaryDirectory } import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail +// TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. +// This is testing something which uses a launcher interface, but was grabbing the underlying class directly +// when it really should, instead, be stubbing out the underyling class. + +/* object ComponentManagerTest extends Specification { val TestID = "manager-test" "Component manager" should { @@ -87,3 +92,4 @@ object ComponentManagerTest extends Specification { } } } +*/ \ No newline at end of file From 7877723d1242516dd589467bd83dc9dac1eb2702 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 25 Mar 2015 08:03:09 -0400 Subject: [PATCH 0403/1030] Restore component manager test via stubs. --- ivy/src/test/scala/ComponentManagerTest.scala | 38 +++++++++++++++++-- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala index a4c720ed2..165bdf9e2 100644 --- a/ivy/src/test/scala/ComponentManagerTest.scala +++ b/ivy/src/test/scala/ComponentManagerTest.scala @@ -1,17 +1,18 @@ package sbt import java.io.File +import java.util.concurrent.Callable import org.specs2._ import mutable.Specification import IO.{ createDirectory, delete, touch, withTemporaryDirectory } import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail +import xsbti.ComponentProvider // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly // when it really should, instead, be stubbing out the underyling class. -/* object ComponentManagerTest extends Specification { val TestID = "manager-test" "Component manager" should { @@ -87,9 +88,40 @@ object ComponentManagerTest extends Specification { private def withManagerHome[T](ivyHome: File)(f: ComponentManager => T): T = TestLogger { logger => withTemporaryDirectory { temp => - val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + // The actual classes we'll use at runtime. + //val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + + // A stub component manager + object provider extends ComponentProvider { + override def componentLocation(id: String): File = new File(temp, id) + override def lockFile(): File = { + IO.createDirectory(temp) + new java.io.File(temp, "sbt.components.lock") + } + override def defineComponent(id: String, files: Array[File]): Unit = { + val location = componentLocation(id) + if (location.exists) + throw new RuntimeException(s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}") + else + IO.copy(files.map { f => f -> new java.io.File(location, f.getName) }) + } + override def addToComponent(id: String, files: Array[File]): Boolean = { + val location = componentLocation(id) + IO.copy(files.map { f => f -> new java.io.File(location, f.getName) }) + true + } + override def component(id: String): Array[File] = + Option(componentLocation(id).listFiles()).map(_.filter(_.isFile)).getOrElse(Array.empty) + } + // A stubbed locking API. + object locks extends xsbti.GlobalLock { + override def apply[T](lockFile: File, run: Callable[T]): T = { + // TODO - do we need to lock? + run.call() + } + } + val mgr = new ComponentManager(locks, provider, Some(ivyHome), logger) f(mgr) } } } -*/ \ No newline at end of file From b4d0feb7daf0598a5693f5ea9a1d0763528da993 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Wed, 25 Mar 2015 10:18:59 -0400 Subject: [PATCH 0404/1030] Remove jcenter from generated pom.xml files (like maven central is not there). --- ivy/src/main/scala/sbt/MakePom.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index de75756cd..072a1a055 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -336,6 +336,9 @@ class MakePom(val log: Logger) { val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { + // TODO - Would it be ok if bintray were in the pom? We should avoid it for now. + case m: CustomRemoteMavenResolver if m.repo.root == JCenterRepository.root => Nil + case m: IBiblioResolver if m.isM2compatible && m.getRoot == JCenterRepository.root => Nil case m: CustomRemoteMavenResolver if m.repo.root != DefaultMavenRepository.root => MavenRepository(m.repo.name, m.repo.root) :: Nil case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => From 7f808721715857b6f9503dd2e65e710ed762e3ed Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Thu, 26 Mar 2015 16:09:29 -0400 Subject: [PATCH 0405/1030] Fixes #1921. * Add version range query (if needed) before resolving artifact in Aether. * Ensure detected version is used after having a version range query. --- ivy/src/main/scala/sbt/MakePom.scala | 96 +++++++++++++++------------- 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 072a1a055..d0e1a2741 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -21,8 +21,61 @@ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } import ivyint.CustomRemoteMavenResolver +object MakePom { + /** True if the revision is an ivy-range, not a complete revision. */ + def isDependencyVersionRange(revision: String): Boolean = { + (revision endsWith "+") || + (revision contains "[") || + (revision contains "]") || + (revision contains "(") || + (revision contains ")") + } + /** Converts Ivy revision ranges to that of Maven POM */ + def makeDependencyVersion(revision: String): String = { + def plusRange(s: String, shift: Int = 0) = { + def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 + val (prefixVersion, lastVersion) = (s + "0" * shift).reverse.split("\\.", 2) match { + case Array(revLast, revRest) => + (revRest.reverse + ".", revLast.reverse) + case Array(revLast) => ("", revLast.reverse) + } + val lastVersionInt = lastVersion.toInt + s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt + pow(shift)})" + } + val startSym = Set(']', '[', '(') + val stopSym = Set(']', '[', ')') + val DotPlusPattern = """(.+)\.\+""".r + val DotNumPlusPattern = """(.+)\.(\d+)\+""".r + val NumPlusPattern = """(\d+)\+""".r + val maxDigit = 5 + try { + revision match { + case "+" => "[0,)" + case DotPlusPattern(base) => plusRange(base) + // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so + // we assume version ranges never go beyond 5 siginificant digits. + case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") + case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") + case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") + case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => + val start = rev(0) + val stop = rev(rev.length - 1) + val mid = rev.substring(1, rev.length - 1) + (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + case _ => revision + } + } catch { + case e: NumberFormatException => + // TODO - if the version doesn't meet our expectations, maybe we just issue a hard + // error instead of softly ignoring the attempt to rewrite. + //sys.error(s"Could not fix version [$revision] into maven style version") + revision + } + } +} class MakePom(val log: Logger) { + import MakePom._ @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = write(ivy, module, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], Set(Artifact.DefaultType), extra, process, filterRepositories, allRepositories, output) @@ -218,49 +271,6 @@ class MakePom(val log: Logger) { } - /** Converts Ivy revision ranges to that of Maven POM */ - def makeDependencyVersion(revision: String): String = { - def plusRange(s: String, shift: Int = 0) = { - def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 - val (prefixVersion, lastVersion) = (s + "0" * shift).reverse.split("\\.", 2) match { - case Array(revLast, revRest) => - (revRest.reverse + ".", revLast.reverse) - case Array(revLast) => ("", revLast.reverse) - } - val lastVersionInt = lastVersion.toInt - s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt + pow(shift)})" - } - val startSym = Set(']', '[', '(') - val stopSym = Set(']', '[', ')') - val DotPlusPattern = """(.+)\.\+""".r - val DotNumPlusPattern = """(.+)\.(\d+)\+""".r - val NumPlusPattern = """(\d+)\+""".r - val maxDigit = 5 - try { - revision match { - case "+" => "[0,)" - case DotPlusPattern(base) => plusRange(base) - // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so - // we assume version ranges never go beyond 5 siginificant digits. - case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") - case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") - case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") - case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => - val start = rev(0) - val stop = rev(rev.length - 1) - val mid = rev.substring(1, rev.length - 1) - (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) - case _ => revision - } - } catch { - case e: NumberFormatException => - // TODO - if the version doesn't meet our expectations, maybe we just issue a hard - // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") - revision - } - } - @deprecated("No longer used and will be removed.", "0.12.1") def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { From 07731e68f51005b91d1f0bebe369ab2fe28847d2 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 27 Mar 2015 07:51:37 -0400 Subject: [PATCH 0406/1030] Fix unit test for makepom. --- ivy/src/test/scala/MakePomSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/test/scala/MakePomSpec.scala b/ivy/src/test/scala/MakePomSpec.scala index 3310ed62b..68ede8bc8 100644 --- a/ivy/src/test/scala/MakePomSpec.scala +++ b/ivy/src/test/scala/MakePomSpec.scala @@ -61,10 +61,10 @@ class MakePomSpec extends Specification { val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String) = - mp.makeDependencyVersion(s) must_== expected + MakePom.makeDependencyVersion(s) must_== expected def beParsedAsError(s: String) = try { - mp.makeDependencyVersion(s) + MakePom.makeDependencyVersion(s) failure } catch { case e: Throwable => success From d3246e591526b8e264729287b9bfea08fccd3047 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 31 Mar 2015 10:59:41 -0400 Subject: [PATCH 0407/1030] Add retrieveManagedSync --- ivy/src/main/scala/sbt/IvyActions.scala | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index bc4bd61fd..bd2647c4d 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,7 +31,7 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value = this.logging): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging) } -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean) final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) @@ -177,7 +177,7 @@ object IvyActions { Left(UnresolvedWarning(x, uwconfig)) case Right(uReport) => configuration.retrieve match { - case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) case None => Right(uReport) } } @@ -193,7 +193,7 @@ object IvyActions { val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) configuration.retrieve match { - case Some(rConf) => Right(retrieve(ivy, uReport, rConf)) + case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) case None => Right(uReport) } } @@ -292,11 +292,12 @@ object IvyActions { } else None (resolveReport, err) } - private def retrieve(ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = - retrieve(ivy, report, config.retrieveDirectory, config.outputPattern) + private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = + retrieve(log, ivy, report, config.retrieveDirectory, config.outputPattern, config.sync) - private def retrieve(ivy: Ivy, report: UpdateReport, base: File, pattern: String): UpdateReport = + private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, base: File, pattern: String, sync: Boolean): UpdateReport = { + val existingFiles = PathFinder(base).***.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf, mid, art, cached) => val to = retrieveTarget(conf, mid, art, base, pattern) @@ -304,6 +305,15 @@ object IvyActions { to } IO.copy(toCopy) + val resolvedFiles = toCopy.map(_._2) + if (sync) { + val filesToDelete = existingFiles.filterNot(resolvedFiles.contains) + filesToDelete foreach { f => + log.info(s"Deleting old dependency: ${f.getAbsolutePath}") + f.delete() + } + } + retReport } private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = From 31d71c72e281bef948cff613de329e804cdf85f7 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 31 Mar 2015 13:03:49 -0400 Subject: [PATCH 0408/1030] Fix compilation error in BaseIvySpecification --- ivy/src/test/scala/BaseIvySpecification.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 1be01ab25..00cbfc013 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -54,7 +54,7 @@ trait BaseIvySpecification extends Specification { def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern) + val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full) IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } From 983d07bd86097a867fbc38676cbaf0c7b10a6d7d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 3 Apr 2015 11:33:12 -0400 Subject: [PATCH 0409/1030] Add constructor with default sync value --- ivy/src/main/scala/sbt/IvyActions.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index bd2647c4d..3fa3c5476 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,7 +31,9 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value = this.logging): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging) } -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean) { + def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false) +} final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) From e647412bf6a6732781cdbb17b8ba84f64a010982 Mon Sep 17 00:00:00 2001 From: Andreas Flierl Date: Wed, 8 Apr 2015 15:01:18 +0200 Subject: [PATCH 0410/1030] Honor overwrite flag when publishing locally. --- ivy/src/main/scala/sbt/ConvertResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index 3771266aa..a01a51380 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -253,7 +253,7 @@ private[sbt] object ConvertResolver { if (totalLength > 0) { progress.setTotalLength(totalLength); } - FileUtil.copy(source, new java.io.File(url.toURI), progress) + FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) } catch { case ex: IOException => fireTransferError(ex) From 3f871a499db69761077bcbeec26791cd3d9de009 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 23 Apr 2015 12:49:45 -0400 Subject: [PATCH 0411/1030] Support configuring a subset of configurations from which to retrieve dependencies when retrieveManaged is true --- ivy/src/main/scala/sbt/IvyActions.scala | 28 ++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index 3fa3c5476..ef2db547e 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -31,8 +31,9 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val logging: UpdateLogging.Value = this.logging): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging) } -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean) { - def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false) +final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean, val configurationsToRetrieve: Option[Set[Configuration]]) { + def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) + def this(retrieveDirectory: File, outputPattern: String, sync: Boolean) = this(retrieveDirectory, outputPattern, sync, None) } final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) // exclude is a map on a restricted ModuleID @@ -295,16 +296,22 @@ object IvyActions { (resolveReport, err) } private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = - retrieve(log, ivy, report, config.retrieveDirectory, config.outputPattern, config.sync) + retrieve(log, ivy, report, config.retrieveDirectory, config.outputPattern, config.sync, config.configurationsToRetrieve) - private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, base: File, pattern: String, sync: Boolean): UpdateReport = + private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, base: File, pattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[Configuration]]): UpdateReport = { + val configurationNames = configurationsToRetrieve match { + case None => None + case Some(configs) => Some(configs.map(_.name)) + } val existingFiles = PathFinder(base).***.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf, mid, art, cached) => - val to = retrieveTarget(conf, mid, art, base, pattern) - toCopy += ((cached, to)) - to + configurationNames match { + case None => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + case Some(names) if names(conf) => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + case _ => cached + } } IO.copy(toCopy) val resolvedFiles = toCopy.map(_._2) @@ -318,6 +325,13 @@ object IvyActions { retReport } + + private def performRetrieve(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String, cached: File, toCopy: collection.mutable.HashSet[(File, File)]): File = { + val to = retrieveTarget(conf, mid, art, base, pattern) + toCopy += ((cached, to)) + to + } + private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = new File(base, substitute(conf, mid, art, pattern)) From 65dc88adc6225e28c39463dc7f894356d4fa43b7 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Wed, 20 May 2015 03:26:30 +0200 Subject: [PATCH 0412/1030] Do not emit in the pom dependencies that are only sources or docs The pom generation code tries its best to map Ivy's configurations to Maven scopes; however, sources and javadoc artifacts cannot be properly mapped and they currently are emitted as dependencies in the default scope (compile). That may lead to the source/doc jars being erroneously processed like regular jars by automated tools. Arguably, the source/docs jars should not be included in the pom file as dependencies at all. This commit filters out the dependencies that only appear in the sources and/or javadoc Ivy configurations, thereby preventing them from appearing in the final pom file. --- ivy/src/main/scala/sbt/MakePom.scala | 29 ++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index d0e1a2741..16bd6002a 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -233,28 +233,33 @@ class MakePom(val log: Logger) { val artifacts = dependency.getAllDependencyArtifacts val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) if (artifacts.isEmpty) { - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None) + val configs = dependency.getModuleConfigurations + if (configs.filterNot(Set("sources","docs")).nonEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None) + } else NodeSeq.Empty } else if (includeArtifacts.isEmpty) NodeSeq.Empty else - NodeSeq.fromSeq(artifacts.map(a => makeDependencyElem(dependency, a))) + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a))) } - def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Elem = + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = { val configs = artifact.getConfigurations.toList match { case Nil | "*" :: Nil => dependency.getModuleConfigurations case x => x.toArray } - val (scope, optional) = getScopeAndOptional(configs) - val classifier = artifactClassifier(artifact) - val baseType = artifactType(artifact) - val tpe = (classifier, baseType) match { - case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None - case _ => baseType - } - makeDependencyElem(dependency, scope, optional, classifier, tpe) + if (configs.filterNot(Set("sources","docs")).nonEmpty) { + val (scope, optional) = getScopeAndOptional(configs) + val classifier = artifactClassifier(artifact) + val baseType = artifactType(artifact) + val tpe = (classifier, baseType) match { + case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None + case _ => baseType + } + Some(makeDependencyElem(dependency, scope, optional, classifier, tpe)) + } else None } def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = { From e430139680d6b91bf00ec3e15d4dea55c0a87fad Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 21 May 2015 23:04:52 -0400 Subject: [PATCH 0413/1030] Fixes #1721/#1763. Cached resolution: summarize callers in graph.json - On some of the builds graph.json is reaching 250MB+ - JSON parsing alone takes hours - 97% of the content are caller info - This change summarizes all callers into one (zero caller would have correctness issues) --- ivy/src/main/scala/sbt/JsonUtil.scala | 28 ++++++++++++++++++- .../CachedResolutionResolveEngine.scala | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index 88d7e1e90..156c9aa44 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -25,8 +25,34 @@ private[sbt] object JsonUtil { } def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => - ConfigurationReportLite(cr.configuration, cr.details) + ConfigurationReportLite(cr.configuration, cr.details map { oar => + new OrganizationArtifactReport(oar.organization, oar.name, oar.modules map { mr => + new ModuleReport( + mr.module, mr.artifacts, mr.missingArtifacts, mr.status, + mr.publicationDate, mr.resolver, mr.artifactResolver, + mr.evicted, mr.evictedData, mr.evictedReason, + mr.problem, mr.homepage, mr.extraAttributes, + mr.isDefault, mr.branch, mr.configurations, mr.licenses, + summarizeCallers(mr.callers)) + }) + }) }) + // #1763/#2030. Caller takes up 97% of space, so we need to shrink it down, + // but there are semantics associated with some of them. + def summarizeCallers(callers: Seq[Caller]): Seq[Caller] = + if (callers.isEmpty) callers + else { + // Use the first element to represent all callers + val head = callers.head + val caller = new Caller( + head.caller, head.callerConfigurations, head.callerExtraAttributes, + callers exists { _.isForceDependency }, + callers exists { _.isChangingDependency }, + callers exists { _.isTransitiveDependency }, + callers exists { _.isDirectlyForceDependency }) + Seq(caller) + } + def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = { val stats = new UpdateStats(0L, 0L, 0L, false) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 14d7af22a..5b0418abf 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -25,7 +25,7 @@ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) def sbtOrgTemp = "org.scala-sbt.temp" - def graphVersion = "0.13.8" + def graphVersion = "0.13.9" } private[sbt] class CachedResolutionResolveCache() { From d83602e12b6e94b3559410d888fd70028876f68a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 23 May 2015 03:25:26 -0400 Subject: [PATCH 0414/1030] Cached resolution: Clean up old dynamic minigraphs. Fixes #2014 Cached resolution saves dynamic mini graphs (including subproject graphs) timestamped to the logical clock (State). This enables graph caching across the subprojects. On the other hand, it creates garbage that becomes stale almost immediately. Prior to #2030 fix, this garbage would reach 1GB+. This fix timestamps these graphs using calendar date, and cleans them up after a day. --- .../CachedResolutionResolveEngine.scala | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 5b0418abf..0c09d9fc4 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -4,6 +4,7 @@ package ivyint import java.util.Date import java.net.URL import java.io.File +import java.text.SimpleDateFormat import collection.concurrent import collection.mutable import collection.immutable.ListMap @@ -20,12 +21,19 @@ import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } import Configurations.{ System => _, _ } import annotation.tailrec +import scala.concurrent.duration._ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) def sbtOrgTemp = "org.scala-sbt.temp" def graphVersion = "0.13.9" + val buildStartup: Long = System.currentTimeMillis + lazy val todayStr: String = toYyyymmdd(buildStartup) + lazy val tomorrowStr: String = toYyyymmdd(buildStartup + (1 day).toMillis) + lazy val yesterdayStr: String = toYyyymmdd(buildStartup - (1 day).toMillis) + def toYyyymmdd(timeSinceEpoch: Long): String = yyyymmdd.format(new Date(timeSinceEpoch)) + lazy val yyyymmdd: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") } private[sbt] class CachedResolutionResolveCache() { @@ -137,7 +145,17 @@ private[sbt] class CachedResolutionResolveCache() { val staticGraphDirectory = miniGraphPath / "static" val dynamicGraphDirectory = miniGraphPath / "dynamic" val staticGraphPath = staticGraphDirectory / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + def cleanDynamicGraph(): Unit = + { + val list = (dynamicGraphDirectory listFiles DirectoryFilter).toList + list filterNot { d => + (d.getName == todayStr) || (d.getName == tomorrowStr) || (d.getName == yesterdayStr) + } foreach { d => + log.debug(s"deleting old graphs $d...") + IO.delete(d) + } + } def loadMiniGraphFromFile: Option[Either[ResolveException, UpdateReport]] = (if (staticGraphPath.exists) Some(staticGraphPath) else if (dynamicGraphPath.exists) Some(dynamicGraphPath) @@ -175,6 +193,9 @@ private[sbt] class CachedResolutionResolveCache() { val gp = if (changing) dynamicGraphPath else staticGraphPath log.debug(s"saving minigraph to $gp") + if (changing) { + cleanDynamicGraph() + } JsonUtil.writeUpdateReport(ur, gp) // limit the update cache size if (updateReportCache.size > maxUpdateReportCacheSize) { From fa97b0b8d61ce05acd47a733044b07c9c4af1595 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 23 May 2015 17:32:56 -0400 Subject: [PATCH 0415/1030] Adds null guard --- .../main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 0c09d9fc4..9f25d2172 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -148,7 +148,7 @@ private[sbt] class CachedResolutionResolveCache() { val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" def cleanDynamicGraph(): Unit = { - val list = (dynamicGraphDirectory listFiles DirectoryFilter).toList + val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList list filterNot { d => (d.getName == todayStr) || (d.getName == tomorrowStr) || (d.getName == yesterdayStr) } foreach { d => From 4d7184d8c394a6199c0ef4bb843220a1a786aea9 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 28 May 2015 08:14:08 +0100 Subject: [PATCH 0416/1030] Add project-level exclusions in the POM. Closes #1877. --- ivy/src/main/scala/sbt/MakePom.scala | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 16bd6002a..ffd189932 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -104,7 +104,7 @@ class MakePom(val log: Logger) { { val deps = depsInConfs(module, configurations) makeProperties(module, deps) ++ - makeDependencies(deps, includeTypes) + makeDependencies(deps, includeTypes, module.getAllExcludeRules) } { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) @@ -220,15 +220,15 @@ class MakePom(val log: Logger) { } val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) - def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = + def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = if (dependencies.isEmpty) NodeSeq.Empty else - { dependencies.map(makeDependency(_, includeTypes)) } + { dependencies.map(makeDependency(_, includeTypes, excludes)) } - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = { val artifacts = dependency.getAllDependencyArtifacts val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) @@ -236,15 +236,15 @@ class MakePom(val log: Logger) { val configs = dependency.getModuleConfigurations if (configs.filterNot(Set("sources","docs")).nonEmpty) { val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None) + makeDependencyElem(dependency, scope, optional, None, None, excludes) } else NodeSeq.Empty } else if (includeArtifacts.isEmpty) NodeSeq.Empty else - NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a))) + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) } - def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor, excludes: Seq[ExcludeRule]): Option[Elem] = { val configs = artifact.getConfigurations.toList match { case Nil | "*" :: Nil => dependency.getModuleConfigurations @@ -258,10 +258,10 @@ class MakePom(val log: Logger) { case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None case _ => baseType } - Some(makeDependencyElem(dependency, scope, optional, classifier, tpe)) + Some(makeDependencyElem(dependency, scope, optional, classifier, tpe, excludes)) } else None } - def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = + def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String], excludes: Seq[ExcludeRule]): Elem = { val mrid = dependency.getDependencyRevisionId @@ -272,7 +272,7 @@ class MakePom(val log: Logger) { { optionalElem(optional) } { classifierElem(classifier) } { typeElem(tpe) } - { exclusions(dependency) } + { exclusions(dependency, excludes) } } @@ -322,9 +322,9 @@ class MakePom(val log: Logger) { (scope, opt.nonEmpty) } - def exclusions(dependency: DependencyDescriptor): NodeSeq = + def exclusions(dependency: DependencyDescriptor, excludes: Seq[ExcludeRule]): NodeSeq = { - val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) + val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) if (excls.nonEmpty) { excls } From 7a124bd2dfbaa3a30ca88b9f19f3407ba0a2675c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 26 May 2015 23:25:08 +0100 Subject: [PATCH 0417/1030] Fix bincompat for project-level excludes in the POM. --- ivy/src/main/scala/sbt/MakePom.scala | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index ffd189932..4e0ed0118 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -220,6 +220,10 @@ class MakePom(val log: Logger) { } val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) + @deprecated("Use `makeDependencies` variant which takes excludes", "0.13.9") + def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = + makeDependencies(dependencies, includeTypes, Nil) + def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = if (dependencies.isEmpty) NodeSeq.Empty @@ -228,6 +232,10 @@ class MakePom(val log: Logger) { { dependencies.map(makeDependency(_, includeTypes, excludes)) } + @deprecated("Use `makeDependency` variant which takes excludes", "0.13.9") + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = + makeDependency(dependency, includeTypes, Nil) + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = { val artifacts = dependency.getAllDependencyArtifacts @@ -244,6 +252,10 @@ class MakePom(val log: Logger) { NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) } + @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = + makeDependencyElem(dependency, artifact, Nil) + def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor, excludes: Seq[ExcludeRule]): Option[Elem] = { val configs = artifact.getConfigurations.toList match { @@ -261,6 +273,11 @@ class MakePom(val log: Logger) { Some(makeDependencyElem(dependency, scope, optional, classifier, tpe, excludes)) } else None } + + @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") + def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = + makeDependencyElem(dependency, scope, optional, classifier, tpe, Nil) + def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String], excludes: Seq[ExcludeRule]): Elem = { val mrid = dependency.getDependencyRevisionId @@ -322,6 +339,9 @@ class MakePom(val log: Logger) { (scope, opt.nonEmpty) } + @deprecated("Use `exclusions` variant which takes excludes", "0.13.9") + def exclusions(dependency: DependencyDescriptor): NodeSeq = exclusions(dependency, Nil) + def exclusions(dependency: DependencyDescriptor, excludes: Seq[ExcludeRule]): NodeSeq = { val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes From 33e3b9f69377d447d3a420843a17438c60cbc47f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 28 May 2015 08:27:55 +0100 Subject: [PATCH 0418/1030] Commit build auto-formatting changes for code in master. --- ivy/src/main/scala/sbt/MakePom.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 4e0ed0118..1dfa5d1fe 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -242,7 +242,7 @@ class MakePom(val log: Logger) { val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) if (artifacts.isEmpty) { val configs = dependency.getModuleConfigurations - if (configs.filterNot(Set("sources","docs")).nonEmpty) { + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) makeDependencyElem(dependency, scope, optional, None, None, excludes) } else NodeSeq.Empty @@ -262,7 +262,7 @@ class MakePom(val log: Logger) { case Nil | "*" :: Nil => dependency.getModuleConfigurations case x => x.toArray } - if (configs.filterNot(Set("sources","docs")).nonEmpty) { + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { val (scope, optional) = getScopeAndOptional(configs) val classifier = artifactClassifier(artifact) val baseType = artifactType(artifact) From b51321b857826e7d3277ac9d164399ebe579e70e Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Mon, 11 May 2015 21:30:59 -0400 Subject: [PATCH 0419/1030] Fix corruption issues with sbt's CustomPomParser. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 29 ++++++++++++++------ 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 7b5664daf..601f6e34d 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -51,7 +51,15 @@ object CustomPomParser { private[this] val TransformedHashKey = "e:sbtTransformHash" // A hash of the parameters transformation is based on. // If a descriptor has a different hash, we need to retransform it. - private[this] val TransformHash: String = hash((unqualifiedKeys ++ JarPackagings).toSeq.sorted) + private[this] def makeCoords(mrid: ModuleRevisionId): String = s"${mrid.getOrganisation}:${mrid.getName}:${mrid.getRevision}" + + // We now include the ModuleID in a hash, to ensure that parent-pom transformations don't corrupt child poms. + private[this] def MakeTransformHash(md: ModuleDescriptor): String = { + val coords: String = makeCoords(md.getModuleRevisionId) + + hash((unqualifiedKeys ++ JarPackagings ++ Set(coords)).toSeq.sorted) + } + private[this] def hash(ss: Seq[String]): String = Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. @@ -65,11 +73,16 @@ object CustomPomParser { { val oldTransformedHashKey = "sbtTransformHash" val extraInfo = md.getExtraInfo + val MyHash = MakeTransformHash(md) + val h = MyHash // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { - case Some(TransformHash) => true - case _ => false + case x @ Some(MyHash) => + true + case Some(other) => + false + case _ => false }) } @@ -95,10 +108,10 @@ object CustomPomParser { val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) val unqualify = toUnqualify(filtered) - if (unqualify.isEmpty && extraDepAttributes.isEmpty && !convertArtifacts && !mergeDuplicates) - md - else - addExtra(unqualify, extraDepAttributes, parser, md) + + // Here we always add extra attributes. There's a scenario where parent-pom information corrupts child-poms with "e:" namespaced xml elements + // and we have to force the every generated xml file to have the appropriate xml namespace + addExtra(unqualify, extraDepAttributes, parser, md) } // The element of the pom is used to store additional metadata, such as for sbt plugins or for the base URL for API docs. // This is done because the pom XSD does not appear to allow extra metadata anywhere else. @@ -185,7 +198,7 @@ object CustomPomParser { for (l <- md.getLicenses) dmd.addLicense(l) for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, TransformHash) // mark as transformed by this version, so we don't need to do it again + dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again for ((key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) From fda77d56dbe53e5425a5bf8a5f1e8aa1607216e4 Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 29 May 2015 09:49:47 -0400 Subject: [PATCH 0420/1030] Minor fixes of leftover codes from review. --- ivy/src/main/scala/sbt/CustomPomParser.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index 601f6e34d..d37804cbc 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -74,14 +74,10 @@ object CustomPomParser { val oldTransformedHashKey = "sbtTransformHash" val extraInfo = md.getExtraInfo val MyHash = MakeTransformHash(md) - val h = MyHash // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { - case x @ Some(MyHash) => - true - case Some(other) => - false + case Some(MyHash) => true case _ => false }) } From 1aa7ba807b1ac6f57933fb35a194471e667d7d79 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 9 Jun 2015 17:20:03 +0200 Subject: [PATCH 0421/1030] Fixes the releasing --- ivy/src/main/scala/sbt/CustomPomParser.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/ivy/src/main/scala/sbt/CustomPomParser.scala index d37804cbc..be98bfe25 100644 --- a/ivy/src/main/scala/sbt/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/CustomPomParser.scala @@ -78,7 +78,7 @@ object CustomPomParser { Option(extraInfo).isDefined && ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { case Some(MyHash) => true - case _ => false + case _ => false }) } From 2bc3b884349b618969e8e5e69ad01f85a93a9d71 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 Jul 2015 01:52:00 -0400 Subject: [PATCH 0422/1030] Reproduce #2046 --- ivy/src/test/scala/BaseIvySpecification.scala | 5 +++ ivy/src/test/scala/CachedResolutionSpec.scala | 35 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 00cbfc013..385c3abce 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -59,6 +59,11 @@ trait BaseIvySpecification extends Specification { IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } + def cleanCachedResolutionCache(module: IvySbt#Module): Unit = + { + IvyActions.cleanCachedResolutionCache(module, log) + } + def ivyUpdate(module: IvySbt#Module) = ivyUpdateEither(module) match { case Right(r) => r diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala index 8ac88740e..a64fcb8c8 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -12,27 +12,38 @@ class CachedResolutionSpec extends BaseIvySpecification { Resolving the unsolvable module should not work $e2 + + Resolving a module with a pseudo-conflict should + work $e3 """ def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile")) + def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7", Some("compile")) + def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40", Some("compile")) + def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final", Some("compile")) def defaultOptions = EvictionWarningOptions.default import ShowLines._ def e1 = { - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), + Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) val report = ivyUpdate(m) + cleanCachedResolutionCache(m) val report2 = ivyUpdate(m) + // first resolution creates the minigraph println(report) + // second resolution reads from the minigraph println(report.configurations.head.modules.head.artifacts) report.configurations.size must_== 3 } def e2 = { - log.setLevel(Level.Debug) - val m = module(ModuleID("com.example", "foo", "0.2.0", Some("compile")), Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + // log.setLevel(Level.Debug) + val m = module(ModuleID("com.example", "foo", "0.2.0", Some("compile")), + Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed") case Left(uw) => @@ -48,4 +59,22 @@ class CachedResolutionSpec extends BaseIvySpecification { "\t\t +- com.example:foo:0.2.0")) } } + + // https://github.com/sbt/sbt/issues/2046 + // data-avro:1.9.40 depends on avro:1.4.0, which depends on netty:3.2.1.Final. + // avro:1.4.0 will be evicted by avro:1.7.7. + // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final + def e3 = { + log.setLevel(Level.Debug) + val m = module(ModuleID("com.example", "foo", "0.3.0", Some("compile")), + Seq(avro177, dataAvro1940, netty320), + Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + // first resolution creates the minigraph + val report0 = ivyUpdate(m) + cleanCachedResolutionCache(m) + // second resolution reads from the minigraph + val report = ivyUpdate(m) + val modules = report.configurations.head.modules + modules must containMatch("""org\.jboss\.netty:netty:3\.2\.0.Final""") + } } From 97d53db03bd9b7023c9a005c32e0fb89c8cd69c8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 Jul 2015 15:57:21 -0400 Subject: [PATCH 0423/1030] Fixes #2046, Ref #1760 Fix minigraph stitching This fixes the minigraph stitching logic by first sorting the graph based on the level of inter-dependencies, and gradually resolving conflict from the root-side that are not called by other libraries. For each eviction, transitive evictions are propagated right away to avoid double eviction observed in #2046 For the transitive eviction checking I needed to bring back the caller information, which is notorious for its size. I am stuffing all ModuleIDs into one ModuleID for the graph, and recovering them only during the merging process. --- ivy/src/main/scala/sbt/JsonUtil.scala | 36 ++++- .../CachedResolutionResolveEngine.scala | 145 ++++++++++++------ 2 files changed, 130 insertions(+), 51 deletions(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index 156c9aa44..5aed6e31f 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -5,8 +5,11 @@ import java.net.URL import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor import sbt.serialization._ +import java.net.{ URLEncoder, URLDecoder } private[sbt] object JsonUtil { + val fakeCallerOrganization = "org.scala-sbt.temp-callers" + def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { try { @@ -44,14 +47,45 @@ private[sbt] object JsonUtil { else { // Use the first element to represent all callers val head = callers.head + val name = + URLEncoder.encode( + (for { + caller <- callers + m = caller.caller + } yield s"${m.organization}:${m.name}:${m.revision}").mkString(";"), "UTF-8") + val version = head.caller.revision + val fakeCaller = ModuleID(fakeCallerOrganization, name, version) val caller = new Caller( - head.caller, head.callerConfigurations, head.callerExtraAttributes, + fakeCaller, head.callerConfigurations, head.callerExtraAttributes, callers exists { _.isForceDependency }, callers exists { _.isChangingDependency }, callers exists { _.isTransitiveDependency }, callers exists { _.isDirectlyForceDependency }) Seq(caller) } + def unsummarizeCallers(callers: Seq[Caller]): Seq[Caller] = + if (callers.isEmpty) callers + else { + val head = callers.head + val m = head.caller + if (m.organization != fakeCallerOrganization) callers + else { + // likely the caller is generated using the above summarizeCallers + val s = URLDecoder.decode(m.name, "UTF-8") + s.split(";").toList map { x => + x.split(":").toList match { + case List(organization, name, revision) => + val caller = ModuleID(organization, name, revision) + new Caller( + caller, head.callerConfigurations, head.callerExtraAttributes, + head.isForceDependency, head.isChangingDependency, + head.isTransitiveDependency, head.isDirectlyForceDependency + ) + case xs => sys.error(s"Unexpected caller $xs") + } + } + } + } def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = { diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 9f25d2172..3aa357031 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -27,7 +27,7 @@ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) def sbtOrgTemp = "org.scala-sbt.temp" - def graphVersion = "0.13.9" + def graphVersion = "0.13.9B" val buildStartup: Long = System.currentTimeMillis lazy val todayStr: String = toYyyymmdd(buildStartup) lazy val tomorrowStr: String = toYyyymmdd(buildStartup + (1 day).toMillis) @@ -367,6 +367,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val cachedReports = reports filter { !_.stats.cached } val stats = new UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) val configReports = rootModuleConfigs map { conf => + log.debug("::: -----------") val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } mergeConfigurationReports(conf.getName, crs, os, log) } @@ -392,70 +393,86 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { /** * Returns a tuple of (merged org + name combo, newly evicted modules) */ - def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Seq[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = + def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = { - val evicteds: mutable.ListBuffer[ModuleReport] = mutable.ListBuffer() - val results: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() // group by takes up too much memory. trading space with time. val orgNamePairs = (reports0 map { oar => (oar.organization, oar.name) }).distinct - orgNamePairs foreach { - case (organization, name) => - // hand rolling groupBy to avoid memory allocation - val xs = reports0 filter { oar => oar.organization == organization && oar.name == name } - if (xs.size == 0) () // do nothing - else if (xs.size == 1) results += xs.head - else - results += (mergeModuleReports(rootModuleConf, xs flatMap { _.modules }, os, log) match { - case (survivor, newlyEvicted) => - evicteds ++= newlyEvicted - new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) - }) - } - transitivelyEvict(rootModuleConf, results.toList.toVector, evicteds.toList, log) - } - /** - * This transitively evicts any non-evicted modules whose only callers are newly evicted. - */ - @tailrec - private final def transitivelyEvict(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], - evicted0: List[ModuleReport], log: Logger): Vector[OrganizationArtifactReport] = - { - val em = evicted0 map { _.module } - def isTransitivelyEvicted(mr: ModuleReport): Boolean = - mr.callers forall { c => em contains { c.caller } } - val evicteds: mutable.ListBuffer[ModuleReport] = mutable.ListBuffer() - // Ordering of the OrganizationArtifactReport matters - val reports: Vector[OrganizationArtifactReport] = reports0 map { oar => - val organization = oar.organization - val name = oar.name - val (affected, unaffected) = oar.modules partition { mr => - val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) - if (x) { - log.debug(s""":::: transitively evicted $rootModuleConf: $organization:$name""") + // this might take up some memory, but it's limited to a single + val reports1 = reports0 map { recoverCallers } + val allModules: ListMap[(String, String), Vector[OrganizationArtifactReport]] = + ListMap(orgNamePairs map { + case (organization, name) => + val xs = reports1 filter { oar => oar.organization == organization && oar.name == name } + ((organization, name), xs) + }: _*) + val stackGuard = reports0.size * reports0.size * 2 + // sort the all modules such that less called modules comes earlier + def sortModules(cs: ListMap[(String, String), Vector[OrganizationArtifactReport]], + n: Int): ListMap[(String, String), Vector[OrganizationArtifactReport]] = + { + val keys = cs.keySet + val (called, notCalled) = cs partition { + case (k, oas) => + oas exists { + _.modules.exists { + _.callers exists { caller => + val m = caller.caller + keys((m.organization, m.name)) + } + } + } } - x + notCalled ++ + (if (called.isEmpty || n > stackGuard) called + else sortModules(called, n + 1)) } - val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) } - if (affected.isEmpty) oar - else { - evicteds ++= newlyEvicted - new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) + def resolveConflicts(cs: List[((String, String), Vector[OrganizationArtifactReport])]): List[OrganizationArtifactReport] = + cs match { + case Nil => Nil + case (k, Vector()) :: rest => resolveConflicts(rest) + case (k, Vector(oa)) :: rest if (oa.modules.size == 0) => resolveConflicts(rest) + case (k, Vector(oa)) :: rest if (oa.modules.size == 1 && !oa.modules.head.evicted) => + log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") + oa :: resolveConflicts(rest) + case ((organization, name), oas) :: rest => + (mergeModuleReports(rootModuleConf, oas flatMap { _.modules }, os, log) match { + case (survivor, newlyEvicted) => + val evicted = (survivor ++ newlyEvicted) filter { m => m.evicted } + val notEvicted = (survivor ++ newlyEvicted) filter { m => !m.evicted } + log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) + log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) + val x = new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) + val next = transitivelyEvict(rootModuleConf, rest, evicted, log) + x :: resolveConflicts(next) + }) } - } - if (evicteds.isEmpty) reports - else transitivelyEvict(rootModuleConf, reports, evicteds.toList, log) + val sorted = sortModules(allModules, 0) + val result = resolveConflicts(sorted.toList) map { summarizeCallers } + result.toVector } + def recoverCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = + OrganizationArtifactReport( + report0.organization, + report0.name, + report0.modules map { mr => mr.copy(callers = JsonUtil.unsummarizeCallers(mr.callers)) }) + def summarizeCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = + OrganizationArtifactReport( + report0.organization, + report0.name, + report0.modules map { mr => mr.copy(callers = JsonUtil.summarizeCallers(mr.callers)) }) /** * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). */ def mergeModuleReports(rootModuleConf: String, modules: Seq[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { + if (modules.nonEmpty) { + log.debug(s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}") + } def mergeModuleReports(org: String, name: String, version: String, xs: Seq[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } val allArtifacts = (xs flatMap { _.artifacts }).distinct - log.debug(s":: merging module report for $org:$name:$version - $allArtifacts") xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = allCallers) } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { @@ -470,6 +487,33 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { (survivor ++ (merged filter { m => m.evicted || m.problem.isDefined }), evicted) } } + /** + * This transitively evicts any non-evicted modules whose only callers are newly evicted. + */ + def transitivelyEvict(rootModuleConf: String, reports0: List[((String, String), Vector[OrganizationArtifactReport])], + evicted0: Vector[ModuleReport], log: Logger): List[((String, String), Vector[OrganizationArtifactReport])] = + { + val em = (evicted0 map { _.module }).toSet + def isTransitivelyEvicted(mr: ModuleReport): Boolean = + mr.callers forall { c => em(c.caller) } + val reports: List[((String, String), Vector[OrganizationArtifactReport])] = reports0 map { + case ((organization, name), oars0) => + val oars = oars0 map { oar => + val (affected, unaffected) = oar.modules partition { mr => + val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) + if (x) { + log.debug(s""":::: transitively evicted $rootModuleConf: ${mr.module}""") + } + x + } + val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) } + if (affected.isEmpty) oar + else new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) + } + ((organization, name), oars) + } + reports + } /** * resolves dependency resolution conflicts in which multiple candidates are found for organization+name combos. * The main input is conflicts, which is a Vector of ModuleReport, which contains full info on the modulerevision, including its callers. @@ -487,7 +531,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val head = conflicts.head val organization = head.module.organization val name = head.module.name - log.debug(s"- conflict in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")")) + log.debug(s"::: resolving conflict in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")")) def useLatest(lcm: LatestConflictManager): (Vector[ModuleReport], Vector[ModuleReport], String) = (conflicts find { m => m.callers.exists { _.isDirectlyForceDependency } @@ -536,7 +580,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { if (conflicts.size == 2 && os.isEmpty) { val (cf0, cf1) = (conflicts(0).module, conflicts(1).module) val cache = cachedResolutionResolveCache - cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } + val (surviving, evicted) = cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } + (surviving, evicted) } else { val (surviving, evicted, mgr) = doResolveConflict (surviving, evicted) From 7cb92b3f6caca68a20eefaf4daadb2ba62616a12 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 Jul 2015 21:17:47 -0400 Subject: [PATCH 0424/1030] #1763 Remove artificial callers --- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 3aa357031..ce8ddf8cb 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -454,7 +454,14 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { OrganizationArtifactReport( report0.organization, report0.name, - report0.modules map { mr => mr.copy(callers = JsonUtil.unsummarizeCallers(mr.callers)) }) + report0.modules map { mr => + val original = JsonUtil.unsummarizeCallers(mr.callers) + // https://github.com/sbt/sbt/issues/1763 + mr.copy(callers = original filter { c => + (c.caller.organization != sbtOrgTemp) && + (c.caller.organization != JsonUtil.fakeCallerOrganization) + }) + }) def summarizeCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = OrganizationArtifactReport( report0.organization, From fe2026f419d68210900f44742cb9ef6cb50bd1cd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Jul 2015 00:10:23 -0400 Subject: [PATCH 0425/1030] #1763 fix by removing one but all artificial callers --- ivy/src/main/scala/sbt/JsonUtil.scala | 53 ++++--------------- .../CachedResolutionResolveEngine.scala | 19 ++----- 2 files changed, 16 insertions(+), 56 deletions(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index 5aed6e31f..e3983e7b4 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -8,7 +8,8 @@ import sbt.serialization._ import java.net.{ URLEncoder, URLDecoder } private[sbt] object JsonUtil { - val fakeCallerOrganization = "org.scala-sbt.temp-callers" + def sbtOrgTemp = "org.scala-sbt.temp" + def fakeCallerOrganization = "org.scala-sbt.temp-callers" def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { @@ -36,55 +37,23 @@ private[sbt] object JsonUtil { mr.evicted, mr.evictedData, mr.evictedReason, mr.problem, mr.homepage, mr.extraAttributes, mr.isDefault, mr.branch, mr.configurations, mr.licenses, - summarizeCallers(mr.callers)) + filterOutArtificialCallers(mr.callers)) }) }) }) // #1763/#2030. Caller takes up 97% of space, so we need to shrink it down, // but there are semantics associated with some of them. - def summarizeCallers(callers: Seq[Caller]): Seq[Caller] = + def filterOutArtificialCallers(callers: Seq[Caller]): Seq[Caller] = if (callers.isEmpty) callers else { - // Use the first element to represent all callers - val head = callers.head - val name = - URLEncoder.encode( - (for { - caller <- callers - m = caller.caller - } yield s"${m.organization}:${m.name}:${m.revision}").mkString(";"), "UTF-8") - val version = head.caller.revision - val fakeCaller = ModuleID(fakeCallerOrganization, name, version) - val caller = new Caller( - fakeCaller, head.callerConfigurations, head.callerExtraAttributes, - callers exists { _.isForceDependency }, - callers exists { _.isChangingDependency }, - callers exists { _.isTransitiveDependency }, - callers exists { _.isDirectlyForceDependency }) - Seq(caller) - } - def unsummarizeCallers(callers: Seq[Caller]): Seq[Caller] = - if (callers.isEmpty) callers - else { - val head = callers.head - val m = head.caller - if (m.organization != fakeCallerOrganization) callers - else { - // likely the caller is generated using the above summarizeCallers - val s = URLDecoder.decode(m.name, "UTF-8") - s.split(";").toList map { x => - x.split(":").toList match { - case List(organization, name, revision) => - val caller = ModuleID(organization, name, revision) - new Caller( - caller, head.callerConfigurations, head.callerExtraAttributes, - head.isForceDependency, head.isChangingDependency, - head.isTransitiveDependency, head.isDirectlyForceDependency - ) - case xs => sys.error(s"Unexpected caller $xs") - } - } + val nonArtificial = callers filter { c => + (c.caller.organization != sbtOrgTemp) && + (c.caller.organization != fakeCallerOrganization) } + val interProj = (callers filter { c => + (c.caller.organization == sbtOrgTemp) + }).headOption.toList + interProj ::: nonArtificial.toList } def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index ce8ddf8cb..2a2b83b86 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -26,7 +26,7 @@ import scala.concurrent.duration._ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) - def sbtOrgTemp = "org.scala-sbt.temp" + def sbtOrgTemp = JsonUtil.sbtOrgTemp def graphVersion = "0.13.9B" val buildStartup: Long = System.currentTimeMillis lazy val todayStr: String = toYyyymmdd(buildStartup) @@ -398,7 +398,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // group by takes up too much memory. trading space with time. val orgNamePairs = (reports0 map { oar => (oar.organization, oar.name) }).distinct // this might take up some memory, but it's limited to a single - val reports1 = reports0 map { recoverCallers } + val reports1 = reports0 map { filterOutCallers } val allModules: ListMap[(String, String), Vector[OrganizationArtifactReport]] = ListMap(orgNamePairs map { case (organization, name) => @@ -447,26 +447,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }) } val sorted = sortModules(allModules, 0) - val result = resolveConflicts(sorted.toList) map { summarizeCallers } + val result = resolveConflicts(sorted.toList) result.toVector } - def recoverCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = + def filterOutCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = OrganizationArtifactReport( report0.organization, report0.name, report0.modules map { mr => - val original = JsonUtil.unsummarizeCallers(mr.callers) // https://github.com/sbt/sbt/issues/1763 - mr.copy(callers = original filter { c => - (c.caller.organization != sbtOrgTemp) && - (c.caller.organization != JsonUtil.fakeCallerOrganization) - }) + mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers)) }) - def summarizeCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = - OrganizationArtifactReport( - report0.organization, - report0.name, - report0.modules map { mr => mr.copy(callers = JsonUtil.summarizeCallers(mr.callers)) }) /** * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). From 63cfbb49e20315ea7726bc37f543ec4477c041ed Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Wed, 15 Jul 2015 10:01:11 +0200 Subject: [PATCH 0426/1030] Find most specific version of compiler interface sources This commit introduces a mechanism that allows sbt to find the most specific version of the compiler interface sources that exists using Ivy. For instance, when asked for a compiler interface for Scala 2.11.8-M2, sbt will look for sources for: - 2.11.8-M2 ; - 2.11.8 ; - 2.11 ; - the default sources. This commit also modifies the build definition by removing the precompiled projects and configuring the compiler-interface project so that it publishes its source artifacts in a Maven-friendly format. --- ivy/src/main/scala/sbt/ComponentManager.scala | 5 ++++- ivy/src/main/scala/sbt/Configuration.scala | 1 + ivy/src/main/scala/sbt/VersionNumber.scala | 5 +++++ ivy/src/test/scala/VersionNumberSpec.scala | 20 ++++++++++++++++++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ComponentManager.scala b/ivy/src/main/scala/sbt/ComponentManager.scala index 2d6c5a447..bdf78b9ec 100644 --- a/ivy/src/main/scala/sbt/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/ComponentManager.scala @@ -39,6 +39,8 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr d() if (d.cache) cache(id) getOrElse(notFound) + case f: IfMissing.Fallback => + f() } lockLocalCache { getOrElse(fromGlobal) } @@ -73,6 +75,7 @@ sealed trait IfMissing extends NotNull object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } + final class Fallback(f: => Iterable[File]) extends IfMissing { def apply() = f } } object ComponentManager { lazy val (version, timestamp) = @@ -86,4 +89,4 @@ object ComponentManager { import java.net.URL private def versionResource: URL = getClass.getResource("/xsbt.version.properties") -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/ivy/src/main/scala/sbt/Configuration.scala index d666b32bc..d2307b89d 100644 --- a/ivy/src/main/scala/sbt/Configuration.scala +++ b/ivy/src/main/scala/sbt/Configuration.scala @@ -44,6 +44,7 @@ object Configurations { lazy val ScalaTool = config("scala-tool") hide lazy val CompilerPlugin = config("plugin") hide + lazy val Component = config("component") hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) diff --git a/ivy/src/main/scala/sbt/VersionNumber.scala b/ivy/src/main/scala/sbt/VersionNumber.scala index 182d44edc..a5d1d494b 100644 --- a/ivy/src/main/scala/sbt/VersionNumber.scala +++ b/ivy/src/main/scala/sbt/VersionNumber.scala @@ -13,6 +13,11 @@ final class VersionNumber private[sbt] ( else Some(numbers(idx)) def size: Int = numbers.size + /** The vector of version numbers from more to less specific from this version number. */ + lazy val cascadingVersions: Vector[VersionNumber] = + (Vector(this) ++ + (numbers.inits filter (_.length >= 2) map (VersionNumber(_, Nil, Nil)))).distinct + private[this] val versionStr: String = numbers.mkString(".") + (tags match { diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/ivy/src/test/scala/VersionNumberSpec.scala index 7b836050f..68bc2ad6e 100644 --- a/ivy/src/test/scala/VersionNumberSpec.scala +++ b/ivy/src/test/scala/VersionNumberSpec.scala @@ -10,15 +10,18 @@ class VersionNumberSpec extends Specification { 1 should ${beParsedAs("1", Seq(1), Seq(), Seq())} ${breakDownTo("1", Some(1))} + ${generateCorrectCascadingNumbers("1", Seq("1"))} 1.0 should ${beParsedAs("1.0", Seq(1, 0), Seq(), Seq())} ${breakDownTo("1.0", Some(1), Some(0))} + ${generateCorrectCascadingNumbers("1.0", Seq("1.0"))} 1.0.0 should ${beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq())} ${breakDownTo("1.0.0", Some(1), Some(0), Some(0))} - + ${generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0"))} + ${beSemVerCompatWith("1.0.0", "1.0.1")} ${beSemVerCompatWith("1.0.0", "1.1.1")} ${notBeSemVerCompatWith("1.0.0", "2.0.0")} @@ -32,10 +35,12 @@ class VersionNumberSpec extends Specification { 1.0.0.0 should ${beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq())} ${breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0))} + ${generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0"))} 0.12.0 should ${beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq())} ${breakDownTo("0.12.0", Some(0), Some(12), Some(0))} + ${generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12"))} ${notBeSemVerCompatWith("0.12.0", "0.12.0-RC1")} ${notBeSemVerCompatWith("0.12.0", "0.12.1")} @@ -47,6 +52,7 @@ class VersionNumberSpec extends Specification { 0.1.0-SNAPSHOT should ${beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))} ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} ${notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0")} @@ -58,15 +64,20 @@ class VersionNumberSpec extends Specification { 0.1.0-M1 should ${beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-M1", Seq("0.1.0-M1", "0.1.0", "0.1"))} 0.1.0-RC1 should ${beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-RC1", Seq("0.1.0-RC1", "0.1.0", "0.1"))} 0.1.0-MSERVER-1 should ${beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())} + ${generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))} + 2.10.4-20140115-000117-b3a-sources should ${beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())} + ${generateCorrectCascadingNumbers("2.10.4-20140115-000117-b3a-sources", Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))} ${beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} @@ -74,12 +85,15 @@ class VersionNumberSpec extends Specification { 20140115000117-b3a-sources should ${beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq())} + ${generateCorrectCascadingNumbers("20140115000117-b3a-sources", Seq("20140115000117-b3a-sources"))} 1.0.0-alpha+001+002 should ${beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))} + ${generateCorrectCascadingNumbers("1.0.0-alpha+001+002", Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))} non.space.!?string should ${beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string"))} + ${generateCorrectCascadingNumbers("non.space.!?string", Seq("non.space.!?string"))} space !?string should ${beParsedAsError("space !?string")} @@ -119,4 +133,8 @@ class VersionNumberSpec extends Specification { VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true def notBeSecSegCompatWith(v1: String, v2: String) = VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false + def generateCorrectCascadingNumbers(s: String, ns: Seq[String]) = { + val versionNumbers = ns.toVector map VersionNumber.apply + VersionNumber(s).cascadingVersions must_== versionNumbers + } } From fd9644dc5df9bdc25042d616823621cfe232f3ba Mon Sep 17 00:00:00 2001 From: Pierre DAL-PRA Date: Fri, 17 Jul 2015 08:30:13 +0200 Subject: [PATCH 0427/1030] Fix several warnings --- ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala index 486d8b7bd..4e2cb1fc2 100644 --- a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala @@ -109,7 +109,7 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = confs foreach dd.addConfiguration - private[this] def concat[T: ClassManifest](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray + private[this] def concat[T: reflect.ClassTag](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) From a1ac6c6eaae0ca16ecd70e3532e81173697fcea3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 18 Jul 2015 02:17:25 -0400 Subject: [PATCH 0428/1030] Fixes #2105/#1763. Cached resolution: removes duplicate callers during merge --- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 6 ++++-- ivy/src/test/scala/BaseIvySpecification.scala | 5 +++++ ivy/src/test/scala/CachedResolutionSpec.scala | 4 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 2a2b83b86..07a157107 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -27,7 +27,7 @@ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = ModuleRevisionId.newInstance(organization, name, revision) def sbtOrgTemp = JsonUtil.sbtOrgTemp - def graphVersion = "0.13.9B" + def graphVersion = "0.13.9C" val buildStartup: Long = System.currentTimeMillis lazy val todayStr: String = toYyyymmdd(buildStartup) lazy val tomorrowStr: String = toYyyymmdd(buildStartup + (1 day).toMillis) @@ -470,8 +470,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def mergeModuleReports(org: String, name: String, version: String, xs: Seq[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } + // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. + val distinctByModuleId = allCallers.groupBy({ _.caller }).toList map { case (k, xs) => xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct - xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = allCallers) + xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = distinctByModuleId) } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { case ((org, name, version), xs) => diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 385c3abce..55efa60fa 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -59,6 +59,11 @@ trait BaseIvySpecification extends Specification { IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } + def cleanIvyCache: Unit = + { + IO.delete(currentTarget / "cache") + } + def cleanCachedResolutionCache(module: IvySbt#Module): Unit = { IvyActions.cleanCachedResolutionCache(module, log) diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala index a64fcb8c8..16021b15c 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -28,6 +28,7 @@ class CachedResolutionSpec extends BaseIvySpecification { import ShowLines._ def e1 = { + cleanIvyCache val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) val report = ivyUpdate(m) @@ -65,7 +66,8 @@ class CachedResolutionSpec extends BaseIvySpecification { // avro:1.4.0 will be evicted by avro:1.7.7. // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final def e3 = { - log.setLevel(Level.Debug) + // log.setLevel(Level.Debug) + cleanIvyCache val m = module(ModuleID("com.example", "foo", "0.3.0", Some("compile")), Seq(avro177, dataAvro1940, netty320), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) From 92202d435317e9c0c104346d85e1bdd77f2805ae Mon Sep 17 00:00:00 2001 From: Josh Suereth Date: Fri, 24 Jul 2015 10:42:49 -0400 Subject: [PATCH 0429/1030] Add warning to MakePom for intransitive dependencies. Intransitive does not work in Maven, and does not translate to pom.xml. --- ivy/src/main/scala/sbt/MakePom.scala | 37 +++++++++++++++++----------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 1dfa5d1fe..530070dda 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -236,21 +236,30 @@ class MakePom(val log: Logger) { def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = makeDependency(dependency, includeTypes, Nil) - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = - { - val artifacts = dependency.getAllDependencyArtifacts - val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) - if (artifacts.isEmpty) { - val configs = dependency.getModuleConfigurations - if (configs.filterNot(Set("sources", "docs")).nonEmpty) { - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None, excludes) - } else NodeSeq.Empty - } else if (includeArtifacts.isEmpty) - NodeSeq.Empty - else - NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = { + def warnIntransitve(): Unit = + if (!dependency.isTransitive) + log.warn( + s"""Translating intransitive dependency (${dependency.getDependencyId}) into pom.xml, but maven does not support intransitive dependencies. + | Please use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. + """.stripMargin) + else () + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if (artifacts.isEmpty) { + val configs = dependency.getModuleConfigurations + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + warnIntransitve() + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None, excludes) + } else NodeSeq.Empty + } else if (includeArtifacts.isEmpty) { + NodeSeq.Empty + } else { + warnIntransitve() + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) } + } @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = From e5ac8316a7cd511d728fbffc6c09f5b5c3133b37 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 25 Jul 2015 17:38:11 -0400 Subject: [PATCH 0430/1030] make sortModules tailrec --- .../sbt/ivyint/CachedResolutionResolveEngine.scala | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 07a157107..0bf2467b8 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -407,9 +407,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }: _*) val stackGuard = reports0.size * reports0.size * 2 // sort the all modules such that less called modules comes earlier - def sortModules(cs: ListMap[(String, String), Vector[OrganizationArtifactReport]], + @tailrec def sortModules(cs: ListMap[(String, String), Vector[OrganizationArtifactReport]], + acc: ListMap[(String, String), Vector[OrganizationArtifactReport]], n: Int): ListMap[(String, String), Vector[OrganizationArtifactReport]] = { + println(s"sortModules: $n / $stackGuard") val keys = cs.keySet val (called, notCalled) = cs partition { case (k, oas) => @@ -422,9 +424,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } } } - notCalled ++ - (if (called.isEmpty || n > stackGuard) called - else sortModules(called, n + 1)) + (if (called.isEmpty || n > stackGuard) acc ++ notCalled ++ called + else sortModules(called, acc ++ notCalled, n + 1)) } def resolveConflicts(cs: List[((String, String), Vector[OrganizationArtifactReport])]): List[OrganizationArtifactReport] = cs match { @@ -446,7 +447,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { x :: resolveConflicts(next) }) } - val sorted = sortModules(allModules, 0) + val sorted = sortModules(allModules, ListMap(), 0) val result = resolveConflicts(sorted.toList) result.toVector } From ddf941f3713a7de6985bdd2dd00f4a31a65127fe Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 25 Jul 2015 22:40:18 -0400 Subject: [PATCH 0431/1030] refactored to use less stack space --- .../CachedResolutionResolveEngine.scala | 97 +++++++++++-------- ivy/src/test/scala/CachedResolutionSpec.scala | 3 +- 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 0bf2467b8..037ab4664 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -396,59 +396,68 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = { // group by takes up too much memory. trading space with time. - val orgNamePairs = (reports0 map { oar => (oar.organization, oar.name) }).distinct + val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct // this might take up some memory, but it's limited to a single val reports1 = reports0 map { filterOutCallers } - val allModules: ListMap[(String, String), Vector[OrganizationArtifactReport]] = - ListMap(orgNamePairs map { + val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = + Map(orgNamePairs map { case (organization, name) => val xs = reports1 filter { oar => oar.organization == organization && oar.name == name } ((organization, name), xs) }: _*) - val stackGuard = reports0.size * reports0.size * 2 // sort the all modules such that less called modules comes earlier - @tailrec def sortModules(cs: ListMap[(String, String), Vector[OrganizationArtifactReport]], - acc: ListMap[(String, String), Vector[OrganizationArtifactReport]], - n: Int): ListMap[(String, String), Vector[OrganizationArtifactReport]] = + @tailrec def sortModules(cs: Vector[(String, String)], + acc: Vector[(String, String)], + n: Int, guard: Int): Vector[(String, String)] = { - println(s"sortModules: $n / $stackGuard") - val keys = cs.keySet - val (called, notCalled) = cs partition { - case (k, oas) => - oas exists { - _.modules.exists { - _.callers exists { caller => - val m = caller.caller - keys((m.organization, m.name)) - } + // println(s"sortModules: $n / $guard") + val keys = cs.toSet + val (called, notCalled) = cs partition { k => + val reports = allModules0(k) + reports exists { + _.modules.exists { + _.callers exists { caller => + val m = caller.caller + keys((m.organization, m.name)) } } + } } - (if (called.isEmpty || n > stackGuard) acc ++ notCalled ++ called - else sortModules(called, acc ++ notCalled, n + 1)) + lazy val result0 = acc ++ notCalled ++ called + (if (n > guard) { + log.warn(s"""cached resolution detected circular dependencies: ${cs.mkString(",")}""") + result0 + } else if (called.isEmpty || notCalled.isEmpty) result0 + else sortModules(called, acc ++ notCalled, 0, called.size * called.size + 1)) } - def resolveConflicts(cs: List[((String, String), Vector[OrganizationArtifactReport])]): List[OrganizationArtifactReport] = + def resolveConflicts(cs: List[(String, String)], + allModules: Map[(String, String), Vector[OrganizationArtifactReport]]): List[OrganizationArtifactReport] = cs match { case Nil => Nil - case (k, Vector()) :: rest => resolveConflicts(rest) - case (k, Vector(oa)) :: rest if (oa.modules.size == 0) => resolveConflicts(rest) - case (k, Vector(oa)) :: rest if (oa.modules.size == 1 && !oa.modules.head.evicted) => - log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") - oa :: resolveConflicts(rest) - case ((organization, name), oas) :: rest => - (mergeModuleReports(rootModuleConf, oas flatMap { _.modules }, os, log) match { - case (survivor, newlyEvicted) => - val evicted = (survivor ++ newlyEvicted) filter { m => m.evicted } - val notEvicted = (survivor ++ newlyEvicted) filter { m => !m.evicted } - log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) - log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) - val x = new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) - val next = transitivelyEvict(rootModuleConf, rest, evicted, log) - x :: resolveConflicts(next) - }) + case (organization, name) :: rest => + val reports = allModules((organization, name)) + reports match { + case Vector() => resolveConflicts(rest, allModules) + case Vector(oa) if (oa.modules.size == 0) => resolveConflicts(rest, allModules) + case Vector(oa) if (oa.modules.size == 1 && !oa.modules.head.evicted) => + log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") + oa :: resolveConflicts(rest, allModules) + case oas => + (mergeModuleReports(rootModuleConf, oas flatMap { _.modules }, os, log) match { + case (survivor, newlyEvicted) => + val evicted = (survivor ++ newlyEvicted) filter { m => m.evicted } + val notEvicted = (survivor ++ newlyEvicted) filter { m => !m.evicted } + log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) + log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) + val x = new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) + val nextModules = transitivelyEvict(rootModuleConf, rest, allModules, evicted, log) + x :: resolveConflicts(rest, nextModules) + }) + } } - val sorted = sortModules(allModules, ListMap(), 0) - val result = resolveConflicts(sorted.toList) + val guard0 = (orgNamePairs.size * orgNamePairs.size) + 1 + val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), 0, guard0) + val result = resolveConflicts(sorted.toList, allModules0) result.toVector } def filterOutCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = @@ -491,13 +500,15 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { /** * This transitively evicts any non-evicted modules whose only callers are newly evicted. */ - def transitivelyEvict(rootModuleConf: String, reports0: List[((String, String), Vector[OrganizationArtifactReport])], - evicted0: Vector[ModuleReport], log: Logger): List[((String, String), Vector[OrganizationArtifactReport])] = + def transitivelyEvict(rootModuleConf: String, pairs: List[(String, String)], + reports0: Map[(String, String), Vector[OrganizationArtifactReport]], + evicted0: Vector[ModuleReport], log: Logger): Map[(String, String), Vector[OrganizationArtifactReport]] = { val em = (evicted0 map { _.module }).toSet def isTransitivelyEvicted(mr: ModuleReport): Boolean = mr.callers forall { c => em(c.caller) } - val reports: List[((String, String), Vector[OrganizationArtifactReport])] = reports0 map { + val reports: Seq[((String, String), Vector[OrganizationArtifactReport])] = reports0.toSeq flatMap { + case (k, v) if !(pairs contains k) => Seq() case ((organization, name), oars0) => val oars = oars0 map { oar => val (affected, unaffected) = oar.modules partition { mr => @@ -511,9 +522,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { if (affected.isEmpty) oar else new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) } - ((organization, name), oars) + Seq(((organization, name), oars)) } - reports + Map(reports: _*) } /** * resolves dependency resolution conflicts in which multiple candidates are found for organization+name combos. diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala index 16021b15c..1860b3ed8 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -77,6 +77,7 @@ class CachedResolutionSpec extends BaseIvySpecification { // second resolution reads from the minigraph val report = ivyUpdate(m) val modules = report.configurations.head.modules - modules must containMatch("""org\.jboss\.netty:netty:3\.2\.0.Final""") + (modules must containMatch("""org\.jboss\.netty:netty:3\.2\.0.Final""")) and + (modules must not containMatch ("""org\.jboss\.netty:netty:3\.2\.1.Final""")) } } From 4e69d04be854205e04ae5c51e148297e8d06012b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Jul 2015 23:19:16 -0400 Subject: [PATCH 0432/1030] try breaking circular dependency and continue sorting --- .../ivyint/CachedResolutionResolveEngine.scala | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 037ab4664..7a9c35269 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -407,7 +407,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }: _*) // sort the all modules such that less called modules comes earlier @tailrec def sortModules(cs: Vector[(String, String)], - acc: Vector[(String, String)], + acc: Vector[(String, String)], extra: Vector[(String, String)], n: Int, guard: Int): Vector[(String, String)] = { // println(s"sortModules: $n / $guard") @@ -423,12 +423,18 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } } } - lazy val result0 = acc ++ notCalled ++ called + lazy val result0 = acc ++ notCalled ++ called ++ extra + def warnCircular(): Unit = { + log.warn(s"""avoid circular dependency while using cached resolution: ${cs.mkString(",")}""") + } (if (n > guard) { - log.warn(s"""cached resolution detected circular dependencies: ${cs.mkString(",")}""") + warnCircular result0 - } else if (called.isEmpty || notCalled.isEmpty) result0 - else sortModules(called, acc ++ notCalled, 0, called.size * called.size + 1)) + } else if (called.isEmpty) result0 + else if (notCalled.isEmpty) { + warnCircular + sortModules(cs.tail, acc, extra :+ cs.head, n + 1, guard) + } else sortModules(called, acc ++ notCalled, extra, 0, called.size * called.size + 1)) } def resolveConflicts(cs: List[(String, String)], allModules: Map[(String, String), Vector[OrganizationArtifactReport]]): List[OrganizationArtifactReport] = @@ -456,7 +462,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } } val guard0 = (orgNamePairs.size * orgNamePairs.size) + 1 - val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), 0, guard0) + val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), Vector(), 0, guard0) val result = resolveConflicts(sorted.toList, allModules0) result.toVector } From e528f3d163f01360823c159e5177f25fcc4170ae Mon Sep 17 00:00:00 2001 From: Pierre DAL-PRA Date: Sat, 1 Aug 2015 02:19:25 +0200 Subject: [PATCH 0433/1030] Simplify operations on collections --- ivy/src/main/scala/sbt/JsonUtil.scala | 6 +++--- ivy/src/main/scala/sbt/MakePom.scala | 4 ++-- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/ivy/src/main/scala/sbt/JsonUtil.scala index e3983e7b4..d4db781f7 100644 --- a/ivy/src/main/scala/sbt/JsonUtil.scala +++ b/ivy/src/main/scala/sbt/JsonUtil.scala @@ -50,9 +50,9 @@ private[sbt] object JsonUtil { (c.caller.organization != sbtOrgTemp) && (c.caller.organization != fakeCallerOrganization) } - val interProj = (callers filter { c => - (c.caller.organization == sbtOrgTemp) - }).headOption.toList + val interProj = (callers find { c => + c.caller.organization == sbtOrgTemp + }).toList interProj ::: nonArtificial.toList } diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 530070dda..81121bf7f 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -248,7 +248,7 @@ class MakePom(val log: Logger) { val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) if (artifacts.isEmpty) { val configs = dependency.getModuleConfigurations - if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + if (!configs.forall(Set("sources", "docs"))) { warnIntransitve() val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) makeDependencyElem(dependency, scope, optional, None, None, excludes) @@ -271,7 +271,7 @@ class MakePom(val log: Logger) { case Nil | "*" :: Nil => dependency.getModuleConfigurations case x => x.toArray } - if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + if (!configs.forall(Set("sources", "docs"))) { val (scope, optional) = getScopeAndOptional(configs) val classifier = artifactClassifier(artifact) val baseType = artifactType(artifact) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 07a157107..5052a46ef 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -430,7 +430,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { cs match { case Nil => Nil case (k, Vector()) :: rest => resolveConflicts(rest) - case (k, Vector(oa)) :: rest if (oa.modules.size == 0) => resolveConflicts(rest) + case (k, Vector(oa)) :: rest if (oa.modules.isEmpty) => resolveConflicts(rest) case (k, Vector(oa)) :: rest if (oa.modules.size == 1 && !oa.modules.head.evicted) => log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") oa :: resolveConflicts(rest) From ec71256040739d048867f9517a6dcc2c4edfb489 Mon Sep 17 00:00:00 2001 From: Pierre DAL-PRA Date: Sat, 1 Aug 2015 12:05:35 +0200 Subject: [PATCH 0434/1030] Remove redundant collection conversions --- ivy/src/main/scala/sbt/IvyRetrieve.scala | 8 ++++---- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 4 ++-- ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/ivy/src/main/scala/sbt/IvyRetrieve.scala index f453efb1f..14ad917fa 100644 --- a/ivy/src/main/scala/sbt/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/IvyRetrieve.scala @@ -74,7 +74,7 @@ object IvyRetrieve { }: _*) def toCaller(caller: IvyCaller): Caller = { val m = toModuleID(caller.getModuleRevisionId) - val callerConfigurations = caller.getCallerConfigurations.toArray.toVector collect { + val callerConfigurations = caller.getCallerConfigurations.toVector collect { case x if nonEmptyString(x).isDefined => x } val ddOpt = Option(caller.getDependencyDescriptor) @@ -128,16 +128,16 @@ object IvyRetrieve { case _ => dep.getResolvedId.getExtraAttributes }) val isDefault = Option(dep.getDescriptor) map { _.isDefault } - val configurations = dep.getConfigurations(confReport.getConfiguration).toArray.toList + val configurations = dep.getConfigurations(confReport.getConfiguration).toList val licenses: Seq[(String, Option[String])] = mdOpt match { - case Some(md) => md.getLicenses.toArray.toVector collect { + case Some(md) => md.getLicenses.toVector collect { case lic: IvyLicense if Option(lic.getName).isDefined => val temporaryURL = "http://localhost" (lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) }) } case _ => Nil } - val callers = dep.getCallers(confReport.getConfiguration).toArray.toVector map { toCaller } + val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) new ModuleReport(moduleId, resolved, missing, status, publicationDate, resolver, artifactResolver, diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 5052a46ef..049130132 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -57,7 +57,7 @@ private[sbt] class CachedResolutionResolveCache() { { log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") // val expanded = expandInternalDependencies(md0, data, prOpt, log) - val rootModuleConfigs = md0.getConfigurations.toArray.toVector + val rootModuleConfigs = md0.getConfigurations.toVector directDependencies(md0) map { dd => val arts = dd.getAllDependencyArtifacts.toVector map { x => s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } log.debug(s"::: dd: $dd (artifacts: ${arts.mkString(",")})") @@ -599,7 +599,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case None => Vector() } // These are the configurations from the original project we want to resolve. - val rootModuleConfs = md0.getConfigurations.toArray.toVector + val rootModuleConfs = md0.getConfigurations.toVector val configurations0 = ur.configurations.toVector // This is how md looks from md0 via dd's mapping. val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => diff --git a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala index 4e2cb1fc2..76bb4d2af 100644 --- a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala @@ -109,7 +109,7 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = confs foreach dd.addConfiguration - private[this] def concat[T: reflect.ClassTag](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct.toArray + private[this] def concat[T: reflect.ClassTag](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) From 71faf889163044931a07e45b17ae6ccc59ef4cfd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 3 Aug 2015 07:31:32 -0400 Subject: [PATCH 0435/1030] Fixes #2129. break up circular dependency loops in cached resolution Simple remove-one method to workaround for circular dependency did not work. This fix traverses the entire graph to detect all loops and then breaks them up. --- .../CachedResolutionResolveEngine.scala | 75 ++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 7a9c35269..bae20ec75 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -405,6 +405,77 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val xs = reports1 filter { oar => oar.organization == organization && oar.name == name } ((organization, name), xs) }: _*) + // this returns a List of Lists of (org, name). should be deterministic + def detectLoops(allModules: Map[(String, String), Vector[OrganizationArtifactReport]]): List[List[(String, String)]] = + { + val loopSets: mutable.Set[Set[(String, String)]] = mutable.Set.empty + val loopLists: mutable.ListBuffer[List[(String, String)]] = mutable.ListBuffer.empty + def testLoop(m: (String, String), current: (String, String), history: List[(String, String)]): Unit = + { + val callers = + (for { + oar <- allModules.getOrElse(current, Vector()) + mr <- oar.modules + c <- mr.callers + } yield (c.caller.organization, c.caller.name)).distinct + callers foreach { c => + if (history contains c) { + val loop = (c :: history.takeWhile(_ != c)) ::: List(c) + if (!loopSets(loop.toSet)) { + loopSets += loop.toSet + loopLists += loop + val loopStr = (loop map { case (o, n) => s"$o:$n" }).mkString("->") + log.warn(s"""avoid circular dependency while using cached resolution: $loopStr""") + } + } else testLoop(m, c, c :: history) + } + } + orgNamePairs map { orgname => + testLoop(orgname, orgname, List(orgname)) + } + loopLists.toList + } + @tailrec def breakLoops(loops: List[List[(String, String)]], + allModules1: Map[(String, String), Vector[OrganizationArtifactReport]]): Map[(String, String), Vector[OrganizationArtifactReport]] = + loops match { + case Nil => + allModules1 + case loop :: rest => + loop match { + case Nil => + breakLoops(rest, allModules1) + case loop => + val sortedLoop = loop sortBy { x => + (for { + oar <- allModules0(x) + mr <- oar.modules + c <- mr.callers + } yield c).size + } + val moduleWithMostCallers = sortedLoop.reverse.head + val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1) + // remove the module with most callers as the caller of next. + // so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed. + val nextMap = allModules1 map { + case (k: (String, String), oars0) if k == next => + val oars: Vector[OrganizationArtifactReport] = oars0 map { oar => + val mrs = oar.modules map { mr => + val callers0 = mr.callers + val callers = callers0 filterNot { c => (c.caller.organization, c.caller.name) == moduleWithMostCallers } + if (callers.size == callers0.size) mr + else mr.copy(callers = callers) + } + OrganizationArtifactReport(oar.organization, oar.name, mrs) + } + (k, oars) + case (k, v) => (k, v) + } + breakLoops(rest, nextMap) + } + } + val loop = detectLoops(allModules0) + log.debug(s":: $rootModuleConf: loop: $loop") + val allModules2 = breakLoops(loop, allModules0) // sort the all modules such that less called modules comes earlier @tailrec def sortModules(cs: Vector[(String, String)], acc: Vector[(String, String)], extra: Vector[(String, String)], @@ -413,7 +484,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // println(s"sortModules: $n / $guard") val keys = cs.toSet val (called, notCalled) = cs partition { k => - val reports = allModules0(k) + val reports = allModules2(k) reports exists { _.modules.exists { _.callers exists { caller => @@ -425,7 +496,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } lazy val result0 = acc ++ notCalled ++ called ++ extra def warnCircular(): Unit = { - log.warn(s"""avoid circular dependency while using cached resolution: ${cs.mkString(",")}""") + log.warn(s"""unexpected circular dependency while using cached resolution: ${cs.mkString(",")}""") } (if (n > guard) { warnCircular From fb2ccdd285eb324fa7e25b94c0636019dc0effdc Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 3 Aug 2015 08:17:48 -0400 Subject: [PATCH 0436/1030] Add debug logs --- .../scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index bae20ec75..73b0ec6fc 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -463,7 +463,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val callers0 = mr.callers val callers = callers0 filterNot { c => (c.caller.organization, c.caller.name) == moduleWithMostCallers } if (callers.size == callers0.size) mr - else mr.copy(callers = callers) + else { + log.debug(s":: $rootModuleConf: removing caller $moduleWithMostCallers -> $next for sorting") + mr.copy(callers = callers) + } } OrganizationArtifactReport(oar.organization, oar.name, mrs) } @@ -534,6 +537,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val guard0 = (orgNamePairs.size * orgNamePairs.size) + 1 val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), Vector(), 0, guard0) + val sortedStr = (sorted map { case (o, n) => s"$o:$n" }).mkString(", ") + log.debug(s":: sort result: $sortedStr") val result = resolveConflicts(sorted.toList, allModules0) result.toVector } From d3dc1736e7d275a248723539351b2b49211820c2 Mon Sep 17 00:00:00 2001 From: Pierre DAL-PRA Date: Mon, 3 Aug 2015 23:13:59 +0200 Subject: [PATCH 0437/1030] Replace procedure syntax by explicit Unit annotation --- .../ReplaceMavenConfigurationMappings.scala | 12 +++---- ivy/src/main/scala/sbt/ConflictWarning.scala | 4 +-- ivy/src/main/scala/sbt/ConvertResolver.scala | 10 +++--- ivy/src/main/scala/sbt/CustomXmlParser.scala | 6 ++-- ivy/src/main/scala/sbt/Ivy.scala | 24 ++++++------- ivy/src/main/scala/sbt/IvyActions.scala | 8 ++--- ivy/src/main/scala/sbt/IvyCache.scala | 8 ++--- ivy/src/main/scala/sbt/IvyLogger.scala | 34 +++++++++---------- ivy/src/main/scala/sbt/IvyScala.scala | 10 +++--- ivy/src/main/scala/sbt/MakePom.scala | 3 +- ivy/src/main/scala/sbt/ProjectResolver.scala | 14 ++++---- ivy/src/main/scala/sbt/ResolutionCache.scala | 6 ++-- ivy/src/main/scala/sbt/StringUtilities.scala | 4 +-- .../ivyint/ErrorMessageAuthenticator.scala | 4 +-- 14 files changed, 72 insertions(+), 75 deletions(-) diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index 0e85d5b6b..e59bd174e 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -38,7 +38,7 @@ object ReplaceMavenConfigurationMappings { // NOTE - This code is copied from org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder // except with altered default configurations... REPLACEMENT_MAPPINGS.put("compile", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. @@ -52,7 +52,7 @@ object ReplaceMavenConfigurationMappings { } }) REPLACEMENT_MAPPINGS.put("provided", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") dd.addDependencyConfiguration("optional", "provided(*)") @@ -70,7 +70,7 @@ object ReplaceMavenConfigurationMappings { }) REPLACEMENT_MAPPINGS.put("runtime", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { if (isOptional) { dd.addDependencyConfiguration("optional", "compile(*)") dd.addDependencyConfiguration("optional", "provided(*)") @@ -86,7 +86,7 @@ object ReplaceMavenConfigurationMappings { }) REPLACEMENT_MAPPINGS.put("test", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { dd.addDependencyConfiguration("test", "runtime(*)") // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("test", "master(compile)") @@ -94,7 +94,7 @@ object ReplaceMavenConfigurationMappings { }) REPLACEMENT_MAPPINGS.put("system", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean) { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. dd.addDependencyConfiguration("system", "master(compile)") } @@ -115,4 +115,4 @@ object ReplaceMavenConfigurationMappings { throw new RuntimeException("FAILURE to install Ivy maven hooks. Your ivy-maven interaction may suffer resolution errors", e) } } -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/ivy/src/main/scala/sbt/ConflictWarning.scala index 082a478b6..a4e011736 100644 --- a/ivy/src/main/scala/sbt/ConflictWarning.scala +++ b/ivy/src/main/scala/sbt/ConflictWarning.scala @@ -28,10 +28,10 @@ object ConflictWarning { @deprecated("Warning on evicted modules is no longer done, so this is the same as `default`. Use a standard Ivy conflict manager.", "0.13.0") def strict(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - def apply(config: ConflictWarning, report: UpdateReport, log: Logger) { + def apply(config: ConflictWarning, report: UpdateReport, log: Logger): Unit = { processCrossVersioned(config, report, log) } - private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger) { + private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger): Unit = { val crossMismatches = crossVersionMismatches(report) if (crossMismatches.nonEmpty) { val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/ivy/src/main/scala/sbt/ConvertResolver.scala index a01a51380..9768241d5 100644 --- a/ivy/src/main/scala/sbt/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/ConvertResolver.scala @@ -113,7 +113,7 @@ private[sbt] object ConvertResolver { { val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns() { + def setPatterns(): Unit = { // done this way for access to protected methods. setArtifactPatterns(pattern) setIvyPatterns(pattern) @@ -189,18 +189,18 @@ private[sbt] object ConvertResolver { def hasExplicitURL(dd: DependencyDescriptor): Boolean = dd.getAllDependencyArtifacts.exists(_.getUrl != null) } - private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String) { + private def initializeMavenStyle(resolver: IBiblioResolver, name: String, root: String): Unit = { resolver.setName(name) resolver.setM2compatible(true) resolver.setRoot(root) } - private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings) { + private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings): Unit = { resolver.setName(repo.name) resolver.setPassfile(null) initializePatterns(resolver, repo.patterns, settings) initializeConnection(resolver, repo.connection) } - private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection) { + private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection): Unit = { import resolver._ import connection._ hostname.foreach(setHost) @@ -216,7 +216,7 @@ private[sbt] object ConvertResolver { setUser(user) } } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings) { + private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings): Unit = { resolver.setM2compatible(patterns.isMavenCompatible) resolver.setDescriptor(if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED) resolver.setCheckconsistency(!patterns.skipConsistencyCheck) diff --git a/ivy/src/main/scala/sbt/CustomXmlParser.scala b/ivy/src/main/scala/sbt/CustomXmlParser.scala index c5462070c..bc8d7544b 100644 --- a/ivy/src/main/scala/sbt/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/CustomXmlParser.scala @@ -21,9 +21,9 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { super.setResource(new URLResource(url)) super.setInput(url) } - def setInput(bytes: Array[Byte]) { setInput(new ByteArrayInputStream(bytes)) } + def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes)) /** Overridden because the super implementation overwrites the module descriptor.*/ - override def setResource(res: Resource) {} + override def setResource(res: Resource): Unit = () override def setMd(md: DefaultModuleDescriptor) = { super.setMd(md) @@ -32,4 +32,4 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) } -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/ivy/src/main/scala/sbt/Ivy.scala index 7e4cf3792..e9ac5a23d 100644 --- a/ivy/src/main/scala/sbt/Ivy.scala +++ b/ivy/src/main/scala/sbt/Ivy.scala @@ -231,7 +231,7 @@ final class IvySbt(val configuration: IvyConfiguration) { addScalaToolDependencies(dmd, parser, is) (dmd, parser.getDefaultConf) } - private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala) { + private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala): Unit = { IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) } @@ -257,7 +257,7 @@ private[sbt] object IvySbt { def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) def defaultPOM(project: File) = new File(project, DefaultMavenFilename) - def loadURI(is: IvySettings, uri: URI) { + def loadURI(is: IvySettings, uri: URI): Unit = { if (uri.getScheme == "file") is.load(new File(uri)) // IVY-1114 else @@ -268,7 +268,7 @@ private[sbt] object IvySbt { * Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, updateOptions: UpdateOptions, log: Logger) { + private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, updateOptions: UpdateOptions, log: Logger): Unit = { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") val chain = resolverChain(name, rs, localOnly, settings, updateOptions, log) @@ -304,7 +304,7 @@ private[sbt] object IvySbt { } } - def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger) { + def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger): Unit = { for (r <- resolvers) { log.debug("\t" + r) settings.addResolver(ConvertResolver(r, settings, log)) @@ -320,7 +320,7 @@ private[sbt] object IvySbt { import collection.JavaConversions._ artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") } - private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger) { + private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger): Unit = { val existing = settings.getResolverNames for (moduleConf <- moduleConfigurations) { import moduleConf._ @@ -332,11 +332,11 @@ private[sbt] object IvySbt { settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } } - private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { + private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]): Unit = { configureResolutionCache(settings, localOnly, resCacheDir) configureRepositoryCache(settings, localOnly) } - private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]) { + private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]): Unit = { val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir settings.setResolutionCacheManager(new ResolutionCache(base, settings)) } @@ -385,7 +385,7 @@ private[sbt] object IvySbt { case _ => false } // ignore the original resolver wherever possible to avoid issues like #704 - override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String) {} + override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String): Unit = () } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) @@ -411,12 +411,12 @@ private[sbt] object IvySbt { dmd.addExtraAttributeNamespace("e", "http://ant.apache.org/ivy/extra") /** Adds the ivy.xml main artifact. */ - private def addMainArtifact(moduleID: DefaultModuleDescriptor) { + private def addMainArtifact(moduleID: DefaultModuleDescriptor): Unit = { val artifact = DefaultArtifact.newIvyArtifact(moduleID.getResolvedModuleRevisionId, moduleID.getPublicationDate) moduleID.setModuleArtifact(artifact) moduleID.check() } - private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings) { + private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings): Unit = { val mid = ModuleId.newInstance(conflict.organization, conflict.module) val matcher = is.getMatcher(PatternMatcher.EXACT_OR_REGEXP) val manager = is.getConflictManager(conflict.name) @@ -555,7 +555,7 @@ private[sbt] object IvySbt { } /** This method is used to add inline dependencies to the provided module. */ - def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser) { + def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser): Unit = { val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } val unique = if (hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted unique foreach moduleID.addDependency @@ -579,7 +579,7 @@ private[sbt] object IvySbt { */ def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = { - // need to preserve basic order of dependencies: can't use dependencies.groupBy + // need to preserve basic order of dependencies: can't use dependencies.groupBy val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] for (dd <- dependencies) { val id = dd.getDependencyRevisionId diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/ivy/src/main/scala/sbt/IvyActions.scala index ef2db547e..33436452c 100644 --- a/ivy/src/main/scala/sbt/IvyActions.scala +++ b/ivy/src/main/scala/sbt/IvyActions.scala @@ -61,7 +61,7 @@ object UpdateLogging extends Enumeration { object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ - def install(module: IvySbt#Module, from: String, to: String, log: Logger) { + def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { module.withModule(log) { (ivy, md, default) => for (dependency <- md.getDependencies) { log.info("Installing " + dependency) @@ -89,7 +89,7 @@ object IvyActions { } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger) { + def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): Unit = { import configuration.{ allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes } module.withModule(log) { (ivy, md, default) => (new MakePom(log)).write(ivy, md, moduleInfo, configurations, includeTypes, extra, process, filterRepositories, allRepositories, file) @@ -112,7 +112,7 @@ object IvyActions { def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) - def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger) { + def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger): Unit = { import configuration._ module.withModule(log) { case (ivy, md, default) => @@ -368,7 +368,7 @@ object IvyActions { } } } - private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]) { + private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]): Unit = { val missing = artifacts filter { case (a, file) => !file.exists } if (missing.nonEmpty) sys.error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/ivy/src/main/scala/sbt/IvyCache.scala index 51e02b60c..ce2ddd9f2 100644 --- a/ivy/src/main/scala/sbt/IvyCache.scala +++ b/ivy/src/main/scala/sbt/IvyCache.scala @@ -28,7 +28,7 @@ private object NotInCache { class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ - def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger) { + def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { val artifact = defaultArtifact(moduleID) val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) withDefaultCache(lock, log) { cache => @@ -37,7 +37,7 @@ class IvyCache(val ivyHome: Option[File]) { } } /** Clears the cache of the jar for the given ID.*/ - def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger) { + def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { try { withCachedJar(id, lock, log)(_.delete) } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } @@ -87,11 +87,11 @@ class IvyCache(val ivyHome: Option[File]) { } /** Required by Ivy for copying to the cache.*/ private class FileDownloader extends ResourceDownloader with NotNull { - def download(artifact: IvyArtifact, resource: Resource, dest: File) { + def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { if (dest.exists()) dest.delete() val part = new File(dest.getAbsolutePath + ".part") FileUtil.copy(resource.openStream, part, null) if (!part.renameTo(dest)) sys.error("Could not move temporary file " + part + " to final location " + dest) } -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/IvyLogger.scala b/ivy/src/main/scala/sbt/IvyLogger.scala index 42131a174..94268672e 100644 --- a/ivy/src/main/scala/sbt/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/IvyLogger.scala @@ -7,8 +7,8 @@ import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } /** Interface to Ivy logging. */ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { - def rawlog(msg: String, level: Int) = log(msg, level) - def log(msg: String, level: Int) { + def rawlog(msg: String, level: Int): Unit = log(msg, level) + def log(msg: String, level: Int): Unit = { import Message.{ MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR } level match { case MSG_DEBUG => debug(msg) @@ -20,32 +20,32 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { } //DEBUG level messages are very verbose and rarely useful to users. // TODO: provide access to this information some other way - def debug(msg: String) {} - def verbose(msg: String) = logger.verbose(msg) - def deprecated(msg: String) = warn(msg) - def info(msg: String) = logger.info(msg) - def rawinfo(msg: String) = info(msg) - def warn(msg: String) = logger.warn(msg) - def error(msg: String) = if (SbtIvyLogger.acceptError(msg)) logger.error(msg) + def debug(msg: String): Unit = () + def verbose(msg: String): Unit = logger.verbose(msg) + def deprecated(msg: String): Unit = warn(msg) + def info(msg: String): Unit = logger.info(msg) + def rawinfo(msg: String): Unit = info(msg) + def warn(msg: String): Unit = logger.warn(msg) + def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) logger.error(msg) private def emptyList = java.util.Collections.emptyList[String] def getProblems = emptyList def getWarns = emptyList def getErrors = emptyList - def clearProblems = () - def sumupProblems = clearProblems() - def progress = () - def endProgress = () + def clearProblems(): Unit = () + def sumupProblems(): Unit = clearProblems() + def progress(): Unit = () + def endProgress(): Unit = () - def endProgress(msg: String) = info(msg) + def endProgress(msg: String): Unit = info(msg) def isShowProgress = false - def setShowProgress(progress: Boolean) {} + def setShowProgress(progress: Boolean): Unit = () } private final class SbtMessageLoggerEngine extends MessageLoggerEngine { /** This is a hack to filter error messages about 'unknown resolver ...'. */ - override def error(msg: String) = if (SbtIvyLogger.acceptError(msg)) super.error(msg) - override def sumupProblems = clearProblems() + override def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) super.error(msg) + override def sumupProblems(): Unit = clearProblems() } private object SbtIvyLogger { val UnknownResolver = "unknown resolver" diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/ivy/src/main/scala/sbt/IvyScala.scala index d2697e308..2614df994 100644 --- a/ivy/src/main/scala/sbt/IvyScala.scala +++ b/ivy/src/main/scala/sbt/IvyScala.scala @@ -37,7 +37,7 @@ final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, private object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala) { + def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) checkDependencies(module, check.scalaBinaryVersion, check.configurations, log) if (check.filterImplicit) @@ -45,12 +45,12 @@ private object IvyScala { if (check.overrideScalaVersion) overrideScalaVersion(module, check.scalaFullVersion) } - def overrideScalaVersion(module: DefaultModuleDescriptor, version: String) { + def overrideScalaVersion(module: DefaultModuleDescriptor, version: String): Unit = { overrideVersion(module, Organization, LibraryID, version) overrideVersion(module, Organization, CompilerID, version) overrideVersion(module, Organization, ReflectID, version) } - def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String) { + def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String): Unit = { val id = new ModuleId(org, name) val over = new OverrideDependencyDescriptorMediator(null, version) module.addDependencyDescriptorMediator(id, ExactPatternMatcher.INSTANCE, over) @@ -60,7 +60,7 @@ private object IvyScala { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger) { + private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { @@ -88,7 +88,7 @@ private object IvyScala { * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use * is done by setting scalaVersion in the project definition. */ - private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]) { + private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = { val configurationNames = { val names = module.getConfigurationsNames diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/ivy/src/main/scala/sbt/MakePom.scala index 81121bf7f..e2018612f 100644 --- a/ivy/src/main/scala/sbt/MakePom.scala +++ b/ivy/src/main/scala/sbt/MakePom.scala @@ -83,9 +83,8 @@ class MakePom(val log: Logger) { write(process(toPom(ivy, module, moduleInfo, configurations, includeTypes, extra, filterRepositories, allRepositories)), output) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") - def write(xmlString: String, output: File, newline: String) { + def write(xmlString: String, output: File, newline: String): Unit = IO.write(output, "" + newline + xmlString) - } def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) @deprecated("Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", "0.11.2") diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/ivy/src/main/scala/sbt/ProjectResolver.scala index a51e0abb8..61c811e7b 100644 --- a/ivy/src/main/scala/sbt/ProjectResolver.scala +++ b/ivy/src/main/scala/sbt/ProjectResolver.scala @@ -70,12 +70,12 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] // doesn't support publishing def publish(artifact: IArtifact, src: File, overwrite: Boolean) = sys.error("Publish not supported by ProjectResolver") - def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean) {} - def abortPublishTransaction() {} - def commitPublishTransaction() {} + def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean): Unit = () + def abortPublishTransaction(): Unit = () + def commitPublishTransaction(): Unit = () - def reportFailure() {} - def reportFailure(art: IArtifact) {} + def reportFailure(): Unit = () + def reportFailure(art: IArtifact): Unit = () def listOrganisations() = new Array[OrganisationEntry](0) def listModules(org: OrganisationEntry) = new Array[ModuleEntry](0) @@ -85,8 +85,8 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] private[this] var settings: Option[ResolverSettings] = None - def dumpSettings() {} - def setSettings(settings: ResolverSettings) { this.settings = Some(settings) } + def dumpSettings(): Unit = () + def setSettings(settings: ResolverSettings): Unit = { this.settings = Some(settings) } def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } } diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/ivy/src/main/scala/sbt/ResolutionCache.scala index 0fd7a0a06..a68c52417 100644 --- a/ivy/src/main/scala/sbt/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/ResolutionCache.scala @@ -28,7 +28,7 @@ private[sbt] final class ResolutionCache(base: File, settings: IvySettings) exte private[this] val reportBase: File = new File(base, ReportDirectory) def getResolutionCacheRoot: File = base - def clean() { IO.delete(base) } + def clean(): Unit = IO.delete(base) override def toString = Name def getResolvedIvyFileInCache(mrid: ModuleRevisionId): File = @@ -66,7 +66,7 @@ private[sbt] object ResolutionCache { * Removes cached files from the resolution cache for the module with ID `mrid` * and the resolveId (as set on `ResolveOptions`). */ - private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager) { + private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager): Unit = { val files = Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: @@ -87,4 +87,4 @@ private[sbt] object ResolutionCache { // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]" -} \ No newline at end of file +} diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/ivy/src/main/scala/sbt/StringUtilities.scala index fc8327304..40018250e 100644 --- a/ivy/src/main/scala/sbt/StringUtilities.scala +++ b/ivy/src/main/scala/sbt/StringUtilities.scala @@ -8,8 +8,6 @@ import java.util.Locale object StringUtilities { @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") def normalize(s: String) = s.toLowerCase(Locale.ENGLISH).replaceAll("""\W+""", "-") - def nonEmpty(s: String, label: String) { - require(s.trim.length > 0, label + " cannot be empty.") - } + def nonEmpty(s: String, label: String): Unit = require(s.trim.length > 0, label + " cannot be empty.") def appendable(s: String) = if (s.isEmpty) "" else "_" + s } diff --git a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala index bb5996834..5d067d313 100644 --- a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala @@ -54,7 +54,7 @@ object ErrorMessageAuthenticator { } /** Installs the error message authenticator so we have nicer error messages when using java's URL for downloading. */ - def install() { + def install(): Unit = { // Actually installs the error message authenticator. def doInstall(original: Option[Authenticator]): Unit = try Authenticator.setDefault(new ErrorMessageAuthenticator(original)) @@ -126,4 +126,4 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato private def isProxyAuthentication: Boolean = getRequestorType == Authenticator.RequestorType.PROXY -} \ No newline at end of file +} From 6848fd9f69474fde2181907ee9cb53940ad0d957 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 5 Aug 2015 07:00:39 -0400 Subject: [PATCH 0438/1030] cached resolution: don't include callers from evicted modules --- .../sbt/ivyint/CachedResolutionResolveEngine.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 73b0ec6fc..96c7d88b4 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -395,6 +395,18 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { */ def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = { + // filter out evicted modules from further logic + def filterReports(report0: OrganizationArtifactReport): Option[OrganizationArtifactReport] = + report0.modules.toVector flatMap { mr => + if (mr.evicted || mr.problem.nonEmpty) None + else + // https://github.com/sbt/sbt/issues/1763 + Some(mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers))) + } match { + case Vector() => None + case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms)) + } + // group by takes up too much memory. trading space with time. val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct // this might take up some memory, but it's limited to a single From 2264a1052c542748c46c17ba06383323f3c84f0a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 5 Aug 2015 07:01:21 -0400 Subject: [PATCH 0439/1030] cached resolution: use mutable map to speed up breakLoops --- .../CachedResolutionResolveEngine.scala | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 96c7d88b4..4ff745276 100644 --- a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -410,7 +410,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // group by takes up too much memory. trading space with time. val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct // this might take up some memory, but it's limited to a single - val reports1 = reports0 map { filterOutCallers } + val reports1 = reports0 flatMap { filterReports } val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = Map(orgNamePairs map { case (organization, name) => @@ -447,15 +447,15 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } loopLists.toList } - @tailrec def breakLoops(loops: List[List[(String, String)]], - allModules1: Map[(String, String), Vector[OrganizationArtifactReport]]): Map[(String, String), Vector[OrganizationArtifactReport]] = + val allModules2: mutable.Map[(String, String), Vector[OrganizationArtifactReport]] = + mutable.Map(allModules0.toSeq: _*) + @tailrec def breakLoops(loops: List[List[(String, String)]]): Unit = loops match { - case Nil => - allModules1 + case Nil => () case loop :: rest => loop match { case Nil => - breakLoops(rest, allModules1) + breakLoops(rest) case loop => val sortedLoop = loop sortBy { x => (for { @@ -468,7 +468,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1) // remove the module with most callers as the caller of next. // so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed. - val nextMap = allModules1 map { + allModules2 foreach { case (k: (String, String), oars0) if k == next => val oars: Vector[OrganizationArtifactReport] = oars0 map { oar => val mrs = oar.modules map { mr => @@ -482,15 +482,17 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } OrganizationArtifactReport(oar.organization, oar.name, mrs) } - (k, oars) - case (k, v) => (k, v) + allModules2(k) = oars + case (k, v) => // do nothing } - breakLoops(rest, nextMap) + + breakLoops(rest) } } val loop = detectLoops(allModules0) log.debug(s":: $rootModuleConf: loop: $loop") - val allModules2 = breakLoops(loop, allModules0) + breakLoops(loop) + // sort the all modules such that less called modules comes earlier @tailrec def sortModules(cs: Vector[(String, String)], acc: Vector[(String, String)], extra: Vector[(String, String)], @@ -554,14 +556,6 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val result = resolveConflicts(sorted.toList, allModules0) result.toVector } - def filterOutCallers(report0: OrganizationArtifactReport): OrganizationArtifactReport = - OrganizationArtifactReport( - report0.organization, - report0.name, - report0.modules map { mr => - // https://github.com/sbt/sbt/issues/1763 - mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers)) - }) /** * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). From 1b90c865d1a38d18ec0f146d517be5f4a6f00ffe Mon Sep 17 00:00:00 2001 From: Pierre DAL-PRA Date: Fri, 7 Aug 2015 00:23:14 +0200 Subject: [PATCH 0440/1030] Fix additional warnings --- .../scala/sbt/ivyint/SbtChainResolver.scala | 20 +++++++++---------- ivy/src/test/scala/BaseIvySpecification.scala | 11 ++-------- ivy/src/test/scala/CachedResolutionSpec.scala | 4 ++-- 3 files changed, 14 insertions(+), 21 deletions(-) diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 08c8f00e7..6b1f59a15 100644 --- a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -7,14 +7,14 @@ import java.util.Date import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.{ IvyContext, LogOptions } -import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultModuleDescriptor, DefaultDependencyDescriptor, ModuleDescriptor, DependencyDescriptor } +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor } import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } import org.apache.ivy.plugins.latest.LatestStrategy import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } import org.apache.ivy.plugins.repository.url.URLResource import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } -import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } +import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } private[sbt] case class SbtChainResolver( name: String, @@ -88,9 +88,9 @@ private[sbt] case class SbtChainResolver( // - If `isReturnFirst` is true, you return the first value found // - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and // leads to undefined behavior. - val useLatest = (dd.isChanging || (IvySbt.isChanging(dd.getDependencyRevisionId))) && updateOptions.latestSnapshots + val useLatest = (dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId)) && updateOptions.latestSnapshots if (useLatest) { - Message.verbose(s"${getName} is changing. Checking all resolvers on the chain") + Message.verbose(s"$getName is changing. Checking all resolvers on the chain") } val data = new ResolveData(data0, doValidate(data0)) // Returns the value if we've already been resolved from some other branch of the resolution tree. @@ -146,7 +146,7 @@ private[sbt] case class SbtChainResolver( Left(ex) } finally { oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) } - checkInterrupted + checkInterrupted() } } } @@ -179,7 +179,7 @@ private[sbt] case class SbtChainResolver( } }).reverse.headOption map { case (rmr, resolver) => - Message.warn(s"Choosing ${resolver} for ${rmr.getId}") + Message.warn(s"Choosing $resolver for ${rmr.getId}") // Now that we know the real latest revision, let's force Ivy to use it val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { @@ -191,7 +191,7 @@ private[sbt] case class SbtChainResolver( case Some(artifactRef) => val systemMd = toSystem(rmr.getDescriptor) getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, - toSystem(dd), systemMd.getAllArtifacts().head, None.orNull, getCacheOptions(data)) + toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) } rmr } @@ -223,7 +223,7 @@ private[sbt] case class SbtChainResolver( case r: FileResource => try { val parser = rmr.getDescriptor.getParser - val md = parser.parseDescriptor(settings, r.getFile.toURL, r, false) + val md = parser.parseDescriptor(settings, r.getFile.toURI.toURL, r, false) Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true)) } catch { case _: ParseException => None @@ -246,7 +246,7 @@ private[sbt] case class SbtChainResolver( Option(artifact.getUrl) map { url => Message.verbose("\tusing url for " + artifact + ": " + url) val resource = - if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath())) + if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath)) else new URLResource(url) new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) } @@ -262,7 +262,7 @@ private[sbt] case class SbtChainResolver( artifactRef(af, data.getDate).toIterator } } - if (artifactRefs.hasNext) Some(artifactRefs.next) + if (artifactRefs.hasNext) Some(artifactRefs.next()) else None } /** Ported from ChainResolver#forcedRevision. */ diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index 55efa60fa..a8a19ea76 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -4,7 +4,6 @@ import Path._, Configurations._ import java.io.File import org.specs2._ import cross.CrossVersionUtil -import sbt.PublishConfiguration import sbt.ivyint.SbtChainResolver trait BaseIvySpecification extends Specification { @@ -59,15 +58,9 @@ trait BaseIvySpecification extends Specification { IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } - def cleanIvyCache: Unit = - { - IO.delete(currentTarget / "cache") - } + def cleanIvyCache(): Unit = IO.delete(currentTarget / "cache") - def cleanCachedResolutionCache(module: IvySbt#Module): Unit = - { - IvyActions.cleanCachedResolutionCache(module, log) - } + def cleanCachedResolutionCache(module: IvySbt#Module): Unit = IvyActions.cleanCachedResolutionCache(module, log) def ivyUpdate(module: IvySbt#Module) = ivyUpdateEither(module) match { diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala index 16021b15c..8edbfaa15 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -28,7 +28,7 @@ class CachedResolutionSpec extends BaseIvySpecification { import ShowLines._ def e1 = { - cleanIvyCache + cleanIvyCache() val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) val report = ivyUpdate(m) @@ -67,7 +67,7 @@ class CachedResolutionSpec extends BaseIvySpecification { // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final def e3 = { // log.setLevel(Level.Debug) - cleanIvyCache + cleanIvyCache() val m = module(ModuleID("com.example", "foo", "0.3.0", Some("compile")), Seq(avro177, dataAvro1940, netty320), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) From 319054fa32b712970cb729c11696b209841ab550 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 19 Aug 2015 03:56:08 -0400 Subject: [PATCH 0441/1030] Add build.sbt --- README.md | 12 +++++ build.sbt | 46 +++++++++++++++++++ .../main/input_sources/CrossVersionUtil.scala | 0 {ivy => librarymanagement}/NOTICE | 0 .../src/main/java/sbt/ResolverAdapter.java | 0 .../sbt/mavenint/SbtPomExtraProperties.java | 0 .../ReplaceMavenConfigurationMappings.scala | 0 .../src/main/scala/sbt/Artifact.scala | 0 .../scala/sbt/CircularDependencyLevel.scala | 0 .../src/main/scala/sbt/ComponentManager.scala | 0 .../src/main/scala/sbt/Configuration.scala | 0 .../src/main/scala/sbt/ConflictWarning.scala | 0 .../src/main/scala/sbt/ConvertResolver.scala | 0 .../src/main/scala/sbt/Credentials.scala | 0 .../src/main/scala/sbt/CrossVersion.scala | 0 .../src/main/scala/sbt/CustomPomParser.scala | 0 .../src/main/scala/sbt/CustomXmlParser.scala | 0 .../src/main/scala/sbt/DependencyFilter.scala | 0 .../src/main/scala/sbt/EvictionWarning.scala | 0 .../src/main/scala/sbt/Ivy.scala | 0 .../src/main/scala/sbt/IvyActions.scala | 0 .../src/main/scala/sbt/IvyCache.scala | 0 .../main/scala/sbt/IvyConfigurations.scala | 0 .../src/main/scala/sbt/IvyInterface.scala | 0 .../src/main/scala/sbt/IvyLogger.scala | 0 .../src/main/scala/sbt/IvyRetrieve.scala | 0 .../src/main/scala/sbt/IvyScala.scala | 0 .../src/main/scala/sbt/IvyUtil.scala | 0 .../src/main/scala/sbt/JsonUtil.scala | 0 .../src/main/scala/sbt/LogicalClock.scala | 0 .../src/main/scala/sbt/MakePom.scala | 0 .../src/main/scala/sbt/ModuleID.scala | 0 .../src/main/scala/sbt/ProjectResolver.scala | 0 .../src/main/scala/sbt/ResolutionCache.scala | 0 .../src/main/scala/sbt/Resolver.scala | 0 .../src/main/scala/sbt/SbtExclusionRule.scala | 0 .../src/main/scala/sbt/StringUtilities.scala | 0 .../src/main/scala/sbt/UpdateOptions.scala | 0 .../src/main/scala/sbt/UpdateReport.scala | 0 .../src/main/scala/sbt/VersionNumber.scala | 0 .../scala/sbt/impl/DependencyBuilders.scala | 0 .../CachedResolutionResolveEngine.scala | 0 .../sbt/ivyint/CustomMavenResolver.scala | 0 .../ivyint/ErrorMessageAuthenticator.scala | 0 .../sbt/ivyint/IvyCredentialsLookup.scala | 0 .../scala/sbt/ivyint/MergeDescriptors.scala | 0 .../scala/sbt/ivyint/SbtChainResolver.scala | 0 .../SbtDefaultDependencyDescriptor.scala | 0 .../PomExtraDependencyAttributes.scala | 0 .../test-artifact-1.0.0-SNAPSHOT.jar | 0 .../test-artifact-1.0.0-SNAPSHOT.pom | 0 .../src/test/scala/BaseIvySpecification.scala | 0 .../src/test/scala/CachedResolutionSpec.scala | 0 .../src/test/scala/ComponentManagerTest.scala | 0 .../src/test/scala/CrossVersionTest.scala | 0 .../src/test/scala/CustomPomParserTest.scala | 0 .../src/test/scala/DMSerializationSpec.scala | 0 .../src/test/scala/EvictionWarningSpec.scala | 0 .../scala/InconsistentDuplicateSpec.scala | 0 .../src/test/scala/MakePomSpec.scala | 0 .../src/test/scala/ResolverTest.scala | 0 .../src/test/scala/VersionNumberSpec.scala | 0 project/Dependencies.scala | 22 +++++++++ project/build.properties | 1 + 64 files changed, 81 insertions(+) create mode 100644 README.md create mode 100644 build.sbt rename {util => internal}/cross/src/main/input_sources/CrossVersionUtil.scala (100%) rename {ivy => librarymanagement}/NOTICE (100%) rename {ivy => librarymanagement}/src/main/java/sbt/ResolverAdapter.java (100%) rename {ivy => librarymanagement}/src/main/java/sbt/mavenint/SbtPomExtraProperties.java (100%) rename {ivy => librarymanagement}/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/Artifact.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/CircularDependencyLevel.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ComponentManager.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/Configuration.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ConflictWarning.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ConvertResolver.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/Credentials.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/CrossVersion.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/CustomPomParser.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/CustomXmlParser.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/DependencyFilter.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/EvictionWarning.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/Ivy.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyActions.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyCache.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyConfigurations.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyInterface.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyLogger.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyRetrieve.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyScala.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/IvyUtil.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/JsonUtil.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/LogicalClock.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/MakePom.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ModuleID.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ProjectResolver.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ResolutionCache.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/Resolver.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/SbtExclusionRule.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/StringUtilities.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/UpdateOptions.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/UpdateReport.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/VersionNumber.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/impl/DependencyBuilders.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/CustomMavenResolver.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/MergeDescriptors.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/SbtChainResolver.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala (100%) rename {ivy => librarymanagement}/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala (100%) rename {ivy => librarymanagement}/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar (100%) rename {ivy => librarymanagement}/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom (100%) rename {ivy => librarymanagement}/src/test/scala/BaseIvySpecification.scala (100%) rename {ivy => librarymanagement}/src/test/scala/CachedResolutionSpec.scala (100%) rename {ivy => librarymanagement}/src/test/scala/ComponentManagerTest.scala (100%) rename {ivy => librarymanagement}/src/test/scala/CrossVersionTest.scala (100%) rename {ivy => librarymanagement}/src/test/scala/CustomPomParserTest.scala (100%) rename {ivy => librarymanagement}/src/test/scala/DMSerializationSpec.scala (100%) rename {ivy => librarymanagement}/src/test/scala/EvictionWarningSpec.scala (100%) rename {ivy => librarymanagement}/src/test/scala/InconsistentDuplicateSpec.scala (100%) rename {ivy => librarymanagement}/src/test/scala/MakePomSpec.scala (100%) rename {ivy => librarymanagement}/src/test/scala/ResolverTest.scala (100%) rename {ivy => librarymanagement}/src/test/scala/VersionNumberSpec.scala (100%) create mode 100644 project/Dependencies.scala create mode 100644 project/build.properties diff --git a/README.md b/README.md new file mode 100644 index 000000000..a265c06e9 --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +librarymanagement module for sbt +================================ + +``` +git clone --no-hardlinks --branch 0.13 sbt sbt-modules/librarymanagement +cd sbt-modules/librarymanagement +git filter-branch --index-filter 'git rm --cached -qr -- . && git reset -q $GIT_COMMIT -- ivy util/cross' --prune-empty +git reset --hard +git gc --aggressive +git prune +git cb 1.0 +``` diff --git a/build.sbt b/build.sbt new file mode 100644 index 000000000..f533b238c --- /dev/null +++ b/build.sbt @@ -0,0 +1,46 @@ +import Dependencies._ + +def internalPath = file("internal") + +// ThisBuild settings take lower precedence, +// but can be shared across the multi projects. +def buildLevelSettings: Seq[Setting[_]] = Seq( + organization in ThisBuild := "org.scala-sbt.librarymanagement", + version in ThisBuild := "1.0.0-SNAPSHOT" + // bintrayOrganization in ThisBuild := Some("sbt"), + // // bintrayRepository in ThisBuild := s"ivy-${(publishStatus in ThisBuild).value}", + // bintrayPackage in ThisBuild := "sbt", + // bintrayReleaseOnPublish in ThisBuild := false +) + +def commonSettings: Seq[Setting[_]] = Seq( + scalaVersion := "2.10.5", + // publishArtifact in packageDoc := false, + resolvers += Resolver.typesafeIvyRepo("releases"), + resolvers += Resolver.sonatypeRepo("snapshots"), + // concurrentRestrictions in Global += Util.testExclusiveRestriction, + testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), + javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), + incOptions := incOptions.value.withNameHashing(true) + // crossScalaVersions := Seq(scala210) + // bintrayPackage := (bintrayPackage in ThisBuild).value, + // bintrayRepository := (bintrayRepository in ThisBuild).value +) + +lazy val root = (project in file(".")). + aggregate(lm). + settings( + buildLevelSettings, + commonSettings, + // rootSettings, + publish := {}, + publishLocal := {} + ) + +lazy val lm = (project in file("librarymanagement")). + settings( + commonSettings, + libraryDependencies ++= Seq(interfaceProj, crossProj, logProj % "compile;test->test", ioProj % "compile;test->test", collectionProj), + libraryDependencies ++= Seq(ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + name := "librarymanagement" + ) diff --git a/util/cross/src/main/input_sources/CrossVersionUtil.scala b/internal/cross/src/main/input_sources/CrossVersionUtil.scala similarity index 100% rename from util/cross/src/main/input_sources/CrossVersionUtil.scala rename to internal/cross/src/main/input_sources/CrossVersionUtil.scala diff --git a/ivy/NOTICE b/librarymanagement/NOTICE similarity index 100% rename from ivy/NOTICE rename to librarymanagement/NOTICE diff --git a/ivy/src/main/java/sbt/ResolverAdapter.java b/librarymanagement/src/main/java/sbt/ResolverAdapter.java similarity index 100% rename from ivy/src/main/java/sbt/ResolverAdapter.java rename to librarymanagement/src/main/java/sbt/ResolverAdapter.java diff --git a/ivy/src/main/java/sbt/mavenint/SbtPomExtraProperties.java b/librarymanagement/src/main/java/sbt/mavenint/SbtPomExtraProperties.java similarity index 100% rename from ivy/src/main/java/sbt/mavenint/SbtPomExtraProperties.java rename to librarymanagement/src/main/java/sbt/mavenint/SbtPomExtraProperties.java diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala similarity index 100% rename from ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala rename to librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala diff --git a/ivy/src/main/scala/sbt/Artifact.scala b/librarymanagement/src/main/scala/sbt/Artifact.scala similarity index 100% rename from ivy/src/main/scala/sbt/Artifact.scala rename to librarymanagement/src/main/scala/sbt/Artifact.scala diff --git a/ivy/src/main/scala/sbt/CircularDependencyLevel.scala b/librarymanagement/src/main/scala/sbt/CircularDependencyLevel.scala similarity index 100% rename from ivy/src/main/scala/sbt/CircularDependencyLevel.scala rename to librarymanagement/src/main/scala/sbt/CircularDependencyLevel.scala diff --git a/ivy/src/main/scala/sbt/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/ComponentManager.scala similarity index 100% rename from ivy/src/main/scala/sbt/ComponentManager.scala rename to librarymanagement/src/main/scala/sbt/ComponentManager.scala diff --git a/ivy/src/main/scala/sbt/Configuration.scala b/librarymanagement/src/main/scala/sbt/Configuration.scala similarity index 100% rename from ivy/src/main/scala/sbt/Configuration.scala rename to librarymanagement/src/main/scala/sbt/Configuration.scala diff --git a/ivy/src/main/scala/sbt/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/ConflictWarning.scala similarity index 100% rename from ivy/src/main/scala/sbt/ConflictWarning.scala rename to librarymanagement/src/main/scala/sbt/ConflictWarning.scala diff --git a/ivy/src/main/scala/sbt/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala similarity index 100% rename from ivy/src/main/scala/sbt/ConvertResolver.scala rename to librarymanagement/src/main/scala/sbt/ConvertResolver.scala diff --git a/ivy/src/main/scala/sbt/Credentials.scala b/librarymanagement/src/main/scala/sbt/Credentials.scala similarity index 100% rename from ivy/src/main/scala/sbt/Credentials.scala rename to librarymanagement/src/main/scala/sbt/Credentials.scala diff --git a/ivy/src/main/scala/sbt/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/CrossVersion.scala similarity index 100% rename from ivy/src/main/scala/sbt/CrossVersion.scala rename to librarymanagement/src/main/scala/sbt/CrossVersion.scala diff --git a/ivy/src/main/scala/sbt/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/CustomPomParser.scala similarity index 100% rename from ivy/src/main/scala/sbt/CustomPomParser.scala rename to librarymanagement/src/main/scala/sbt/CustomPomParser.scala diff --git a/ivy/src/main/scala/sbt/CustomXmlParser.scala b/librarymanagement/src/main/scala/sbt/CustomXmlParser.scala similarity index 100% rename from ivy/src/main/scala/sbt/CustomXmlParser.scala rename to librarymanagement/src/main/scala/sbt/CustomXmlParser.scala diff --git a/ivy/src/main/scala/sbt/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/DependencyFilter.scala similarity index 100% rename from ivy/src/main/scala/sbt/DependencyFilter.scala rename to librarymanagement/src/main/scala/sbt/DependencyFilter.scala diff --git a/ivy/src/main/scala/sbt/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/EvictionWarning.scala similarity index 100% rename from ivy/src/main/scala/sbt/EvictionWarning.scala rename to librarymanagement/src/main/scala/sbt/EvictionWarning.scala diff --git a/ivy/src/main/scala/sbt/Ivy.scala b/librarymanagement/src/main/scala/sbt/Ivy.scala similarity index 100% rename from ivy/src/main/scala/sbt/Ivy.scala rename to librarymanagement/src/main/scala/sbt/Ivy.scala diff --git a/ivy/src/main/scala/sbt/IvyActions.scala b/librarymanagement/src/main/scala/sbt/IvyActions.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyActions.scala rename to librarymanagement/src/main/scala/sbt/IvyActions.scala diff --git a/ivy/src/main/scala/sbt/IvyCache.scala b/librarymanagement/src/main/scala/sbt/IvyCache.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyCache.scala rename to librarymanagement/src/main/scala/sbt/IvyCache.scala diff --git a/ivy/src/main/scala/sbt/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyConfigurations.scala rename to librarymanagement/src/main/scala/sbt/IvyConfigurations.scala diff --git a/ivy/src/main/scala/sbt/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/IvyInterface.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyInterface.scala rename to librarymanagement/src/main/scala/sbt/IvyInterface.scala diff --git a/ivy/src/main/scala/sbt/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/IvyLogger.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyLogger.scala rename to librarymanagement/src/main/scala/sbt/IvyLogger.scala diff --git a/ivy/src/main/scala/sbt/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/IvyRetrieve.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyRetrieve.scala rename to librarymanagement/src/main/scala/sbt/IvyRetrieve.scala diff --git a/ivy/src/main/scala/sbt/IvyScala.scala b/librarymanagement/src/main/scala/sbt/IvyScala.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyScala.scala rename to librarymanagement/src/main/scala/sbt/IvyScala.scala diff --git a/ivy/src/main/scala/sbt/IvyUtil.scala b/librarymanagement/src/main/scala/sbt/IvyUtil.scala similarity index 100% rename from ivy/src/main/scala/sbt/IvyUtil.scala rename to librarymanagement/src/main/scala/sbt/IvyUtil.scala diff --git a/ivy/src/main/scala/sbt/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/JsonUtil.scala similarity index 100% rename from ivy/src/main/scala/sbt/JsonUtil.scala rename to librarymanagement/src/main/scala/sbt/JsonUtil.scala diff --git a/ivy/src/main/scala/sbt/LogicalClock.scala b/librarymanagement/src/main/scala/sbt/LogicalClock.scala similarity index 100% rename from ivy/src/main/scala/sbt/LogicalClock.scala rename to librarymanagement/src/main/scala/sbt/LogicalClock.scala diff --git a/ivy/src/main/scala/sbt/MakePom.scala b/librarymanagement/src/main/scala/sbt/MakePom.scala similarity index 100% rename from ivy/src/main/scala/sbt/MakePom.scala rename to librarymanagement/src/main/scala/sbt/MakePom.scala diff --git a/ivy/src/main/scala/sbt/ModuleID.scala b/librarymanagement/src/main/scala/sbt/ModuleID.scala similarity index 100% rename from ivy/src/main/scala/sbt/ModuleID.scala rename to librarymanagement/src/main/scala/sbt/ModuleID.scala diff --git a/ivy/src/main/scala/sbt/ProjectResolver.scala b/librarymanagement/src/main/scala/sbt/ProjectResolver.scala similarity index 100% rename from ivy/src/main/scala/sbt/ProjectResolver.scala rename to librarymanagement/src/main/scala/sbt/ProjectResolver.scala diff --git a/ivy/src/main/scala/sbt/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/ResolutionCache.scala similarity index 100% rename from ivy/src/main/scala/sbt/ResolutionCache.scala rename to librarymanagement/src/main/scala/sbt/ResolutionCache.scala diff --git a/ivy/src/main/scala/sbt/Resolver.scala b/librarymanagement/src/main/scala/sbt/Resolver.scala similarity index 100% rename from ivy/src/main/scala/sbt/Resolver.scala rename to librarymanagement/src/main/scala/sbt/Resolver.scala diff --git a/ivy/src/main/scala/sbt/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/SbtExclusionRule.scala similarity index 100% rename from ivy/src/main/scala/sbt/SbtExclusionRule.scala rename to librarymanagement/src/main/scala/sbt/SbtExclusionRule.scala diff --git a/ivy/src/main/scala/sbt/StringUtilities.scala b/librarymanagement/src/main/scala/sbt/StringUtilities.scala similarity index 100% rename from ivy/src/main/scala/sbt/StringUtilities.scala rename to librarymanagement/src/main/scala/sbt/StringUtilities.scala diff --git a/ivy/src/main/scala/sbt/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/UpdateOptions.scala similarity index 100% rename from ivy/src/main/scala/sbt/UpdateOptions.scala rename to librarymanagement/src/main/scala/sbt/UpdateOptions.scala diff --git a/ivy/src/main/scala/sbt/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/UpdateReport.scala similarity index 100% rename from ivy/src/main/scala/sbt/UpdateReport.scala rename to librarymanagement/src/main/scala/sbt/UpdateReport.scala diff --git a/ivy/src/main/scala/sbt/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/VersionNumber.scala similarity index 100% rename from ivy/src/main/scala/sbt/VersionNumber.scala rename to librarymanagement/src/main/scala/sbt/VersionNumber.scala diff --git a/ivy/src/main/scala/sbt/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/impl/DependencyBuilders.scala similarity index 100% rename from ivy/src/main/scala/sbt/impl/DependencyBuilders.scala rename to librarymanagement/src/main/scala/sbt/impl/DependencyBuilders.scala diff --git a/ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala rename to librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala diff --git a/ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala b/librarymanagement/src/main/scala/sbt/ivyint/CustomMavenResolver.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/CustomMavenResolver.scala rename to librarymanagement/src/main/scala/sbt/ivyint/CustomMavenResolver.scala diff --git a/ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala rename to librarymanagement/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala diff --git a/ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala b/librarymanagement/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala rename to librarymanagement/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala diff --git a/ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/ivyint/MergeDescriptors.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/MergeDescriptors.scala rename to librarymanagement/src/main/scala/sbt/ivyint/MergeDescriptors.scala diff --git a/ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/SbtChainResolver.scala rename to librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala diff --git a/ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala b/librarymanagement/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala similarity index 100% rename from ivy/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala rename to librarymanagement/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala diff --git a/ivy/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala b/librarymanagement/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala similarity index 100% rename from ivy/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala rename to librarymanagement/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala diff --git a/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar b/librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar similarity index 100% rename from ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar rename to librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar diff --git a/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom b/librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom similarity index 100% rename from ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom rename to librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala similarity index 100% rename from ivy/src/test/scala/BaseIvySpecification.scala rename to librarymanagement/src/test/scala/BaseIvySpecification.scala diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala similarity index 100% rename from ivy/src/test/scala/CachedResolutionSpec.scala rename to librarymanagement/src/test/scala/CachedResolutionSpec.scala diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala similarity index 100% rename from ivy/src/test/scala/ComponentManagerTest.scala rename to librarymanagement/src/test/scala/ComponentManagerTest.scala diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala similarity index 100% rename from ivy/src/test/scala/CrossVersionTest.scala rename to librarymanagement/src/test/scala/CrossVersionTest.scala diff --git a/ivy/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala similarity index 100% rename from ivy/src/test/scala/CustomPomParserTest.scala rename to librarymanagement/src/test/scala/CustomPomParserTest.scala diff --git a/ivy/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala similarity index 100% rename from ivy/src/test/scala/DMSerializationSpec.scala rename to librarymanagement/src/test/scala/DMSerializationSpec.scala diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala similarity index 100% rename from ivy/src/test/scala/EvictionWarningSpec.scala rename to librarymanagement/src/test/scala/EvictionWarningSpec.scala diff --git a/ivy/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala similarity index 100% rename from ivy/src/test/scala/InconsistentDuplicateSpec.scala rename to librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala diff --git a/ivy/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala similarity index 100% rename from ivy/src/test/scala/MakePomSpec.scala rename to librarymanagement/src/test/scala/MakePomSpec.scala diff --git a/ivy/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala similarity index 100% rename from ivy/src/test/scala/ResolverTest.scala rename to librarymanagement/src/test/scala/ResolverTest.scala diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala similarity index 100% rename from ivy/src/test/scala/VersionNumberSpec.scala rename to librarymanagement/src/test/scala/VersionNumberSpec.scala diff --git a/project/Dependencies.scala b/project/Dependencies.scala new file mode 100644 index 000000000..55639f4cf --- /dev/null +++ b/project/Dependencies.scala @@ -0,0 +1,22 @@ +import sbt._ +import Keys._ + +object Dependencies { + val bootstrapSbtVersion = "0.13.8" + lazy val interfaceProj = "org.scala-sbt" % "interface" % bootstrapSbtVersion + lazy val ioProj = "org.scala-sbt" % "io" % bootstrapSbtVersion + lazy val collectionProj = "org.scala-sbt" % "collections" % bootstrapSbtVersion + lazy val logProj = "org.scala-sbt" % "logging" % bootstrapSbtVersion + lazy val crossProj = "org.scala-sbt" % "cross" % bootstrapSbtVersion + + lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" + lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" + lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () + lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" + // lazy val sbinary = "org.scala-tools.sbinary" %% "sbinary" % "0.4.2" + // lazy val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.4" + // lazy val specs2 = "org.specs2" %% "specs2" % "2.3.11" + // lazy val junit = "junit" % "junit" % "4.11" + // lazy val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } + lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } +} diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 000000000..817bc38df --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.9 From 887cb7cc3e78b08a96837bbc18f96ce18a987816 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 19 Aug 2015 04:13:08 -0400 Subject: [PATCH 0442/1030] Code gen no longer needed --- build.sbt | 2 +- .../main/scala/sbt/cross}/CrossVersionUtil.scala | 16 ++++++++-------- project/Dependencies.scala | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) rename {internal/cross/src/main/input_sources => librarymanagement/src/main/scala/sbt/cross}/CrossVersionUtil.scala (78%) diff --git a/build.sbt b/build.sbt index f533b238c..cc09d7d70 100644 --- a/build.sbt +++ b/build.sbt @@ -40,7 +40,7 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, - libraryDependencies ++= Seq(interfaceProj, crossProj, logProj % "compile;test->test", ioProj % "compile;test->test", collectionProj), + libraryDependencies ++= Seq(interfaceProj, logProj % "compile;test->test", ioProj % "compile;test->test", collectionProj), libraryDependencies ++= Seq(ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), name := "librarymanagement" ) diff --git a/internal/cross/src/main/input_sources/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala similarity index 78% rename from internal/cross/src/main/input_sources/CrossVersionUtil.scala rename to librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala index 6a63c9139..c890980fc 100644 --- a/internal/cross/src/main/input_sources/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala @@ -1,4 +1,4 @@ -package ${{cross.package0}}.${{cross.package1}} +package sbt.cross object CrossVersionUtil { @@ -15,12 +15,12 @@ object CrossVersionUtil def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) def isBinary(s: String): Boolean = (s == binaryString) - private[${{cross.package0}}] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined /** Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - private[${{cross.package0}}] def sbtApiVersion(v: String): Option[(Int, Int)] = + private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = { val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r @@ -32,11 +32,11 @@ object CrossVersionUtil case _ => None } } - private[${{cross.package0}}] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined /** Returns Scala binary interface x.y API compatible with the given version string v. * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - private[${{cross.package0}}] def scalaApiVersion(v: String): Option[(Int, Int)] = + private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = { val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r val BinCompatV = """(\d+)\.(\d+)\.(\d+)-bin(-.*)?""".r @@ -48,15 +48,15 @@ object CrossVersionUtil case _ => None } } - private[${{cross.package0}}] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r - private[${{cross.package0}}] def partialVersion(s: String): Option[(Int,Int)] = + private[sbt] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + private[sbt] def partialVersion(s: String): Option[(Int,Int)] = s match { case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) case _ => None } def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) - private[${{cross.package0}}] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[sbt] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 55639f4cf..35630da55 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,7 +7,7 @@ object Dependencies { lazy val ioProj = "org.scala-sbt" % "io" % bootstrapSbtVersion lazy val collectionProj = "org.scala-sbt" % "collections" % bootstrapSbtVersion lazy val logProj = "org.scala-sbt" % "logging" % bootstrapSbtVersion - lazy val crossProj = "org.scala-sbt" % "cross" % bootstrapSbtVersion + // lazy val crossProj = "org.scala-sbt" % "cross" % bootstrapSbtVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" From e81b37821471ef26faa48d33c1209e9539740655 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 20 Aug 2015 01:33:22 -0400 Subject: [PATCH 0443/1030] Depend on sbt/util --- build.sbt | 2 +- librarymanagement/src/main/scala/sbt/IvyScala.scala | 10 ++++------ project/Dependencies.scala | 7 +++---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/build.sbt b/build.sbt index cc09d7d70..aa9aaeedb 100644 --- a/build.sbt +++ b/build.sbt @@ -40,7 +40,7 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, - libraryDependencies ++= Seq(interfaceProj, logProj % "compile;test->test", ioProj % "compile;test->test", collectionProj), + libraryDependencies ++= Seq(utilLogging % "compile;test->test", ioProj % "compile;test->test", utilCollection), libraryDependencies ++= Seq(ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), name := "librarymanagement" ) diff --git a/librarymanagement/src/main/scala/sbt/IvyScala.scala b/librarymanagement/src/main/scala/sbt/IvyScala.scala index 2614df994..fc9400174 100644 --- a/librarymanagement/src/main/scala/sbt/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/IvyScala.scala @@ -12,10 +12,9 @@ import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher object ScalaArtifacts { - import xsbti.ArtifactInfo._ - val Organization = ScalaOrganization - val LibraryID = ScalaLibraryID - val CompilerID = ScalaCompilerID + val Organization = "org.scala-lang" + val LibraryID = "scala-library" + val CompilerID = "scala-compiler" val ReflectID = "scala-reflect" def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) @@ -27,8 +26,7 @@ object ScalaArtifacts { ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) } object SbtArtifacts { - import xsbti.ArtifactInfo._ - val Organization = SbtOrganization + val Organization = "org.scala-sbt" } import ScalaArtifacts._ diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 35630da55..7246cdf9e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,12 +2,11 @@ import sbt._ import Keys._ object Dependencies { + val utilVersion = "1.0.0-SNAPSHOT" val bootstrapSbtVersion = "0.13.8" - lazy val interfaceProj = "org.scala-sbt" % "interface" % bootstrapSbtVersion lazy val ioProj = "org.scala-sbt" % "io" % bootstrapSbtVersion - lazy val collectionProj = "org.scala-sbt" % "collections" % bootstrapSbtVersion - lazy val logProj = "org.scala-sbt" % "logging" % bootstrapSbtVersion - // lazy val crossProj = "org.scala-sbt" % "cross" % bootstrapSbtVersion + lazy val utilCollection = "org.scala-sbt.util" %% "util-collection" % utilVersion + lazy val utilLogging = "org.scala-sbt.util" %% "util-logging" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" From 7939e385c145e1b09da698d5a3c7af66e2897276 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 2 Sep 2015 02:59:00 -0400 Subject: [PATCH 0444/1030] Bintray --- build.sbt | 37 ++++++++++++++++++++++--------------- project/Dependencies.scala | 10 +++++----- project/bintray.sbt | 1 + 3 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 project/bintray.sbt diff --git a/build.sbt b/build.sbt index aa9aaeedb..39eceba3f 100644 --- a/build.sbt +++ b/build.sbt @@ -2,17 +2,6 @@ import Dependencies._ def internalPath = file("internal") -// ThisBuild settings take lower precedence, -// but can be shared across the multi projects. -def buildLevelSettings: Seq[Setting[_]] = Seq( - organization in ThisBuild := "org.scala-sbt.librarymanagement", - version in ThisBuild := "1.0.0-SNAPSHOT" - // bintrayOrganization in ThisBuild := Some("sbt"), - // // bintrayRepository in ThisBuild := s"ivy-${(publishStatus in ThisBuild).value}", - // bintrayPackage in ThisBuild := "sbt", - // bintrayReleaseOnPublish in ThisBuild := false -) - def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := "2.10.5", // publishArtifact in packageDoc := false, @@ -21,16 +10,34 @@ def commonSettings: Seq[Setting[_]] = Seq( // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), - incOptions := incOptions.value.withNameHashing(true) + incOptions := incOptions.value.withNameHashing(true), // crossScalaVersions := Seq(scala210) // bintrayPackage := (bintrayPackage in ThisBuild).value, - // bintrayRepository := (bintrayRepository in ThisBuild).value + // bintrayRepository := (bintrayRepository in ThisBuild).value, + resolvers += Resolver.sonatypeRepo("public") ) lazy val root = (project in file(".")). aggregate(lm). settings( - buildLevelSettings, + inThisBuild(Seq( + organization := "org.scala-sbt", + version := "0.1.0-SNAPSHOT", + homepage := Some(url("https://github.com/sbt/librarymanagement")), + description := "Library management module for sbt", + licenses := List("BSD New" -> url("https://github.com/sbt/sbt/blob/0.13/LICENSE")), + scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git")), + developers := List( + Developer("harrah", "Mark Harrah", "@harrah", url("https://github.com/harrah")), + Developer("eed3si9n", "Eugene Yokota", "@eed3si9n", url("https://github.com/eed3si9n")), + Developer("jsuereth", "Josh Suereth", "@jsuereth", url("https://github.com/jsuereth")), + Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")) + ), + bintrayReleaseOnPublish := false, + bintrayOrganization := Some("sbt"), + bintrayRepository := "maven-releases", + bintrayPackage := "librarymanagement" + )), commonSettings, // rootSettings, publish := {}, @@ -40,7 +47,7 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, - libraryDependencies ++= Seq(utilLogging % "compile;test->test", ioProj % "compile;test->test", utilCollection), + libraryDependencies ++= Seq(utilLogging, ioProj, utilCollection), libraryDependencies ++= Seq(ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), name := "librarymanagement" ) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7246cdf9e..e0f1916fc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,11 +2,11 @@ import sbt._ import Keys._ object Dependencies { - val utilVersion = "1.0.0-SNAPSHOT" - val bootstrapSbtVersion = "0.13.8" - lazy val ioProj = "org.scala-sbt" % "io" % bootstrapSbtVersion - lazy val utilCollection = "org.scala-sbt.util" %% "util-collection" % utilVersion - lazy val utilLogging = "org.scala-sbt.util" %% "util-logging" % utilVersion + val utilVersion = "0.1.0-M1" + val ioVersion = "1.0.0-M1" + lazy val ioProj = "org.scala-sbt" %% "io" % ioVersion + lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion + lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" diff --git a/project/bintray.sbt b/project/bintray.sbt new file mode 100644 index 000000000..8dd913f98 --- /dev/null +++ b/project/bintray.sbt @@ -0,0 +1 @@ +addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") From 277c754e36aee2a8eaa0ac9dad7a679bf0544e5f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 2 Sep 2015 03:03:20 -0400 Subject: [PATCH 0445/1030] Merge #1 --- .travis.yml | 4 +++ build.sbt | 8 +++-- .../src/main/scala/sbt/ConvertResolver.scala | 1 + .../src/main/scala/sbt/Credentials.scala | 1 + .../src/main/scala/sbt/CustomPomParser.scala | 1 + .../src/main/scala/sbt/DependencyFilter.scala | 4 ++- .../src/main/scala/sbt/IvyActions.scala | 3 +- .../src/main/scala/sbt/IvyCache.scala | 1 + .../src/main/scala/sbt/JsonUtil.scala | 2 +- .../src/main/scala/sbt/LogicalClock.scala | 2 +- .../src/main/scala/sbt/MakePom.scala | 1 + .../src/main/scala/sbt/ResolutionCache.scala | 1 + .../src/main/scala/sbt/Resolver.scala | 4 +-- .../CachedResolutionResolveEngine.scala | 1 + .../src/test/scala/BaseIvySpecification.scala | 3 +- .../src/test/scala/ComponentManagerTest.scala | 3 +- .../src/test/scala/CustomPomParserTest.scala | 2 +- project/Dependencies.scala | 10 +++--- project/Util.scala | 32 +++++++++++++++++++ 19 files changed, 66 insertions(+), 18 deletions(-) create mode 100644 .travis.yml create mode 100644 project/Util.scala diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..a5b73c0d8 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: scala +scala: + - 2.10.5 + - 2.11.7 diff --git a/build.sbt b/build.sbt index 39eceba3f..71e663210 100644 --- a/build.sbt +++ b/build.sbt @@ -7,11 +7,12 @@ def commonSettings: Seq[Setting[_]] = Seq( // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), + resolvers += Resolver.bintrayRepo("sbt", "maven-releases"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), incOptions := incOptions.value.withNameHashing(true), - // crossScalaVersions := Seq(scala210) + crossScalaVersions := Seq(scala210, scala211), // bintrayPackage := (bintrayPackage in ThisBuild).value, // bintrayRepository := (bintrayRepository in ThisBuild).value, resolvers += Resolver.sonatypeRepo("public") @@ -47,7 +48,8 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, - libraryDependencies ++= Seq(utilLogging, ioProj, utilCollection), - libraryDependencies ++= Seq(ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + libraryDependencies ++= Seq(utilLogging, utilLogging), + libraryDependencies ++= Seq(sbtIO, utilCollection, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, name := "librarymanagement" ) diff --git a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala index 9768241d5..9e2f11f63 100644 --- a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala @@ -17,6 +17,7 @@ import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, File import java.io.{ IOException, File } import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } +import sbt.io.IO private[sbt] object ConvertResolver { import UpdateOptions.ResolverConverter diff --git a/librarymanagement/src/main/scala/sbt/Credentials.scala b/librarymanagement/src/main/scala/sbt/Credentials.scala index 464d5de8e..9cbe9d977 100644 --- a/librarymanagement/src/main/scala/sbt/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/Credentials.scala @@ -5,6 +5,7 @@ package sbt import java.io.File import org.apache.ivy.util.url.CredentialsStore +import sbt.io.IO object Credentials { def apply(realm: String, host: String, userName: String, passwd: String): Credentials = diff --git a/librarymanagement/src/main/scala/sbt/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/CustomPomParser.scala index be98bfe25..8cf372af0 100644 --- a/librarymanagement/src/main/scala/sbt/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/CustomPomParser.scala @@ -13,6 +13,7 @@ import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern import sbt.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } +import sbt.io.Hash @deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { diff --git a/librarymanagement/src/main/scala/sbt/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/DependencyFilter.scala index fee8da46c..701d179aa 100644 --- a/librarymanagement/src/main/scala/sbt/DependencyFilter.scala +++ b/librarymanagement/src/main/scala/sbt/DependencyFilter.scala @@ -3,6 +3,8 @@ */ package sbt +import sbt.io.{ AllPassFilter, NameFilter } + trait DependencyFilterExtra { def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = new ModuleFilter { @@ -57,4 +59,4 @@ trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] { trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] { protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) } final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) -} \ No newline at end of file +} diff --git a/librarymanagement/src/main/scala/sbt/IvyActions.scala b/librarymanagement/src/main/scala/sbt/IvyActions.scala index 33436452c..e3cc20602 100644 --- a/librarymanagement/src/main/scala/sbt/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/IvyActions.scala @@ -16,6 +16,7 @@ import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, MDArtifact import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } +import sbt.io.{ IO, PathFinder } final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, @@ -304,7 +305,7 @@ object IvyActions { case None => None case Some(configs) => Some(configs.map(_.name)) } - val existingFiles = PathFinder(base).***.get filterNot { _.isDirectory } + val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf, mid, art, cached) => configurationNames match { diff --git a/librarymanagement/src/main/scala/sbt/IvyCache.scala b/librarymanagement/src/main/scala/sbt/IvyCache.scala index ce2ddd9f2..1e715a278 100644 --- a/librarymanagement/src/main/scala/sbt/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/IvyCache.scala @@ -12,6 +12,7 @@ import org.apache.ivy.plugins.repository.file.{ FileRepository => IvyFileReposit import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, ResourceDownloader } import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil +import sbt.io.Path class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { diff --git a/librarymanagement/src/main/scala/sbt/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/JsonUtil.scala index d4db781f7..6ee5bd68a 100644 --- a/librarymanagement/src/main/scala/sbt/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/JsonUtil.scala @@ -24,7 +24,7 @@ private[sbt] object JsonUtil { } def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { - IO.createDirectory(graphPath.getParentFile) + sbt.io.IO.createDirectory(graphPath.getParentFile) toJsonFile(toLite(ur), graphPath) } def toLite(ur: UpdateReport): UpdateReportLite = diff --git a/librarymanagement/src/main/scala/sbt/LogicalClock.scala b/librarymanagement/src/main/scala/sbt/LogicalClock.scala index d4e1d4cc3..83c516a17 100644 --- a/librarymanagement/src/main/scala/sbt/LogicalClock.scala +++ b/librarymanagement/src/main/scala/sbt/LogicalClock.scala @@ -12,7 +12,7 @@ object LogicalClock { def apply(hashCode: Int): LogicalClock = { def intToByteArray(x: Int): Array[Byte] = Array((x >>> 24).toByte, (x >> 16 & 0xff).toByte, (x >> 8 & 0xff).toByte, (x & 0xff).toByte) - apply(Hash.toHex(intToByteArray(hashCode))) + apply(sbt.io.Hash.toHex(intToByteArray(hashCode))) } def apply(x: String): LogicalClock = new LogicalClock { override def toString: String = x diff --git a/librarymanagement/src/main/scala/sbt/MakePom.scala b/librarymanagement/src/main/scala/sbt/MakePom.scala index e2018612f..472dd6cfb 100644 --- a/librarymanagement/src/main/scala/sbt/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/MakePom.scala @@ -21,6 +21,7 @@ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } import ivyint.CustomRemoteMavenResolver +import sbt.io.IO object MakePom { /** True if the revision is an ivy-range, not a complete revision. */ def isDependencyVersionRange(revision: String): Boolean = { diff --git a/librarymanagement/src/main/scala/sbt/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/ResolutionCache.scala index a68c52417..30b8d74f7 100644 --- a/librarymanagement/src/main/scala/sbt/ResolutionCache.scala +++ b/librarymanagement/src/main/scala/sbt/ResolutionCache.scala @@ -12,6 +12,7 @@ import core.module.id.ModuleRevisionId import core.module.descriptor.ModuleDescriptor import ResolutionCache.{ Name, ReportDirectory, ResolvedName, ResolvedPattern } import parser.xml.XmlModuleDescriptorParser +import sbt.io.IO /** * Replaces the standard Ivy resolution cache in order to: diff --git a/librarymanagement/src/main/scala/sbt/Resolver.scala b/librarymanagement/src/main/scala/sbt/Resolver.scala index ce3a2830f..ec2564b43 100644 --- a/librarymanagement/src/main/scala/sbt/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/Resolver.scala @@ -345,9 +345,9 @@ object Resolver { case _: IOException => None case e: SAXParseException => System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); None } - loadHomeFromSettings(() => new File(Path.userHome, ".m2/settings.xml")) orElse + loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse - new File(Path.userHome, ".m2/repository") + new File(sbt.io.Path.userHome, ".m2/repository") } // TODO - should this just be the *exact* same as mavenLocal? probably... def publishMavenLocal: MavenCache = new MavenCache("publish-m2-local", mavenLocalDir) diff --git a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index a1fc5ddfc..ab0896649 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -22,6 +22,7 @@ import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } import Configurations.{ System => _, _ } import annotation.tailrec import scala.concurrent.duration._ +import sbt.io.{ DirectoryFilter, Hash, IO, Path } private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index a8a19ea76..f4e21c4c0 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -1,6 +1,7 @@ package sbt -import Path._, Configurations._ +import sbt.io.Path._, Configurations._ +import sbt.io.IO import java.io.File import org.specs2._ import cross.CrossVersionUtil diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 165bdf9e2..29017b6a3 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -4,7 +4,8 @@ import java.io.File import java.util.concurrent.Callable import org.specs2._ import mutable.Specification -import IO.{ createDirectory, delete, touch, withTemporaryDirectory } +import sbt.io.IO.{ createDirectory, delete, touch, withTemporaryDirectory } +import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 1bc39a120..262e4a22b 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -4,7 +4,7 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions import org.specs2.mutable.Specification import sbt._ -import IO.withTemporaryDirectory +import sbt.io.IO.withTemporaryDirectory object CustomPomParserTest extends Specification { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e0f1916fc..92f1a778d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,9 +2,12 @@ import sbt._ import Keys._ object Dependencies { + lazy val scala210 = "2.10.5" + lazy val scala211 = "2.11.7" + val utilVersion = "0.1.0-M1" val ioVersion = "1.0.0-M1" - lazy val ioProj = "org.scala-sbt" %% "io" % ioVersion + lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion @@ -12,10 +15,5 @@ object Dependencies { lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" - // lazy val sbinary = "org.scala-tools.sbinary" %% "sbinary" % "0.4.2" - // lazy val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.11.4" - // lazy val specs2 = "org.specs2" %% "specs2" % "2.3.11" - // lazy val junit = "junit" % "junit" % "4.11" - // lazy val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } } diff --git a/project/Util.scala b/project/Util.scala new file mode 100644 index 000000000..26533a73b --- /dev/null +++ b/project/Util.scala @@ -0,0 +1,32 @@ +import sbt._ +import Keys._ +import sbt.IO + +import java.io.File + + +object Util { + + def versionLine(version: String): String = "version=" + version + def containsVersion(propFile: File, version: String): Boolean = IO.read(propFile).contains(versionLine(version)) + def lastCompilationTime(analysis: sbt.inc.Analysis): Long = + { + val lastCompilation = analysis.compilations.allCompilations.lastOption + lastCompilation.map(_.startTime) getOrElse 0L + } + + def generateVersionFile(version: String, dir: File, s: TaskStreams, analysis: sbt.inc.Analysis): Seq[File] = + { + import java.util.{ Date, TimeZone } + val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") + formatter.setTimeZone(TimeZone.getTimeZone("GMT")) + val timestamp = formatter.format(new Date) + val content = versionLine(version) + "\ntimestamp=" + timestamp + val f = dir / "xsbt.version.properties" + if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { + s.log.info("Writing version information to " + f + " :\n" + content) + IO.write(f, content) + } + f :: Nil + } +} From 734923fbae5ad97753d908928f74182efd455197 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 2 Sep 2015 03:25:37 -0400 Subject: [PATCH 0446/1030] Bintray --- build.sbt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 71e663210..d9374e157 100644 --- a/build.sbt +++ b/build.sbt @@ -13,8 +13,8 @@ def commonSettings: Seq[Setting[_]] = Seq( javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala210, scala211), - // bintrayPackage := (bintrayPackage in ThisBuild).value, - // bintrayRepository := (bintrayRepository in ThisBuild).value, + bintrayPackage := (bintrayPackage in ThisBuild).value, + bintrayRepository := (bintrayRepository in ThisBuild).value, resolvers += Resolver.sonatypeRepo("public") ) @@ -42,7 +42,8 @@ lazy val root = (project in file(".")). commonSettings, // rootSettings, publish := {}, - publishLocal := {} + publishLocal := {}, + publishArtifact := false ) lazy val lm = (project in file("librarymanagement")). From dbf9dc7450aba460b5aa98559bc9112486f24ec9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 5 Sep 2015 05:32:07 -0400 Subject: [PATCH 0447/1030] bump to util 0.1.0-M2 and migrated to scalatest --- build.sbt | 9 +- .../src/main/scala/sbt/ComponentManager.scala | 1 + .../src/main/scala/sbt/ConflictWarning.scala | 1 + .../src/main/scala/sbt/ConvertResolver.scala | 1 + .../src/main/scala/sbt/Credentials.scala | 1 + .../src/main/scala/sbt/EvictionWarning.scala | 1 + .../src/main/scala/sbt/Ivy.scala | 2 + .../src/main/scala/sbt/IvyActions.scala | 1 + .../src/main/scala/sbt/IvyCache.scala | 1 + .../main/scala/sbt/IvyConfigurations.scala | 1 + .../src/main/scala/sbt/IvyLogger.scala | 1 + .../src/main/scala/sbt/IvyScala.scala | 2 + .../src/main/scala/sbt/JsonUtil.scala | 1 + .../src/main/scala/sbt/MakePom.scala | 1 + .../src/main/scala/sbt/UpdateOptions.scala | 1 + .../CachedResolutionResolveEngine.scala | 1 + .../scala/sbt/ivyint/SbtChainResolver.scala | 1 + .../src/test/scala/BaseIvySpecification.scala | 5 +- .../src/test/scala/CachedResolutionSpec.scala | 50 ++-- .../src/test/scala/ComponentManagerTest.scala | 93 +++---- .../src/test/scala/CrossVersionTest.scala | 228 +++++++++--------- .../src/test/scala/CustomPomParserTest.scala | 44 ++-- .../src/test/scala/DMSerializationSpec.scala | 88 +++---- .../src/test/scala/EvictionWarningSpec.scala | 108 ++++----- .../scala/InconsistentDuplicateSpec.scala | 30 +-- .../src/test/scala/MakePomSpec.scala | 95 ++++---- .../src/test/scala/ResolverTest.scala | 27 +-- .../src/test/scala/VersionNumberSpec.scala | 179 ++++++-------- project/Dependencies.scala | 5 +- 29 files changed, 473 insertions(+), 506 deletions(-) diff --git a/build.sbt b/build.sbt index d9374e157..92bca0d1a 100644 --- a/build.sbt +++ b/build.sbt @@ -40,7 +40,7 @@ lazy val root = (project in file(".")). bintrayPackage := "librarymanagement" )), commonSettings, - // rootSettings, + name := "LM Root", publish := {}, publishLocal := {}, publishArtifact := false @@ -49,8 +49,11 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, - libraryDependencies ++= Seq(utilLogging, utilLogging), - libraryDependencies ++= Seq(sbtIO, utilCollection, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + libraryDependencies ++= Seq( + utilLogging, (utilLogging % Test).classifier("tests"), + sbtIO, (sbtIO % Test).classifier("tests"), + utilTesting % Test, + utilCollection, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, name := "librarymanagement" ) diff --git a/librarymanagement/src/main/scala/sbt/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/ComponentManager.scala index bdf78b9ec..af4788ece 100644 --- a/librarymanagement/src/main/scala/sbt/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/ComponentManager.scala @@ -5,6 +5,7 @@ package sbt import java.io.{ File, FileOutputStream } import java.util.concurrent.Callable +import sbt.internal.util.Logger /** * A component manager provides access to the pieces of xsbt that are distributed as components. diff --git a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/ConflictWarning.scala index a4e011736..182272476 100644 --- a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala +++ b/librarymanagement/src/main/scala/sbt/ConflictWarning.scala @@ -1,6 +1,7 @@ package sbt import DependencyFilter._ +import sbt.internal.util.{ Logger, Level } /** * Provide warnings for cross version conflicts. diff --git a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala index 9e2f11f63..6658ae45d 100644 --- a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala @@ -18,6 +18,7 @@ import java.io.{ IOException, File } import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } import sbt.io.IO +import sbt.internal.util.Logger private[sbt] object ConvertResolver { import UpdateOptions.ResolverConverter diff --git a/librarymanagement/src/main/scala/sbt/Credentials.scala b/librarymanagement/src/main/scala/sbt/Credentials.scala index 9cbe9d977..8cbb5ff43 100644 --- a/librarymanagement/src/main/scala/sbt/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/Credentials.scala @@ -6,6 +6,7 @@ package sbt import java.io.File import org.apache.ivy.util.url.CredentialsStore import sbt.io.IO +import sbt.internal.util.Logger object Credentials { def apply(realm: String, host: String, userName: String, passwd: String): Credentials = diff --git a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/EvictionWarning.scala index 7a3bcaed8..55ebf052a 100644 --- a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/EvictionWarning.scala @@ -3,6 +3,7 @@ package sbt import collection.mutable import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } +import sbt.internal.util.{ Logger, ShowLines } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], diff --git a/librarymanagement/src/main/scala/sbt/Ivy.scala b/librarymanagement/src/main/scala/sbt/Ivy.scala index e9ac5a23d..fbe38619c 100644 --- a/librarymanagement/src/main/scala/sbt/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/Ivy.scala @@ -39,6 +39,8 @@ import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{ NodeSeq, Text } import scala.collection.mutable +import sbt.internal.util.Logger + final class IvySbt(val configuration: IvyConfiguration) { import configuration.baseDirectory diff --git a/librarymanagement/src/main/scala/sbt/IvyActions.scala b/librarymanagement/src/main/scala/sbt/IvyActions.scala index e3cc20602..0a6547d76 100644 --- a/librarymanagement/src/main/scala/sbt/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/IvyActions.scala @@ -17,6 +17,7 @@ import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import sbt.io.{ IO, PathFinder } +import sbt.internal.util.{ Logger, ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/librarymanagement/src/main/scala/sbt/IvyCache.scala b/librarymanagement/src/main/scala/sbt/IvyCache.scala index 1e715a278..d9c9992f6 100644 --- a/librarymanagement/src/main/scala/sbt/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/IvyCache.scala @@ -13,6 +13,7 @@ import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, R import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil import sbt.io.Path +import sbt.internal.util.Logger class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { diff --git a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala index ed8df9546..8b2855423 100644 --- a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala @@ -6,6 +6,7 @@ package sbt import java.io.File import java.net.{ URI, URL } import scala.xml.NodeSeq +import sbt.internal.util.Logger final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) diff --git a/librarymanagement/src/main/scala/sbt/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/IvyLogger.scala index 94268672e..56fa3561d 100644 --- a/librarymanagement/src/main/scala/sbt/IvyLogger.scala +++ b/librarymanagement/src/main/scala/sbt/IvyLogger.scala @@ -4,6 +4,7 @@ package sbt import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } +import sbt.internal.util.Logger /** Interface to Ivy logging. */ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { diff --git a/librarymanagement/src/main/scala/sbt/IvyScala.scala b/librarymanagement/src/main/scala/sbt/IvyScala.scala index fc9400174..f8e8c6a68 100644 --- a/librarymanagement/src/main/scala/sbt/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/IvyScala.scala @@ -11,6 +11,8 @@ import org.apache.ivy.core.module.descriptor.{ DependencyDescriptor, DefaultModu import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher +import sbt.internal.util.Logger + object ScalaArtifacts { val Organization = "org.scala-lang" val LibraryID = "scala-library" diff --git a/librarymanagement/src/main/scala/sbt/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/JsonUtil.scala index 6ee5bd68a..1e8dbd5e4 100644 --- a/librarymanagement/src/main/scala/sbt/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/JsonUtil.scala @@ -6,6 +6,7 @@ import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor import sbt.serialization._ import java.net.{ URLEncoder, URLDecoder } +import sbt.internal.util.Logger private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" diff --git a/librarymanagement/src/main/scala/sbt/MakePom.scala b/librarymanagement/src/main/scala/sbt/MakePom.scala index 472dd6cfb..663173e0d 100644 --- a/librarymanagement/src/main/scala/sbt/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/MakePom.scala @@ -8,6 +8,7 @@ package sbt import java.io.File +import sbt.internal.util.Logger import sbt.mavenint.PomExtraDependencyAttributes diff --git a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/UpdateOptions.scala index 3a710026c..159472672 100644 --- a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/UpdateOptions.scala @@ -3,6 +3,7 @@ package sbt import java.io.File import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings +import sbt.internal.util.Logger /** * Represents configurable options for update task. diff --git a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index ab0896649..34dd0c308 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -23,6 +23,7 @@ import Configurations.{ System => _, _ } import annotation.tailrec import scala.concurrent.duration._ import sbt.io.{ DirectoryFilter, Hash, IO, Path } +import sbt.internal.util.Logger private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = diff --git a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 6b1f59a15..73328ce5c 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -15,6 +15,7 @@ import org.apache.ivy.plugins.repository.url.URLResource import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } +import sbt.internal.util.Logger private[sbt] case class SbtChainResolver( name: String, diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index f4e21c4c0..8b46ccd9c 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -3,11 +3,12 @@ package sbt import sbt.io.Path._, Configurations._ import sbt.io.IO import java.io.File -import org.specs2._ import cross.CrossVersionUtil import sbt.ivyint.SbtChainResolver +import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.internal.util.UnitSpec -trait BaseIvySpecification extends Specification { +trait BaseIvySpecification extends UnitSpec { def currentBase: File = new File(".") def currentTarget: File = currentBase / "target" / "ivyhome" def currentManaged: File = currentBase / "target" / "lib_managed" diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 719431282..c4282120a 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -1,33 +1,11 @@ package sbt -import org.specs2._ +import sbt.internal.util.ShowLines class CachedResolutionSpec extends BaseIvySpecification { - def is = args(sequential = true) ^ s2""" - - This is a specification to check the cached resolution - - Resolving the same module twice should - work $e1 - - Resolving the unsolvable module should - not work $e2 - - Resolving a module with a pseudo-conflict should - work $e3 - """ - - def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) - def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile")) - def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7", Some("compile")) - def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40", Some("compile")) - def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final", Some("compile")) - - def defaultOptions = EvictionWarningOptions.default - import ShowLines._ - def e1 = { + "Resolving the same module twice" should "work" in { cleanIvyCache() val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) @@ -38,10 +16,10 @@ class CachedResolutionSpec extends BaseIvySpecification { println(report) // second resolution reads from the minigraph println(report.configurations.head.modules.head.artifacts) - report.configurations.size must_== 3 + report.configurations.size shouldBe 3 } - def e2 = { + "Resolving the unsolvable module should" should "not work" in { // log.setLevel(Level.Debug) val m = module(ModuleID("com.example", "foo", "0.2.0", Some("compile")), Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) @@ -53,11 +31,11 @@ class CachedResolutionSpec extends BaseIvySpecification { ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed 2") case Left(uw) => - uw.lines must contain(allOf("\n\tNote: Unresolved dependencies path:", + uw.lines should contain allOf("\n\tNote: Unresolved dependencies path:", "\t\tfoundrylogic.vpp:vpp:2.2.1", "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", - "\t\t +- com.example:foo:0.2.0")) + "\t\t +- com.example:foo:0.2.0") } } @@ -65,7 +43,7 @@ class CachedResolutionSpec extends BaseIvySpecification { // data-avro:1.9.40 depends on avro:1.4.0, which depends on netty:3.2.1.Final. // avro:1.4.0 will be evicted by avro:1.7.7. // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final - def e3 = { + "Resolving a module with a pseudo-conflict" should "work" in { // log.setLevel(Level.Debug) cleanIvyCache() val m = module(ModuleID("com.example", "foo", "0.3.0", Some("compile")), @@ -76,8 +54,16 @@ class CachedResolutionSpec extends BaseIvySpecification { cleanCachedResolutionCache(m) // second resolution reads from the minigraph val report = ivyUpdate(m) - val modules = report.configurations.head.modules - (modules must containMatch("""org\.jboss\.netty:netty:3\.2\.0.Final""")) and - (modules must not containMatch ("""org\.jboss\.netty:netty:3\.2\.1.Final""")) + val modules: Seq[String] = report.configurations.head.modules map {_.toString} + modules should contain("""org.jboss.netty:netty:3.2.0.Final""") + modules should not contain("""org.jboss.netty:netty:3.2.1.Final""") } + + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) + def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile")) + def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7", Some("compile")) + def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40", Some("compile")) + def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final", Some("compile")) + + def defaultOptions = EvictionWarningOptions.default } diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 29017b6a3..19c29cda8 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -2,73 +2,74 @@ package sbt import java.io.File import java.util.concurrent.Callable -import org.specs2._ -import mutable.Specification import sbt.io.IO.{ createDirectory, delete, touch, withTemporaryDirectory } import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider +import sbt.internal.util.Logger +import sbt.internal.util.{ UnitSpec, TestLogger } // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly // when it really should, instead, be stubbing out the underyling class. -object ComponentManagerTest extends Specification { +class ComponentManagerTest extends UnitSpec { val TestID = "manager-test" - "Component manager" should { - "throw an exception if 'file' is called for a non-existing component" in { - withManager { _.file(TestID)(Fail) must throwA[InvalidComponent] } + "Component manager" should "throw an exception if 'file' is called for a non-existing component" in { + withManager { manager => + intercept[InvalidComponent] { manager.file(TestID)(Fail) } } - "throw an exception if 'file' is called for an empty component" in { - withManager { manager => - manager.define(TestID, Nil) - (manager.file(TestID)(Fail)) must throwA[InvalidComponent] - } + } + it should "throw an exception if 'file' is called for an empty component" in { + withManager { manager => + manager.define(TestID, Nil) + intercept[InvalidComponent] { manager.file(TestID)(Fail) } } - "return the file for a single-file component" in { - withManager { manager => - val hash = defineFile(manager, TestID, "a") - checksum(manager.file(TestID)(Fail)) must beEqualTo(hash) - } + } + it should "return the file for a single-file component" in { + withManager { manager => + val hash = defineFile(manager, TestID, "a") + checksum(manager.file(TestID)(Fail)) shouldBe hash } - - "throw an exception if 'file' is called for multi-file component" in { - withManager { manager => - defineFiles(manager, TestID, "a", "b") - (manager.file(TestID)(Fail)) must throwA[InvalidComponent] - } + } + it should "throw an exception if 'file' is called for multi-file component" in { + withManager { manager => + defineFiles(manager, TestID, "a", "b") + intercept[InvalidComponent] { manager.file(TestID)(Fail) } } - "return the files for a multi-file component" in { - withManager { manager => - val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)(Fail)) must containTheSameElementsAs(hashes) - } + } + it should "return the files for a multi-file component" in { + withManager { manager => + val hashes = defineFiles(manager, TestID, "a", "b") + checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) } - "return the files for a single-file component" in { - withManager { manager => - val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)(Fail)) must containTheSameElementsAs(hashes) - } + } + it should "return the files for a single-file component" in { + withManager { manager => + val hashes = defineFiles(manager, TestID, "a") + checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) } - "throw an exception if 'files' is called for a non-existing component" in { - withManager { _.files(TestID)(Fail) must throwA[InvalidComponent] } + } + it should "throw an exception if 'files' is called for a non-existing component" in { + withManager { manager => + intercept[InvalidComponent] { manager.files(TestID)(Fail) } } - - "properly cache a file and then retrieve it to an unresolved component" in { - withTemporaryDirectory { ivyHome => - withManagerHome(ivyHome) { definingManager => - val hash = defineFile(definingManager, TestID, "a") - try { - definingManager.cache(TestID) - withManagerHome(ivyHome) { usingManager => - checksum(usingManager.file(TestID)(Fail)) must beEqualTo(hash) - } - } finally { definingManager.clearCache(TestID) } - } + } + it should "properly cache a file and then retrieve it to an unresolved component" in { + withTemporaryDirectory { ivyHome => + withManagerHome(ivyHome) { definingManager => + val hash = defineFile(definingManager, TestID, "a") + try { + definingManager.cache(TestID) + withManagerHome(ivyHome) { usingManager => + checksum(usingManager.file(TestID)(Fail)) shouldBe hash + } + } finally { definingManager.clearCache(TestID) } } } } + private def checksum(files: Iterable[File]): Seq[String] = files.map(checksum).toSeq private def checksum(file: File): String = if (file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" private def defineFile(manager: ComponentManager, id: String, name: String): String = createFile(manager, id, name)(checksum) diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 364d6c67e..33e1f62f2 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -1,122 +1,118 @@ package sbt import java.io.File -import org.specs2._ -import mutable.Specification +import sbt.internal.util.UnitSpec -object CrossVersionTest extends Specification { - "Cross version" should { - "return sbt API for xyz as None" in { - CrossVersion.sbtApiVersion("xyz") must_== None - } - "return sbt API for 0.12 as None" in { - CrossVersion.sbtApiVersion("0.12") must_== None - } - "return sbt API for 0.12.0-SNAPSHOT as None" in { - CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") must_== None - } - "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0-RC1") must_== Some((0, 12)) - } - "return sbt API for 0.12.0 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0") must_== Some((0, 12)) - } - "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") must_== Some((0, 12)) - } - "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-RC1") must_== Some((0, 12)) - } - "return sbt API for 0.12.1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1") must_== Some((0, 12)) - } - "return sbt API compatibility for 0.12.0-M1 as false" in { - CrossVersion.isSbtApiCompatible("0.12.0-M1") must_== false - } - "return sbt API compatibility for 0.12.0-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.0-RC1") must_== true - } - "return sbt API compatibility for 0.12.1-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.1-RC1") must_== true - } - "return binary sbt version for 0.11.3 as 0.11.3" in { - CrossVersion.binarySbtVersion("0.11.3") must_== "0.11.3" - } - "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { - CrossVersion.binarySbtVersion("0.12.0-M1") must_== "0.12.0-M1" - } - "return binary sbt version for 0.12.0-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0-RC1") must_== "0.12" - } - "return binary sbt version for 0.12.0 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0") must_== "0.12" - } - "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") must_== "0.12" - } - "return binary sbt version for 0.12.1-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-RC1") must_== "0.12" - } - "return binary sbt version for 0.12.1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1") must_== "0.12" - } - - "return Scala API for xyz as None" in { - CrossVersion.scalaApiVersion("xyz") must_== None - } - "return Scala API for 2.10 as None" in { - CrossVersion.scalaApiVersion("2.10") must_== None - } - "return Scala API for 2.10.0-SNAPSHOT as None" in { - CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") must_== None - } - "return Scala API for 2.10.0-RC1 as None" in { - CrossVersion.scalaApiVersion("2.10.0-RC1") must_== None - } - "return Scala API for 2.10.0 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0") must_== Some((2, 10)) - } - "return Scala API for 2.10.0-1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0-1") must_== Some((2, 10)) - } - "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") must_== Some((2, 10)) - } - "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-RC1") must_== Some((2, 10)) - } - "return Scala API for 2.10.1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1") must_== Some((2, 10)) - } - "return Scala API compatibility for 2.10.0-M1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-M1") must_== false - } - "return Scala API compatibility for 2.10.0-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-RC1") must_== false - } - "return Scala API compatibility for 2.10.1-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.1-RC1") must_== true - } - "return binary Scala version for 2.9.2 as 2.9.2" in { - CrossVersion.binaryScalaVersion("2.9.2") must_== "2.9.2" - } - "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { - CrossVersion.binaryScalaVersion("2.10.0-M1") must_== "2.10.0-M1" - } - "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { - CrossVersion.binaryScalaVersion("2.10.0-RC1") must_== "2.10.0-RC1" - } - "return binary Scala version for 2.10.0 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.0") must_== "2.10" - } - "return binary Scala version for 2.10.1-M1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-M1") must_== "2.10" - } - "return binary Scala version for 2.10.1-RC1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-RC1") must_== "2.10" - } - "return binary Scala version for 2.10.1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1") must_== "2.10" - } +class CrossVersionTest extends UnitSpec { + "Cross version" should "return sbt API for xyz as None" in { + CrossVersion.sbtApiVersion("xyz") shouldBe None + } + it should "return sbt API for 0.12 as None" in { + CrossVersion.sbtApiVersion("0.12") shouldBe None + } + it should "return sbt API for 0.12.0-SNAPSHOT as None" in { + CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") shouldBe None + } + it should "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0-RC1") shouldBe Some((0, 12)) + } + it should "return sbt API for 0.12.0 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.0") shouldBe Some((0, 12)) + } + it should "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") shouldBe Some((0, 12)) + } + it should "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1-RC1") shouldBe Some((0, 12)) + } + it should "return sbt API for 0.12.1 as Some((0, 12))" in { + CrossVersion.sbtApiVersion("0.12.1") shouldBe Some((0, 12)) + } + it should "return sbt API compatibility for 0.12.0-M1 as false" in { + CrossVersion.isSbtApiCompatible("0.12.0-M1") shouldBe false + } + it should "return sbt API compatibility for 0.12.0-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.0-RC1") shouldBe true + } + it should "return sbt API compatibility for 0.12.1-RC1 as true" in { + CrossVersion.isSbtApiCompatible("0.12.1-RC1") shouldBe true + } + it should "return binary sbt version for 0.11.3 as 0.11.3" in { + CrossVersion.binarySbtVersion("0.11.3") shouldBe "0.11.3" + } + it should "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { + CrossVersion.binarySbtVersion("0.12.0-M1") shouldBe "0.12.0-M1" + } + it should "return binary sbt version for 0.12.0-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0-RC1") shouldBe "0.12" + } + it should "return binary sbt version for 0.12.0 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.0") shouldBe "0.12" + } + it should "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") shouldBe "0.12" + } + it should "return binary sbt version for 0.12.1-RC1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1-RC1") shouldBe "0.12" + } + it should "return binary sbt version for 0.12.1 as 0.12" in { + CrossVersion.binarySbtVersion("0.12.1") shouldBe "0.12" + } + it should "return Scala API for xyz as None" in { + CrossVersion.scalaApiVersion("xyz") shouldBe None + } + it should "return Scala API for 2.10 as None" in { + CrossVersion.scalaApiVersion("2.10") shouldBe None + } + it should "return Scala API for 2.10.0-SNAPSHOT as None" in { + CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") shouldBe None + } + it should "return Scala API for 2.10.0-RC1 as None" in { + CrossVersion.scalaApiVersion("2.10.0-RC1") shouldBe None + } + it should "return Scala API for 2.10.0 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0") shouldBe Some((2, 10)) + } + it should "return Scala API for 2.10.0-1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.0-1") shouldBe Some((2, 10)) + } + it should "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") shouldBe Some((2, 10)) + } + it should "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1-RC1") shouldBe Some((2, 10)) + } + it should "return Scala API for 2.10.1 as Some((2, 10))" in { + CrossVersion.scalaApiVersion("2.10.1") shouldBe Some((2, 10)) + } + it should "return Scala API compatibility for 2.10.0-M1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-M1") shouldBe false + } + it should "return Scala API compatibility for 2.10.0-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.0-RC1") shouldBe false + } + it should "return Scala API compatibility for 2.10.1-RC1 as false" in { + CrossVersion.isScalaApiCompatible("2.10.1-RC1") shouldBe true + } + it should "return binary Scala version for 2.9.2 as 2.9.2" in { + CrossVersion.binaryScalaVersion("2.9.2") shouldBe "2.9.2" + } + it should "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { + CrossVersion.binaryScalaVersion("2.10.0-M1") shouldBe "2.10.0-M1" + } + it should "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { + CrossVersion.binaryScalaVersion("2.10.0-RC1") shouldBe "2.10.0-RC1" + } + it should "return binary Scala version for 2.10.0 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.0") shouldBe "2.10" + } + it should "return binary Scala version for 2.10.1-M1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-M1") shouldBe "2.10" + } + it should "return binary Scala version for 2.10.1-RC1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1-RC1") shouldBe "2.10" + } + it should "return binary Scala version for 2.10.1 as 2.10" in { + CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" } } diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 262e4a22b..c2bf9180b 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -2,36 +2,32 @@ import java.io.File import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact } import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions -import org.specs2.mutable.Specification import sbt._ import sbt.io.IO.withTemporaryDirectory +import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.internal.util.UnitSpec -object CustomPomParserTest extends Specification { +class CustomPomParserTest extends UnitSpec { + "CustomPomParser" should "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { + val log = ConsoleLogger() + withTemporaryDirectory { cacheDir => + val repoUrl = getClass.getResource("/test-maven-repo") + val local = MavenRepository("Test Repo", repoUrl.toExternalForm) + val paths = new IvyPaths(new File("."), Some(cacheDir)) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, log) + val ivySbt = new IvySbt(conf) + val resolveOpts = new ResolveOptions().setConfs(Array("default")) + val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") - "CustomPomParser" should { - "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { - val log = ConsoleLogger() - withTemporaryDirectory { cacheDir => - val repoUrl = getClass.getResource("/test-maven-repo") - val local = MavenRepository("Test Repo", repoUrl.toExternalForm) - val paths = new IvyPaths(new File("."), Some(cacheDir)) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, log) - val ivySbt = new IvySbt(conf) - val resolveOpts = new ResolveOptions().setConfs(Array("default")) - val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") - - val resolveReport = ivySbt.withIvy(log) { ivy => - ivy.resolve(mrid, resolveOpts, true) - } - - resolveReport.hasError must beFalse - resolveReport.getArtifacts.size() must beEqualTo(1) - val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) - artifact.getModuleRevisionId must beEqualTo(mrid) - artifact.getExt must beEqualTo("jar") + val resolveReport = ivySbt.withIvy(log) { ivy => + ivy.resolve(mrid, resolveOpts, true) } + resolveReport.hasError shouldBe false + resolveReport.getArtifacts.size() shouldBe 1 + val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) + artifact.getModuleRevisionId shouldBe mrid + artifact.getExt shouldBe "jar" } } - } diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index bf62de10b..532fae381 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -1,46 +1,50 @@ package sbt -import org.specs2._ -import matcher.MatchResult import java.net.URL import java.io.File import sbt.serialization._ +import sbt.internal.util.UnitSpec -class DMSerializationSpec extends Specification { - def is = sequential ^ s2""" - - This is a specification to check the serialization of dependency graph. - - CrossVersion.full should - ${roundtripStr(CrossVersion.full: sbt.CrossVersion)} - CrossVersion.binary should - ${roundtripStr(CrossVersion.binary: sbt.CrossVersion)} - CrossVersion.Disabled should - ${roundtrip(CrossVersion.Disabled: sbt.CrossVersion)} - - Artifact("foo") should - ${roundtrip(Artifact("foo"))} - Artifact("foo", "sources") should - ${roundtrip(Artifact("foo", "sources"))} - Artifact.pom("foo") should - ${roundtrip(Artifact.pom("foo"))} - Artifact("foo", url("http://example.com/")) should - ${roundtrip(Artifact("foo", new URL("http://example.com/")))} - Artifact("foo").extra(("key", "value")) should - ${roundtrip(Artifact("foo").extra(("key", "value")))} - - ModuleID("org", "name", "1.0") should - ${roundtrip(ModuleID("org", "name", "1.0"))} - - ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) should - ${roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil))} - Organization artifact report should - ${roundtripStr(organizationArtifactReportExample)} - Configuration report should - ${roundtripStr(configurationReportExample)} - Update report should - ${roundtripStr(updateReportExample)} - """ +class DMSerializationSpec extends UnitSpec { + "CrossVersion.full" should "roundtrip" in { + roundtripStr(CrossVersion.full: sbt.CrossVersion) + } + "CrossVersion.binary" should "roundtrip" in { + roundtripStr(CrossVersion.binary: sbt.CrossVersion) + } + "CrossVersion.Disabled" should "roundtrip" in { + roundtrip(CrossVersion.Disabled: sbt.CrossVersion) + } + """Artifact("foo")""" should "roundtrip" in { + roundtrip(Artifact("foo")) + } + """Artifact("foo", "sources")""" should "roundtrip" in { + roundtrip(Artifact("foo", "sources")) + } + """Artifact.pom("foo")""" should "roundtrip" in { + roundtrip(Artifact.pom("foo")) + } + """Artifact("foo", url("http://example.com/"))""" should "roundtrip" in { + roundtrip(Artifact("foo", new URL("http://example.com/"))) + } + """Artifact("foo").extra(("key", "value"))""" should "roundtrip" in { + roundtrip(Artifact("foo").extra(("key", "value"))) + } + """ModuleID("org", "name", "1.0")""" should "roundtrip" in { + roundtrip(ModuleID("org", "name", "1.0")) + } + """ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)""" should "roundtrip" in { + roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)) + } + "Organization artifact report" should "roundtrip" in { + roundtripStr(organizationArtifactReportExample) + } + "Configuration report" should "roundtrip" in { + roundtripStr(configurationReportExample) + } + "Update report" should "roundtrip" in { + roundtripStr(updateReportExample) + } lazy val updateReportExample = new UpdateReport(new File("./foo"), Vector(configurationReportExample), @@ -53,11 +57,11 @@ class DMSerializationSpec extends Specification { lazy val moduleReportExample = ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) - def roundtrip[A: Pickler: Unpickler](a: A) = - roundtripBuilder(a) { _ must_== _ } - def roundtripStr[A: Pickler: Unpickler](a: A) = - roundtripBuilder(a) { _.toString must_== _.toString } - def roundtripBuilder[A: Pickler: Unpickler](a: A)(f: (A, A) => MatchResult[Any]): MatchResult[Any] = + def roundtrip[A: Pickler: Unpickler](a: A): Unit = + roundtripBuilder(a) { _ shouldBe _ } + def roundtripStr[A: Pickler: Unpickler](a: A): Unit = + roundtripBuilder(a) { _.toString shouldBe _.toString } + def roundtripBuilder[A: Pickler: Unpickler](a: A)(f: (A, A) => Unit): Unit = { val json = toJsonString(a) println(json) diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 0e1e3dd2c..a2f30fb3b 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -1,52 +1,40 @@ package sbt -import org.specs2._ - class EvictionWarningSpec extends BaseIvySpecification { - def is = s2""" + // This is a specification to check the eviction warnings - This is a specification to check the eviction warnings + "Eviction of scala-library whose scalaVersion" should "be detected" in scalaVersionWarn1 + it should "not be detected if it's diabled" in scalaVersionWarn2 + it should "print out message about the eviction" in scalaVersionWarn3 + it should "print out message about the eviction with callers" in scalaVersionWarn4 - Eviction of scala-library whose scalaVersion should - be detected $scalaVersionWarn1 - not be detected if it's diabled $scalaVersionWarn2 - print out message about the eviction $scalaVersionWarn3 - print out message about the eviction with callers $scalaVersionWarn4 + """Including two (suspect) binary incompatible Java libraries to + direct dependencies""" should "be detected as eviction" in javaLibWarn1 + it should "not be detected if it's disabled" in javaLibWarn2 + it should "print out message about the eviction" in javaLibWarn3 + it should "print out message about the eviction with callers" in javaLibWarn4 - Including two (suspect) binary incompatible Java libraries to - direct dependencies should - be detected as eviction $javaLibWarn1 - not be detected if it's disabled $javaLibWarn2 - print out message about the eviction $javaLibWarn3 - print out message about the eviction with callers $javaLibWarn4 + """Including two (suspect) binary compatible Java libraries to + direct dependencies""" should "not be detected as eviction" in javaLibNoWarn1 + it should "print out message about the eviction" in javaLibNoWarn2 - Including two (suspect) binary compatible Java libraries to - direct dependencies should - not be detected as eviction $javaLibNoWarn1 - print out message about the eviction $javaLibNoWarn2 + """Including two (suspect) transitively binary incompatible Java libraries to + direct dependencies""" should "be not detected as eviction" in javaLibTransitiveWarn1 + it should "be detected if it's enabled" in javaLibTransitiveWarn2 + it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3 - Including two (suspect) transitively binary incompatible Java libraries to - direct dependencies should - be not detected as eviction $javaLibTransitiveWarn1 - be detected if it's enabled $javaLibTransitiveWarn2 - print out message about the eviction if it's enabled $javaLibTransitiveWarn3 + """Including two (suspect) binary incompatible Scala libraries to + direct dependencies""" should "be detected as eviction" in scalaLibWarn1 + it should "print out message about the eviction" in scalaLibWarn2 - Including two (suspect) binary incompatible Scala libraries to - direct dependencies should - be detected as eviction $scalaLibWarn1 - print out message about the eviction $scalaLibWarn2 + """Including two (suspect) binary compatible Scala libraries to + direct dependencies""" should "not be detected as eviction" in scalaLibNoWarn1 + it should "print out message about the eviction" in scalaLibNoWarn2 - Including two (suspect) binary compatible Scala libraries to - direct dependencies should - not be detected as eviction $scalaLibNoWarn1 - print out message about the eviction $scalaLibNoWarn2 - - Including two (suspect) transitively binary incompatible Scala libraries to - direct dependencies should - be not detected as eviction $scalaLibTransitiveWarn1 - be detected if it's enabled $scalaLibTransitiveWarn2 - print out message about the eviction if it's enabled $scalaLibTransitiveWarn3 - """ + """Including two (suspect) transitively binary incompatible Scala libraries to + direct dependencies""" should "be not detected as eviction" in scalaLibTransitiveWarn1 + it should "be detected if it's enabled" in scalaLibTransitiveWarn2 + it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3 def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary @@ -64,26 +52,26 @@ class EvictionWarningSpec extends BaseIvySpecification { def defaultOptions = EvictionWarningOptions.default - import ShowLines._ + import sbt.internal.util.ShowLines._ def scalaVersionDeps = Seq(scala2102, akkaActor230) def scalaVersionWarn1 = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).scalaEvictions must have size (1) + EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size(1) } def scalaVersionWarn2 = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions must have size (0) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size(0) } def scalaVersionWarn3 = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines must_== + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List("Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", "To force scalaVersion, add the following:", @@ -94,7 +82,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn4 = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines must_== + EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe List("Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", "To force scalaVersion, add the following:", @@ -106,19 +94,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn1 = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(1) } def javaLibWarn2 = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions must have size (0) + EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions should have size(0) } def javaLibWarn3 = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines must_== + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List("There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* commons-io:commons-io:1.4 -> 2.4", @@ -128,7 +116,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn4 = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines must_== + EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe List("There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)") @@ -138,14 +126,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Seq(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) } def javaLibNoWarn2 = { val deps = Seq(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines must_== Nil + EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil } def javaLibTransitiveDeps = Seq(unfilteredUploads080, bnfparser10) @@ -153,19 +141,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveWarn1 = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) } def javaLibTransitiveWarn2 = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions must have size (1) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size(1) } def javaLibTransitiveWarn3 = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines must_== + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe List("There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)") @@ -175,14 +163,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Seq(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(1) } def scalaLibWarn2 = { val deps = Seq(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines must_== + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List("There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4", @@ -193,14 +181,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Seq(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) } def scalaLibNoWarn2 = { val deps = Seq(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines must_== Nil + EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil } def scalaLibTransitiveDeps = Seq(scala2104, bananaSesame04, akkaRemote234) @@ -208,19 +196,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveWarn1 = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions must have size (0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) } def scalaLibTransitiveWarn2 = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions must have size (1) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size(1) } def scalaLibTransitiveWarn3 = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines must_== + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe List("There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)") diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index b9f4a05ef..343149e85 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -1,28 +1,20 @@ package sbt -import org.specs2._ +import sbt.internal.util.UnitSpec -class InconsistentDuplicateSpec extends Specification { - def is = s2""" +// This is a specification to check the inconsistent duplicate warnings +class InconsistentDuplicateSpec extends UnitSpec { + "Duplicate with different version" should "be warned" in { + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) shouldBe + List("Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", + " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)") + } - This is a specification to check the inconsistent duplicate warnings - - Duplicate with different version should - be warned $warn1 - - Duplicate with same version should - not be warned $nodupe1 - """ + "Duplicate with same version" should "not be warned" in { + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil + } def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("test")) cross CrossVersion.binary - - def warn1 = - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) must_== - List("Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", - " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)") - - def nodupe1 = - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) must_== Nil } diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index 68ede8bc8..edd1eef03 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -1,73 +1,78 @@ package sbt import java.io.File -import org.specs2._ +import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.internal.util.UnitSpec // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html // http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html -class MakePomSpec extends Specification { - def is = s2""" +class MakePomSpec extends UnitSpec { + // This is a specification to check the Ivy revision number conversion to pom. - This is a specification to check the Ivy revision number conversion to pom. + "1.0" should "convert to 1.0" in convertTo("1.0", "1.0") - 1.0 should - ${convertTo("1.0", "1.0")} + "[1.0,2.0]" should "convert to [1.0,2.0]" in { + convertTo("[1.0,2.0]", "[1.0,2.0]") + } - [1.0,2.0] should - ${convertTo("[1.0,2.0]", "[1.0,2.0]")} + "[1.0,2.0[" should "convert to [1.0,2.0)" in { + convertTo("[1.0,2.0[", "[1.0,2.0)") + } - [1.0,2.0[ should - ${convertTo("[1.0,2.0[", "[1.0,2.0)")} + "]1.0,2.0]" should "convert to (1.0,2.0]" in { + convertTo("]1.0,2.0]", "(1.0,2.0]") + } - ]1.0,2.0] should - ${convertTo("]1.0,2.0]", "(1.0,2.0]")} + "]1.0,2.0[" should "convert to (1.0,2.0)" in { + convertTo("]1.0,2.0[", "(1.0,2.0)") + } - ]1.0,2.0[ should - ${convertTo("]1.0,2.0[", "(1.0,2.0)")} + "[1.0,)" should "convert to [1.0,)" in { + convertTo("[1.0,)", "[1.0,)") + } - [1.0,) should - ${convertTo("[1.0,)", "[1.0,)")} + "]1.0,)" should "convert to (1.0,)" in { + convertTo("]1.0,)", "(1.0,)") + } - ]1.0,) should - ${convertTo("]1.0,)", "(1.0,)")} + "(,2.0]" should "convert to (,2.0]" in { + convertTo("(,2.0]", "(,2.0]") + } - (,2.0] should - ${convertTo("(,2.0]", "(,2.0]")} + "(,2.0[" should "convert to (,2.0)" in { + convertTo("(,2.0[", "(,2.0)") + } - (,2.0[ should - ${convertTo("(,2.0[", "(,2.0)")} + "1.+" should "convert to [1,2)" in { + convertTo("1.+", "[1,2)") + } - 1.+ should - ${convertTo("1.+", "[1,2)")} + "1.2.3.4.+" should "convert to [1.2.3.4,1.2.3.5)" in { + convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)") + } - 1.2.3.4.+ should - ${convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)")} + "12.31.42.+" should "convert to [12.31.42,12.31.43)" in { + convertTo("12.31.42.+", "[12.31.42,12.31.43)") + } - 12.31.42.+ should - ${convertTo("12.31.42.+", "[12.31.42,12.31.43)")} + "1.1+" should "convert to [1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)" in { + convertTo("1.1+", "[1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)") + } - 1.1+ should - ${convertTo("1.1+", "[1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)")} + "1+" should "convert to [1,2),[10,20),[100,200),[1000,2000),[10000,20000)" in { + convertTo("1+", "[1,2),[10,20),[100,200),[1000,2000),[10000,20000)") + } - 1+ should - ${convertTo("1+", "[1,2),[10,20),[100,200),[1000,2000),[10000,20000)")} + "+" should "convert to [0,)" in convertTo("+", "[0,)") - + should - ${convertTo("+", "[0,)")} - - foo+ should - ${beParsedAsError("foo+")} - """ + "foo+" should "convert to foo+" in beParsedAsError("foo+") val mp = new MakePom(ConsoleLogger()) - def convertTo(s: String, expected: String) = - MakePom.makeDependencyVersion(s) must_== expected - def beParsedAsError(s: String) = - try { + def convertTo(s: String, expected: String): Unit = + MakePom.makeDependencyVersion(s) shouldBe expected + def beParsedAsError(s: String): Unit = + intercept[Throwable] { MakePom.makeDependencyVersion(s) - failure - } catch { - case e: Throwable => success } } diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index 64c6ab777..adfb9c576 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -1,24 +1,19 @@ import java.net.URL -import org.specs2.mutable.Specification import sbt._ +import sbt.internal.util.UnitSpec -object ResolverTest extends Specification { +object ResolverTest extends UnitSpec { - "Resolver" should { - "url" should { - "propagate pattern descriptorOptional and skipConsistencyCheck." in { - val pats = Seq("[orgPath]") - val patsExpected = Seq("http://foo.com/test/[orgPath]") - val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns + "Resolver url" should "propagate pattern descriptorOptional and skipConsistencyCheck." in { + val pats = Seq("[orgPath]") + val patsExpected = Seq("http://foo.com/test/[orgPath]") + val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns - patterns.ivyPatterns must equalTo(patsExpected) - patterns.artifactPatterns must equalTo(patsExpected) - patterns.isMavenCompatible must beFalse - patterns.skipConsistencyCheck must beTrue - patterns.descriptorOptional must beTrue - } - } + patterns.ivyPatterns shouldBe patsExpected + patterns.artifactPatterns shouldBe patsExpected + patterns.isMavenCompatible shouldBe false + assert(patterns.skipConsistencyCheck) + assert(patterns.descriptorOptional) } - } diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala index 68bc2ad6e..3e7b8c631 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/librarymanagement/src/test/scala/VersionNumberSpec.scala @@ -1,112 +1,93 @@ package sbt -import org.specs2._ +import sbt.internal.util.UnitSpec -class VersionNumberSpec extends Specification { - def is = s2""" +// This is a specification to check the version number parsing. +class VersionNumberSpec extends UnitSpec { + "1" should "be parsed" in beParsedAs("1", Seq(1), Seq(), Seq()) + it should "breakdown" in breakDownTo("1", Some(1)) + it should "cascade" in generateCorrectCascadingNumbers("1", Seq("1")) - This is a specification to check the version number parsing. + "1.0" should "be parsed" in beParsedAs("1.0", Seq(1, 0), Seq(), Seq()) + it should "breakdown" in breakDownTo("1.0", Some(1), Some(0)) + it should "cascade" in generateCorrectCascadingNumbers("1.0", Seq("1.0")) - 1 should - ${beParsedAs("1", Seq(1), Seq(), Seq())} - ${breakDownTo("1", Some(1))} - ${generateCorrectCascadingNumbers("1", Seq("1"))} + "1.0.0" should "be parsed" in beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq()) + it should "breakdown" in breakDownTo("1.0.0", Some(1), Some(0), Some(0)) + it should "cascade" in generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0")) + it should "be SemVer compat with 1.0.1" in beSemVerCompatWith("1.0.0", "1.0.1") + it should "be SemVer compat with 1.1.1" in beSemVerCompatWith("1.0.0", "1.1.1") + it should "not be SemVer compat with 2.0.0" in notBeSemVerCompatWith("1.0.0", "2.0.0") + it should "not be SemVer compat with 1.0.0-M1" in notBeSemVerCompatWith("1.0.0", "1.0.0-M1") + it should "be SecSeg compat with 1.0.1" in beSecSegCompatWith("1.0.0", "1.0.1") + it should "not be SecSeg compat with 1.1.1" in notBeSecSegCompatWith("1.0.0", "1.1.1") + it should "not be SecSeg compat with 2.0.0" in notBeSecSegCompatWith("1.0.0", "2.0.0") + it should "not be SecSeg compat with 1.0.0-M1" in notBeSecSegCompatWith("1.0.0", "1.0.0-M1") - 1.0 should - ${beParsedAs("1.0", Seq(1, 0), Seq(), Seq())} - ${breakDownTo("1.0", Some(1), Some(0))} - ${generateCorrectCascadingNumbers("1.0", Seq("1.0"))} + "1.0.0.0" should "be parsed" in beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq()) + it should "breakdown" in breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0)) + it should "cascade" in generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0")) - 1.0.0 should - ${beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq())} - ${breakDownTo("1.0.0", Some(1), Some(0), Some(0))} - ${generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0"))} + "0.12.0" should "be parsed" in beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq()) + it should "breakdown" in breakDownTo("0.12.0", Some(0), Some(12), Some(0)) + it should "cascade" in generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12")) + it should "not be SemVer compat with 0.12.0-RC1" in notBeSemVerCompatWith("0.12.0", "0.12.0-RC1") + it should "not be SemVer compat with 0.12.1" in notBeSemVerCompatWith("0.12.0", "0.12.1") + it should "not be SemVer compat with 0.12.1-M1" in notBeSemVerCompatWith("0.12.0", "0.12.1-M1") + it should "not be SecSeg compat with 0.12.0-RC1" in notBeSecSegCompatWith("0.12.0", "0.12.0-RC1") + it should "be SecSeg compat with 0.12.1" in beSecSegCompatWith("0.12.0", "0.12.1") + it should "be SecSeg compat with 0.12.1-M1" in beSecSegCompatWith("0.12.0", "0.12.1-M1") - ${beSemVerCompatWith("1.0.0", "1.0.1")} - ${beSemVerCompatWith("1.0.0", "1.1.1")} - ${notBeSemVerCompatWith("1.0.0", "2.0.0")} - ${notBeSemVerCompatWith("1.0.0", "1.0.0-M1")} + "0.1.0-SNAPSHOT" should "be parsed" in beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) + it should "be SemVer compat with 0.1.0-SNAPSHOT" in beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT") + it should "not be SemVer compat with 0.1.0" in notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0") + it should "be SemVer compat with 0.1.0-SNAPSHOT+001" in beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001") + it should "be SecSeg compat with 0.1.0-SNAPSHOT" in beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT") + it should "be not SecSeg compat with 0.1.0" in notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0") + it should "be SecSeg compat with 0.1.0-SNAPSHOT+001" in beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001") - ${beSecSegCompatWith("1.0.0", "1.0.1")} - ${notBeSecSegCompatWith("1.0.0", "1.1.1")} - ${notBeSecSegCompatWith("1.0.0", "2.0.0")} - ${notBeSecSegCompatWith("1.0.0", "1.0.0-M1")} + "0.1.0-M1" should "be parsed" in beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-M1", Seq("0.1.0-M1", "0.1.0", "0.1")) - 1.0.0.0 should - ${beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq())} - ${breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0))} - ${generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0"))} + "0.1.0-RC1" should "be parsed" in beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-RC1", Seq("0.1.0-RC1", "0.1.0", "0.1")) - 0.12.0 should - ${beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq())} - ${breakDownTo("0.12.0", Some(0), Some(12), Some(0))} - ${generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12"))} - - ${notBeSemVerCompatWith("0.12.0", "0.12.0-RC1")} - ${notBeSemVerCompatWith("0.12.0", "0.12.1")} - ${notBeSemVerCompatWith("0.12.0", "0.12.1-M1")} - - ${notBeSecSegCompatWith("0.12.0", "0.12.0-RC1")} - ${beSecSegCompatWith("0.12.0", "0.12.1")} - ${beSecSegCompatWith("0.12.0", "0.12.1-M1")} - - 0.1.0-SNAPSHOT should - ${beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())} - ${generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))} - - ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} - ${notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0")} - ${beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001")} - - ${beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT")} - ${notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0")} - ${beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001")} - - 0.1.0-M1 should - ${beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq())} - ${generateCorrectCascadingNumbers("0.1.0-M1", Seq("0.1.0-M1", "0.1.0", "0.1"))} - - 0.1.0-RC1 should - ${beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq())} - ${generateCorrectCascadingNumbers("0.1.0-RC1", Seq("0.1.0-RC1", "0.1.0", "0.1"))} - - 0.1.0-MSERVER-1 should - ${beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())} - ${generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))} + "0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) - 2.10.4-20140115-000117-b3a-sources should - ${beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())} - ${generateCorrectCascadingNumbers("2.10.4-20140115-000117-b3a-sources", Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))} + "2.10.4-20140115-000117-b3a-sources" should "be parsed" in { + beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) + } + it should "cascade" in generateCorrectCascadingNumbers("2.10.4-20140115-000117-b3a-sources", Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) + it should "be SemVer compat with 2.0.0" in beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0") + it should "be not SecSeg compat with 2.0.0" in notBeSecSegCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0") - ${beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} + "20140115000117-b3a-sources" should "be parsed" in { + beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq()) + } + it should "cascade" in generateCorrectCascadingNumbers("20140115000117-b3a-sources", Seq("20140115000117-b3a-sources")) - ${notBeSecSegCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0")} + "1.0.0-alpha+001+002" should "be parsed" in { + beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) + } + it should "cascade" in generateCorrectCascadingNumbers("1.0.0-alpha+001+002", Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) - 20140115000117-b3a-sources should - ${beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq())} - ${generateCorrectCascadingNumbers("20140115000117-b3a-sources", Seq("20140115000117-b3a-sources"))} + "non.space.!?string" should "be parsed" in { + beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string")) + } + it should "cascade" in generateCorrectCascadingNumbers("non.space.!?string", Seq("non.space.!?string")) - 1.0.0-alpha+001+002 should - ${beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))} - ${generateCorrectCascadingNumbers("1.0.0-alpha+001+002", Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))} + "space !?string" should "be parsed as an error" in beParsedAsError("space !?string") + "blank string" should "be parsed as an error" in beParsedAsError("") - non.space.!?string should - ${beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string"))} - ${generateCorrectCascadingNumbers("non.space.!?string", Seq("non.space.!?string"))} - - space !?string should - ${beParsedAsError("space !?string")} - - blank string should - ${beParsedAsError("")} - """ def beParsedAs(s: String, ns: Seq[Long], ts: Seq[String], es: Seq[String]) = s match { case VersionNumber(ns1, ts1, es1) if (ns1 == ns && ts1 == ts && es1 == es) => - (VersionNumber(ns, ts, es).toString must_== s) and - (VersionNumber(ns, ts, es) == VersionNumber(ns, ts, es)) + (VersionNumber(ns, ts, es).toString shouldBe s) + (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) case VersionNumber(ns1, ts1, es1) => sys.error(s"$ns1, $ts1, $es1") } @@ -115,26 +96,26 @@ class VersionNumberSpec extends Specification { s match { case VersionNumber(ns, ts, es) => val v = VersionNumber(ns, ts, es) - (v._1 must_== major) and - (v._2 must_== minor) and - (v._3 must_== patch) and - (v._4 must_== buildNumber) + (v._1 shouldBe major) + (v._2 shouldBe minor) + (v._3 shouldBe patch) + (v._4 shouldBe buildNumber) } - def beParsedAsError(s: String) = + def beParsedAsError(s: String): Unit = s match { - case VersionNumber(ns1, ts1, es1) => failure - case _ => success + case VersionNumber(ns1, ts1, es1) => sys.error(s) + case _ => () } def beSemVerCompatWith(v1: String, v2: String) = - VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true + VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true def notBeSemVerCompatWith(v1: String, v2: String) = - VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false + VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false def beSecSegCompatWith(v1: String, v2: String) = - VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== true + VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true def notBeSecSegCompatWith(v1: String, v2: String) = - VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) must_== false + VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false def generateCorrectCascadingNumbers(s: String, ns: Seq[String]) = { val versionNumbers = ns.toVector map VersionNumber.apply - VersionNumber(s).cascadingVersions must_== versionNumbers + VersionNumber(s).cascadingVersions shouldBe versionNumbers } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 92f1a778d..155785557 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,11 +5,12 @@ object Dependencies { lazy val scala210 = "2.10.5" lazy val scala211 = "2.11.7" - val utilVersion = "0.1.0-M1" - val ioVersion = "1.0.0-M1" + val utilVersion = "0.1.0-M2" + val ioVersion = "1.0.0-M3" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion + lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" From a30bcdbb37da43c07794454478fc5649874ccb3e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 5 Sep 2015 05:53:15 -0400 Subject: [PATCH 0448/1030] Fix test --- librarymanagement/src/test/scala/CachedResolutionSpec.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index c4282120a..48ee003c0 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -55,8 +55,8 @@ class CachedResolutionSpec extends BaseIvySpecification { // second resolution reads from the minigraph val report = ivyUpdate(m) val modules: Seq[String] = report.configurations.head.modules map {_.toString} - modules should contain("""org.jboss.netty:netty:3.2.0.Final""") - modules should not contain("""org.jboss.netty:netty:3.2.1.Final""") + assert(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.0.Final"""}) + assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final"""})) } def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) From c65c5016b08832f18b021b462db14fb794447911 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 7 Sep 2015 02:59:23 -0400 Subject: [PATCH 0449/1030] bump to up Util 0.1.0-M3 --- librarymanagement/src/main/scala/sbt/ComponentManager.scala | 2 +- librarymanagement/src/main/scala/sbt/ConflictWarning.scala | 2 +- librarymanagement/src/main/scala/sbt/ConvertResolver.scala | 2 +- librarymanagement/src/main/scala/sbt/Credentials.scala | 2 +- librarymanagement/src/main/scala/sbt/EvictionWarning.scala | 3 ++- librarymanagement/src/main/scala/sbt/Ivy.scala | 2 +- librarymanagement/src/main/scala/sbt/IvyActions.scala | 3 ++- librarymanagement/src/main/scala/sbt/IvyCache.scala | 2 +- librarymanagement/src/main/scala/sbt/IvyConfigurations.scala | 2 +- librarymanagement/src/main/scala/sbt/IvyLogger.scala | 2 +- librarymanagement/src/main/scala/sbt/IvyScala.scala | 2 +- librarymanagement/src/main/scala/sbt/JsonUtil.scala | 2 +- librarymanagement/src/main/scala/sbt/MakePom.scala | 2 +- librarymanagement/src/main/scala/sbt/UpdateOptions.scala | 2 +- .../main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala | 2 +- .../src/main/scala/sbt/ivyint/SbtChainResolver.scala | 2 +- librarymanagement/src/test/scala/BaseIvySpecification.scala | 3 ++- librarymanagement/src/test/scala/ComponentManagerTest.scala | 2 +- librarymanagement/src/test/scala/CustomPomParserTest.scala | 3 ++- librarymanagement/src/test/scala/MakePomSpec.scala | 3 ++- project/Dependencies.scala | 2 +- 21 files changed, 26 insertions(+), 21 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/ComponentManager.scala index af4788ece..3dd08c928 100644 --- a/librarymanagement/src/main/scala/sbt/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/ComponentManager.scala @@ -5,7 +5,7 @@ package sbt import java.io.{ File, FileOutputStream } import java.util.concurrent.Callable -import sbt.internal.util.Logger +import sbt.util.Logger /** * A component manager provides access to the pieces of xsbt that are distributed as components. diff --git a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/ConflictWarning.scala index 182272476..75a4a5bd9 100644 --- a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala +++ b/librarymanagement/src/main/scala/sbt/ConflictWarning.scala @@ -1,7 +1,7 @@ package sbt import DependencyFilter._ -import sbt.internal.util.{ Logger, Level } +import sbt.util.{ Logger, Level } /** * Provide warnings for cross version conflicts. diff --git a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala index 6658ae45d..5234ca506 100644 --- a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/ConvertResolver.scala @@ -18,7 +18,7 @@ import java.io.{ IOException, File } import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } import sbt.io.IO -import sbt.internal.util.Logger +import sbt.util.Logger private[sbt] object ConvertResolver { import UpdateOptions.ResolverConverter diff --git a/librarymanagement/src/main/scala/sbt/Credentials.scala b/librarymanagement/src/main/scala/sbt/Credentials.scala index 8cbb5ff43..e2bd74fed 100644 --- a/librarymanagement/src/main/scala/sbt/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/Credentials.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import org.apache.ivy.util.url.CredentialsStore import sbt.io.IO -import sbt.internal.util.Logger +import sbt.util.Logger object Credentials { def apply(realm: String, host: String, userName: String, passwd: String): Credentials = diff --git a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/EvictionWarning.scala index 55ebf052a..4d6618b3c 100644 --- a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/EvictionWarning.scala @@ -3,7 +3,8 @@ package sbt import collection.mutable import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } -import sbt.internal.util.{ Logger, ShowLines } +import sbt.util.Logger +import sbt.internal.util.ShowLines final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], diff --git a/librarymanagement/src/main/scala/sbt/Ivy.scala b/librarymanagement/src/main/scala/sbt/Ivy.scala index fbe38619c..92079f6e8 100644 --- a/librarymanagement/src/main/scala/sbt/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/Ivy.scala @@ -39,7 +39,7 @@ import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.{ NodeSeq, Text } import scala.collection.mutable -import sbt.internal.util.Logger +import sbt.util.Logger final class IvySbt(val configuration: IvyConfiguration) { import configuration.baseDirectory diff --git a/librarymanagement/src/main/scala/sbt/IvyActions.scala b/librarymanagement/src/main/scala/sbt/IvyActions.scala index 0a6547d76..2480b92b1 100644 --- a/librarymanagement/src/main/scala/sbt/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/IvyActions.scala @@ -17,7 +17,8 @@ import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import sbt.io.{ IO, PathFinder } -import sbt.internal.util.{ Logger, ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } +import sbt.util.Logger +import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/librarymanagement/src/main/scala/sbt/IvyCache.scala b/librarymanagement/src/main/scala/sbt/IvyCache.scala index d9c9992f6..52f6ed50e 100644 --- a/librarymanagement/src/main/scala/sbt/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/IvyCache.scala @@ -13,7 +13,7 @@ import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, R import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil import sbt.io.Path -import sbt.internal.util.Logger +import sbt.util.Logger class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { diff --git a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala index 8b2855423..f03deb071 100644 --- a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala @@ -6,7 +6,7 @@ package sbt import java.io.File import java.net.{ URI, URL } import scala.xml.NodeSeq -import sbt.internal.util.Logger +import sbt.util.Logger final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) diff --git a/librarymanagement/src/main/scala/sbt/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/IvyLogger.scala index 56fa3561d..60d8c4616 100644 --- a/librarymanagement/src/main/scala/sbt/IvyLogger.scala +++ b/librarymanagement/src/main/scala/sbt/IvyLogger.scala @@ -4,7 +4,7 @@ package sbt import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } -import sbt.internal.util.Logger +import sbt.util.Logger /** Interface to Ivy logging. */ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { diff --git a/librarymanagement/src/main/scala/sbt/IvyScala.scala b/librarymanagement/src/main/scala/sbt/IvyScala.scala index f8e8c6a68..ea82f44ce 100644 --- a/librarymanagement/src/main/scala/sbt/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/IvyScala.scala @@ -11,7 +11,7 @@ import org.apache.ivy.core.module.descriptor.{ DependencyDescriptor, DefaultModu import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher -import sbt.internal.util.Logger +import sbt.util.Logger object ScalaArtifacts { val Organization = "org.scala-lang" diff --git a/librarymanagement/src/main/scala/sbt/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/JsonUtil.scala index 1e8dbd5e4..f83ee21ff 100644 --- a/librarymanagement/src/main/scala/sbt/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/JsonUtil.scala @@ -6,7 +6,7 @@ import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor import sbt.serialization._ import java.net.{ URLEncoder, URLDecoder } -import sbt.internal.util.Logger +import sbt.util.Logger private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" diff --git a/librarymanagement/src/main/scala/sbt/MakePom.scala b/librarymanagement/src/main/scala/sbt/MakePom.scala index 663173e0d..2f4640c39 100644 --- a/librarymanagement/src/main/scala/sbt/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/MakePom.scala @@ -8,7 +8,7 @@ package sbt import java.io.File -import sbt.internal.util.Logger +import sbt.util.Logger import sbt.mavenint.PomExtraDependencyAttributes diff --git a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/UpdateOptions.scala index 159472672..91fa7902d 100644 --- a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/UpdateOptions.scala @@ -3,7 +3,7 @@ package sbt import java.io.File import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings -import sbt.internal.util.Logger +import sbt.util.Logger /** * Represents configurable options for update task. diff --git a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala index 34dd0c308..1fc3291a4 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala @@ -23,7 +23,7 @@ import Configurations.{ System => _, _ } import annotation.tailrec import scala.concurrent.duration._ import sbt.io.{ DirectoryFilter, Hash, IO, Path } -import sbt.internal.util.Logger +import sbt.util.Logger private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = diff --git a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala index 73328ce5c..2ca80898f 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.repository.url.URLResource import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } -import sbt.internal.util.Logger +import sbt.util.Logger private[sbt] case class SbtChainResolver( name: String, diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 8b46ccd9c..a9936e956 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -5,7 +5,8 @@ import sbt.io.IO import java.io.File import cross.CrossVersionUtil import sbt.ivyint.SbtChainResolver -import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.util.Logger +import sbt.internal.util.ConsoleLogger import sbt.internal.util.UnitSpec trait BaseIvySpecification extends UnitSpec { diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 19c29cda8..22923f62f 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -7,7 +7,7 @@ import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider -import sbt.internal.util.Logger +import sbt.util.Logger import sbt.internal.util.{ UnitSpec, TestLogger } // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index c2bf9180b..e8319ba2b 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -4,7 +4,8 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions import sbt._ import sbt.io.IO.withTemporaryDirectory -import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.util.Logger +import sbt.internal.util.ConsoleLogger import sbt.internal.util.UnitSpec class CustomPomParserTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index edd1eef03..5f0513556 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -1,7 +1,8 @@ package sbt import java.io.File -import sbt.internal.util.{ Logger, ConsoleLogger } +import sbt.util.Logger +import sbt.internal.util.ConsoleLogger import sbt.internal.util.UnitSpec // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 155785557..ee5217690 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ object Dependencies { lazy val scala210 = "2.10.5" lazy val scala211 = "2.11.7" - val utilVersion = "0.1.0-M2" + val utilVersion = "0.1.0-M3" val ioVersion = "1.0.0-M3" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion From 1232a010371750d013778e35e0a68de622ea64b9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 7 Sep 2015 04:33:45 -0400 Subject: [PATCH 0450/1030] Put things into sbt.librarymanagement package --- .../librarymanagement}/ResolverAdapter.java | 2 +- .../mavenint/SbtPomExtraProperties.java | 2 +- .../librarymanagement}/ComponentManager.scala | 3 ++- .../librarymanagement}/ConvertResolver.scala | 3 ++- .../librarymanagement}/CustomPomParser.scala | 5 +++-- .../librarymanagement}/CustomXmlParser.scala | 3 ++- .../librarymanagement}/DependencyFilter.scala | 3 ++- .../{ => internal/librarymanagement}/Ivy.scala | 8 ++++---- .../librarymanagement}/IvyActions.scala | 3 ++- .../librarymanagement}/IvyCache.scala | 3 ++- .../librarymanagement}/IvyConfigurations.scala | 3 ++- .../librarymanagement}/IvyLogger.scala | 3 ++- .../librarymanagement}/IvyRetrieve.scala | 3 ++- .../librarymanagement}/IvyUtil.scala | 2 +- .../librarymanagement}/JsonUtil.scala | 3 ++- .../librarymanagement}/LogicalClock.scala | 2 +- .../librarymanagement}/MakePom.scala | 7 ++++--- .../librarymanagement}/ProjectResolver.scala | 3 ++- .../librarymanagement}/ResolutionCache.scala | 3 ++- .../librarymanagement}/SbtExclusionRule.scala | 5 +++-- .../librarymanagement}/StringUtilities.scala | 2 +- .../cross/CrossVersionUtil.scala | 3 ++- .../impl/DependencyBuilders.scala | 3 ++- .../ivyint/CachedResolutionResolveEngine.scala | 5 +++-- .../ivyint/CustomMavenResolver.scala | 3 ++- .../ivyint/ErrorMessageAuthenticator.scala | 2 +- .../ivyint/IvyCredentialsLookup.scala | 2 +- .../ivyint/MergeDescriptors.scala | 2 +- .../ivyint/SbtChainResolver.scala | 3 ++- .../ivyint/SbtDefaultDependencyDescriptor.scala | 3 ++- .../mavenint/PomExtraDependencyAttributes.scala | 3 ++- .../sbt/{ => librarymanagement}/Artifact.scala | 2 +- .../CircularDependencyLevel.scala | 2 +- .../{ => librarymanagement}/Configuration.scala | 2 +- .../{ => librarymanagement}/ConflictWarning.scala | 15 ++------------- .../sbt/{ => librarymanagement}/Credentials.scala | 3 ++- .../{ => librarymanagement}/CrossVersion.scala | 5 +++-- .../{ => librarymanagement}/EvictionWarning.scala | 3 ++- .../{ => librarymanagement}/IvyInterface.scala | 2 +- .../sbt/{ => librarymanagement}/IvyScala.scala | 5 ++--- .../sbt/{ => librarymanagement}/ModuleID.scala | 4 ++-- .../sbt/{ => librarymanagement}/Resolver.scala | 2 +- .../{ => librarymanagement}/UpdateOptions.scala | 2 +- .../{ => librarymanagement}/UpdateReport.scala | 10 ++++++---- .../{ => librarymanagement}/VersionNumber.scala | 2 +- .../src/test/scala/BaseIvySpecification.scala | 8 +++++--- .../src/test/scala/CachedResolutionSpec.scala | 3 ++- .../src/test/scala/ComponentManagerTest.scala | 2 +- .../src/test/scala/CrossVersionTest.scala | 2 +- .../src/test/scala/CustomPomParserTest.scala | 4 +++- .../src/test/scala/DMSerializationSpec.scala | 8 ++++---- .../src/test/scala/EvictionWarningSpec.scala | 4 +++- .../test/scala/InconsistentDuplicateSpec.scala | 3 ++- .../src/test/scala/MakePomSpec.scala | 2 +- .../src/test/scala/ResolverTest.scala | 2 ++ .../src/test/scala/VersionNumberSpec.scala | 2 +- 56 files changed, 112 insertions(+), 87 deletions(-) rename librarymanagement/src/main/java/sbt/{ => internal/librarymanagement}/ResolverAdapter.java (90%) rename librarymanagement/src/main/java/sbt/{ => internal/librarymanagement}/mavenint/SbtPomExtraProperties.java (94%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ComponentManager.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ConvertResolver.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/CustomPomParser.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/CustomXmlParser.scala (95%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/DependencyFilter.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/Ivy.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyActions.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyCache.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyConfigurations.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyLogger.scala (96%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyRetrieve.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/IvyUtil.scala (79%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/JsonUtil.scala (97%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/LogicalClock.scala (94%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/MakePom.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ProjectResolver.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ResolutionCache.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/SbtExclusionRule.scala (93%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/StringUtilities.scala (92%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/cross/CrossVersionUtil.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/impl/DependencyBuilders.scala (97%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/CachedResolutionResolveEngine.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/CustomMavenResolver.scala (80%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/ErrorMessageAuthenticator.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/IvyCredentialsLookup.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/MergeDescriptors.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/SbtChainResolver.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/ivyint/SbtDefaultDependencyDescriptor.scala (75%) rename librarymanagement/src/main/scala/sbt/{ => internal/librarymanagement}/mavenint/PomExtraDependencyAttributes.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/Artifact.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/CircularDependencyLevel.scala (97%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/Configuration.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/ConflictWarning.scala (78%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/Credentials.scala (97%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/CrossVersion.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/EvictionWarning.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/IvyInterface.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/IvyScala.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/ModuleID.scala (98%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/Resolver.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/UpdateOptions.scala (99%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/UpdateReport.scala (97%) rename librarymanagement/src/main/scala/sbt/{ => librarymanagement}/VersionNumber.scala (99%) diff --git a/librarymanagement/src/main/java/sbt/ResolverAdapter.java b/librarymanagement/src/main/java/sbt/internal/librarymanagement/ResolverAdapter.java similarity index 90% rename from librarymanagement/src/main/java/sbt/ResolverAdapter.java rename to librarymanagement/src/main/java/sbt/internal/librarymanagement/ResolverAdapter.java index 4247c97e7..86894b0bb 100644 --- a/librarymanagement/src/main/java/sbt/ResolverAdapter.java +++ b/librarymanagement/src/main/java/sbt/internal/librarymanagement/ResolverAdapter.java @@ -1,4 +1,4 @@ -package sbt; +package sbt.internal.librarymanagement; import java.util.Map; import org.apache.ivy.plugins.resolver.DependencyResolver; diff --git a/librarymanagement/src/main/java/sbt/mavenint/SbtPomExtraProperties.java b/librarymanagement/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java similarity index 94% rename from librarymanagement/src/main/java/sbt/mavenint/SbtPomExtraProperties.java rename to librarymanagement/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java index fde6af15b..83addbc46 100644 --- a/librarymanagement/src/main/java/sbt/mavenint/SbtPomExtraProperties.java +++ b/librarymanagement/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java @@ -1,4 +1,4 @@ -package sbt.mavenint; +package sbt.internal.librarymanagement.mavenint; /** * Extra properties we dump from Aether into the properties list. diff --git a/librarymanagement/src/main/scala/sbt/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/ComponentManager.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 3dd08c928..ba27eb76c 100644 --- a/librarymanagement/src/main/scala/sbt/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -1,11 +1,12 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.{ File, FileOutputStream } import java.util.concurrent.Callable import sbt.util.Logger +import sbt.librarymanagement._ /** * A component manager provides access to the pieces of xsbt that are distributed as components. diff --git a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/ConvertResolver.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 5234ca506..7029f19e0 100644 --- a/librarymanagement/src/main/scala/sbt/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.net.URL import java.util.Collections @@ -19,6 +19,7 @@ import org.apache.ivy.util.{ FileUtil, ChecksumHelper } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } import sbt.io.IO import sbt.util.Logger +import sbt.librarymanagement._ private[sbt] object ConvertResolver { import UpdateOptions.ResolverConverter diff --git a/librarymanagement/src/main/scala/sbt/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/CustomPomParser.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 8cf372af0..c75565daf 100644 --- a/librarymanagement/src/main/scala/sbt/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } @@ -12,8 +12,9 @@ import org.apache.ivy.util.extendable.ExtendableItem import java.io.{ File, InputStream } import java.net.URL import java.util.regex.Pattern -import sbt.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } +import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } import sbt.io.Hash +import sbt.librarymanagement._ @deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { diff --git a/librarymanagement/src/main/scala/sbt/CustomXmlParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala similarity index 95% rename from librarymanagement/src/main/scala/sbt/CustomXmlParser.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index bc8d7544b..cad47b173 100644 --- a/librarymanagement/src/main/scala/sbt/CustomXmlParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.ByteArrayInputStream import java.net.URL @@ -11,6 +11,7 @@ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.repository.url.URLResource +import sbt.librarymanagement._ /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { diff --git a/librarymanagement/src/main/scala/sbt/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/DependencyFilter.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala index 701d179aa..3b0cc28ef 100644 --- a/librarymanagement/src/main/scala/sbt/DependencyFilter.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala @@ -1,9 +1,10 @@ /* sbt -- Simple Build Tool * Copyright 2011 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import sbt.io.{ AllPassFilter, NameFilter } +import sbt.librarymanagement._ trait DependencyFilterExtra { def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = diff --git a/librarymanagement/src/main/scala/sbt/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/Ivy.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 92079f6e8..a2709140a 100644 --- a/librarymanagement/src/main/scala/sbt/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -1,10 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt - -import Resolver.PluginPattern -import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } +package sbt.internal.librarymanagement import java.io.File import java.net.URI @@ -40,6 +37,9 @@ import scala.xml.{ NodeSeq, Text } import scala.collection.mutable import sbt.util.Logger +import sbt.librarymanagement._ +import Resolver.PluginPattern +import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } final class IvySbt(val configuration: IvyConfiguration) { import configuration.baseDirectory diff --git a/librarymanagement/src/main/scala/sbt/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/IvyActions.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 2480b92b1..d5cc59781 100644 --- a/librarymanagement/src/main/scala/sbt/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.File import scala.xml.{ Node => XNode, NodeSeq } @@ -19,6 +19,7 @@ import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import sbt.io.{ IO, PathFinder } import sbt.util.Logger import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } +import sbt.librarymanagement._ final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/librarymanagement/src/main/scala/sbt/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/IvyCache.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 52f6ed50e..aee827923 100644 --- a/librarymanagement/src/main/scala/sbt/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.net.URL @@ -14,6 +14,7 @@ import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil import sbt.io.Path import sbt.util.Logger +import sbt.librarymanagement._ class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { diff --git a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/IvyConfigurations.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index f03deb071..9b35425ef 100644 --- a/librarymanagement/src/main/scala/sbt/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -1,12 +1,13 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.net.{ URI, URL } import scala.xml.NodeSeq import sbt.util.Logger +import sbt.librarymanagement._ final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) diff --git a/librarymanagement/src/main/scala/sbt/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala similarity index 96% rename from librarymanagement/src/main/scala/sbt/IvyLogger.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index 60d8c4616..b5d61fc06 100644 --- a/librarymanagement/src/main/scala/sbt/IvyLogger.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -1,10 +1,11 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } import sbt.util.Logger +import sbt.librarymanagement._ /** Interface to Ivy logging. */ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { diff --git a/librarymanagement/src/main/scala/sbt/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/IvyRetrieve.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 14ad917fa..8e10b0633 100644 --- a/librarymanagement/src/main/scala/sbt/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.{ util => ju } @@ -14,6 +14,7 @@ import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveRepor import resolve.{ IvyNode, IvyNodeCallers } import IvyNodeCallers.{ Caller => IvyCaller } import ivyint.SbtDefaultDependencyDescriptor +import sbt.librarymanagement._ object IvyRetrieve { def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = diff --git a/librarymanagement/src/main/scala/sbt/IvyUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala similarity index 79% rename from librarymanagement/src/main/scala/sbt/IvyUtil.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala index 0f06b6b84..d9477b9cc 100644 --- a/librarymanagement/src/main/scala/sbt/IvyUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement private[sbt] object IvyUtil { def separate[A, B](l: Seq[Either[A, B]]): (Seq[A], Seq[B]) = diff --git a/librarymanagement/src/main/scala/sbt/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/JsonUtil.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index f83ee21ff..8842301ea 100644 --- a/librarymanagement/src/main/scala/sbt/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.net.URL @@ -7,6 +7,7 @@ import core.module.descriptor.ModuleDescriptor import sbt.serialization._ import java.net.{ URLEncoder, URLDecoder } import sbt.util.Logger +import sbt.librarymanagement._ private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" diff --git a/librarymanagement/src/main/scala/sbt/LogicalClock.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala similarity index 94% rename from librarymanagement/src/main/scala/sbt/LogicalClock.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala index 83c516a17..b8ce426e7 100644 --- a/librarymanagement/src/main/scala/sbt/LogicalClock.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement /** * Represents a logical time point for dependency resolution. diff --git a/librarymanagement/src/main/scala/sbt/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/MakePom.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 2f4640c39..a8489119c 100644 --- a/librarymanagement/src/main/scala/sbt/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -5,12 +5,12 @@ // based on Ivy's PomModuleDescriptorWriter, which is Apache Licensed, Version 2.0 // http://www.apache.org/licenses/LICENSE-2.0 -package sbt +package sbt.internal.librarymanagement import java.io.File import sbt.util.Logger - -import sbt.mavenint.PomExtraDependencyAttributes +import sbt.librarymanagement._ +import mavenint.PomExtraDependencyAttributes // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation @@ -23,6 +23,7 @@ import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, Dep import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } import ivyint.CustomRemoteMavenResolver import sbt.io.IO + object MakePom { /** True if the revision is an ivy-range, not a complete revision. */ def isDependencyVersionRange(revision: String): Boolean = { diff --git a/librarymanagement/src/main/scala/sbt/ProjectResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/ProjectResolver.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala index 61c811e7b..760f63f52 100644 --- a/librarymanagement/src/main/scala/sbt/ProjectResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2011 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.util.Date @@ -15,6 +15,7 @@ import org.apache.ivy.plugins.namespace.Namespace import org.apache.ivy.plugins.resolver.{ DependencyResolver, ResolverSettings } import report.{ ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport } import resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } +import sbt.librarymanagement._ /** * A Resolver that uses a predefined mapping from module ids to in-memory descriptors. diff --git a/librarymanagement/src/main/scala/sbt/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/ResolutionCache.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index 30b8d74f7..26b85b0b7 100644 --- a/librarymanagement/src/main/scala/sbt/ResolutionCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.io.FileInputStream @@ -13,6 +13,7 @@ import core.module.descriptor.ModuleDescriptor import ResolutionCache.{ Name, ReportDirectory, ResolvedName, ResolvedPattern } import parser.xml.XmlModuleDescriptorParser import sbt.io.IO +import sbt.librarymanagement._ /** * Replaces the standard Ivy resolution cache in order to: diff --git a/librarymanagement/src/main/scala/sbt/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala similarity index 93% rename from librarymanagement/src/main/scala/sbt/SbtExclusionRule.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala index 6e897a16b..1f6c27c47 100644 --- a/librarymanagement/src/main/scala/sbt/SbtExclusionRule.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala @@ -1,6 +1,7 @@ -package sbt +package sbt.internal.librarymanagement -import sbt.impl.{ GroupID, GroupArtifactID } +import impl.{ GroupID, GroupArtifactID } +import sbt.librarymanagement._ final class SbtExclusionRule( val organization: String, diff --git a/librarymanagement/src/main/scala/sbt/StringUtilities.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala similarity index 92% rename from librarymanagement/src/main/scala/sbt/StringUtilities.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala index 40018250e..00541d441 100644 --- a/librarymanagement/src/main/scala/sbt/StringUtilities.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2009 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement import java.util.Locale diff --git a/librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index c890980fc..fee1ae4ef 100644 --- a/librarymanagement/src/main/scala/sbt/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -1,4 +1,5 @@ -package sbt.cross +package sbt.internal.librarymanagement +package cross object CrossVersionUtil { diff --git a/librarymanagement/src/main/scala/sbt/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/impl/DependencyBuilders.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index c449393f7..f589e7674 100755 --- a/librarymanagement/src/main/scala/sbt/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -1,10 +1,11 @@ /* sbt -- Simple Build Tool * Copyright 2009,2010 Mark Harrah */ -package sbt +package sbt.internal.librarymanagement package impl import StringUtilities.nonEmpty +import sbt.librarymanagement._ trait DependencyBuilders { final implicit def toGroupID(groupID: String): GroupID = diff --git a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 1fc3291a4..adabbeb47 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import java.util.Date @@ -19,11 +19,12 @@ import core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } -import Configurations.{ System => _, _ } import annotation.tailrec import scala.concurrent.duration._ import sbt.io.{ DirectoryFilter, Hash, IO, Path } import sbt.util.Logger +import sbt.librarymanagement._ +import Configurations.{ System => _, _ } private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = diff --git a/librarymanagement/src/main/scala/sbt/ivyint/CustomMavenResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala similarity index 80% rename from librarymanagement/src/main/scala/sbt/ivyint/CustomMavenResolver.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala index e3e41148e..3fc19aed9 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/CustomMavenResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala @@ -1,7 +1,8 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import org.apache.ivy.plugins.resolver.DependencyResolver +import sbt.librarymanagement._ // These are placeholder traits for sbt-aether-resolver trait CustomMavenResolver extends DependencyResolver { diff --git a/librarymanagement/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 5d067d313..9a889d808 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/ErrorMessageAuthenticator.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import java.lang.reflect.Field diff --git a/librarymanagement/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index aeef4d428..88a237910 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/IvyCredentialsLookup.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import org.apache.ivy.util.url.CredentialsStore diff --git a/librarymanagement/src/main/scala/sbt/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/ivyint/MergeDescriptors.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 76bb4d2af..03e043043 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import java.io.File diff --git a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 2ca80898f..c67c77b7e 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import java.io.File @@ -16,6 +16,7 @@ import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } import sbt.util.Logger +import sbt.librarymanagement._ private[sbt] case class SbtChainResolver( name: String, diff --git a/librarymanagement/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala similarity index 75% rename from librarymanagement/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala index 0a3338fac..f4f281a50 100644 --- a/librarymanagement/src/main/scala/sbt/ivyint/SbtDefaultDependencyDescriptor.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala @@ -1,8 +1,9 @@ -package sbt +package sbt.internal.librarymanagement package ivyint import org.apache.ivy.core import core.module.descriptor.DefaultDependencyDescriptor +import sbt.librarymanagement._ trait SbtDefaultDependencyDescriptor { self: DefaultDependencyDescriptor => def dependencyModuleId: ModuleID diff --git a/librarymanagement/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index ab87cae75..a1091aed4 100644 --- a/librarymanagement/src/main/scala/sbt/mavenint/PomExtraDependencyAttributes.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -1,4 +1,5 @@ -package sbt.mavenint +package sbt.internal.librarymanagement +package mavenint import java.util.Properties import java.util.regex.Pattern diff --git a/librarymanagement/src/main/scala/sbt/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/Artifact.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 4cafb0e67..93dc66fcb 100644 --- a/librarymanagement/src/main/scala/sbt/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.io.File import java.net.URL diff --git a/librarymanagement/src/main/scala/sbt/CircularDependencyLevel.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/CircularDependencyLevel.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala index 3c2f62bc6..0fc32c015 100644 --- a/librarymanagement/src/main/scala/sbt/CircularDependencyLevel.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement import org.apache.ivy.plugins.circular.{ CircularDependencyStrategy, WarnCircularDependencyStrategy, IgnoreCircularDependencyStrategy, ErrorCircularDependencyStrategy } diff --git a/librarymanagement/src/main/scala/sbt/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/Configuration.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index d2307b89d..95c8119da 100644 --- a/librarymanagement/src/main/scala/sbt/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import sbt.serialization._ diff --git a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala similarity index 78% rename from librarymanagement/src/main/scala/sbt/ConflictWarning.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index 75a4a5bd9..ab98c67af 100644 --- a/librarymanagement/src/main/scala/sbt/ConflictWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -1,6 +1,6 @@ -package sbt +package sbt.librarymanagement -import DependencyFilter._ +import sbt.internal.librarymanagement.DependencyFilter._ import sbt.util.{ Logger, Level } /** @@ -9,16 +9,8 @@ import sbt.util.{ Logger, Level } * library dependency graph by mistake, but it won't be caught by eviction. */ final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) { - @deprecated("`filter` is no longer used", "0.13.0") - val filter: ModuleFilter = (_: ModuleID) => false - @deprecated("`group` is no longer used", "0.13.0") - val group: ModuleID => String = ConflictWarning.org } object ConflictWarning { - @deprecated("`group` and `filter` are no longer used. Use a standard Ivy conflict manager.", "0.13.0") - def apply(label: String, filter: ModuleFilter, group: ModuleID => String, level: Level.Value, failOnConflict: Boolean): ConflictWarning = - ConflictWarning(label, level, failOnConflict) - def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) private def org = (_: ModuleID).organization @@ -26,9 +18,6 @@ object ConflictWarning { def default(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - @deprecated("Warning on evicted modules is no longer done, so this is the same as `default`. Use a standard Ivy conflict manager.", "0.13.0") - def strict(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) - def apply(config: ConflictWarning, report: UpdateReport, log: Logger): Unit = { processCrossVersioned(config, report, log) } diff --git a/librarymanagement/src/main/scala/sbt/Credentials.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/Credentials.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala index e2bd74fed..d86a8b774 100644 --- a/librarymanagement/src/main/scala/sbt/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala @@ -1,12 +1,13 @@ /* sbt -- Simple Build Tool * Copyright 2009 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.io.File import org.apache.ivy.util.url.CredentialsStore import sbt.io.IO import sbt.util.Logger +import sbt.internal.librarymanagement.IvyUtil object Credentials { def apply(realm: String, host: String, userName: String, passwd: String): Credentials = diff --git a/librarymanagement/src/main/scala/sbt/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/CrossVersion.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index b17ac525c..63cee85a3 100644 --- a/librarymanagement/src/main/scala/sbt/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -1,7 +1,8 @@ -package sbt +package sbt.librarymanagement -import cross.CrossVersionUtil import sbt.serialization._ +import sbt.internal.librarymanagement.SbtExclusionRule +import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) diff --git a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/EvictionWarning.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 4d6618b3c..f7b4523e3 100644 --- a/librarymanagement/src/main/scala/sbt/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -1,10 +1,11 @@ -package sbt +package sbt.librarymanagement import collection.mutable import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } import sbt.util.Logger import sbt.internal.util.ShowLines +import sbt.internal.librarymanagement.{ IvySbt, InlineConfiguration, InlineConfigurationWithExcludes } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], diff --git a/librarymanagement/src/main/scala/sbt/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/IvyInterface.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 3b54c684c..b582a51ed 100644 --- a/librarymanagement/src/main/scala/sbt/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.io.File import java.net.{ URI, URL } diff --git a/librarymanagement/src/main/scala/sbt/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/IvyScala.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index ea82f44ce..a399cb9d9 100644 --- a/librarymanagement/src/main/scala/sbt/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.util.Collections.emptyMap import scala.collection.mutable.HashSet @@ -10,7 +10,6 @@ import org.apache.ivy.core.module.descriptor.{ DefaultExcludeRule, ExcludeRule } import org.apache.ivy.core.module.descriptor.{ DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator } import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher - import sbt.util.Logger object ScalaArtifacts { @@ -35,7 +34,7 @@ import ScalaArtifacts._ final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization) -private object IvyScala { +private[sbt] object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) diff --git a/librarymanagement/src/main/scala/sbt/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/ModuleID.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 10647dcad..46b63ce39 100644 --- a/librarymanagement/src/main/scala/sbt/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -1,11 +1,11 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.net.URL -import sbt.mavenint.SbtPomExtraProperties +import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import sbt.serialization._ final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { diff --git a/librarymanagement/src/main/scala/sbt/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/Resolver.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index ec2564b43..a44615784 100644 --- a/librarymanagement/src/main/scala/sbt/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -1,7 +1,7 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.io.{ IOException, File } import java.net.URL diff --git a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/UpdateOptions.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 91fa7902d..2ff9bf80f 100644 --- a/librarymanagement/src/main/scala/sbt/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement import java.io.File import org.apache.ivy.plugins.resolver.DependencyResolver diff --git a/librarymanagement/src/main/scala/sbt/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/UpdateReport.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 5a866632a..8f03a2939 100644 --- a/librarymanagement/src/main/scala/sbt/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -1,12 +1,13 @@ /* sbt -- Simple Build Tool * Copyright 2011 Mark Harrah */ -package sbt +package sbt.librarymanagement import java.io.File import java.net.URL import java.{ util => ju } import sbt.serialization._ +import sbt.internal.librarymanagement.{ DependencyFilter, ConfigurationFilter, ModuleFilter, ArtifactFilter } /** * Provides information about resolution of a single configuration. @@ -225,14 +226,15 @@ object UpdateReport { } import DependencyFilter._ + /** Obtains all successfully retrieved files in all configurations and modules. */ def allFiles: Seq[File] = matching(DependencyFilter.allPass) /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + private[sbt] def matching(f: DependencyFilter): Seq[File] = select0(f).distinct /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ - def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = + private[sbt] def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = matching(DependencyFilter.make(configuration, module, artifact)) private[this] def select0(f: DependencyFilter): Seq[File] = @@ -242,7 +244,7 @@ object UpdateReport { } /** Constructs a new report that only contains files matching the specified filter.*/ - def filter(f: DependencyFilter): UpdateReport = + private[sbt] def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => modReport.copy( artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, diff --git a/librarymanagement/src/main/scala/sbt/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/VersionNumber.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala index a5d1d494b..226126bc3 100644 --- a/librarymanagement/src/main/scala/sbt/VersionNumber.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement final class VersionNumber private[sbt] ( val numbers: Seq[Long], diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index a9936e956..7ac8a3014 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -1,13 +1,15 @@ -package sbt +package sbt.internal.librarymanagement -import sbt.io.Path._, Configurations._ +import sbt.io.Path._ import sbt.io.IO import java.io.File import cross.CrossVersionUtil -import sbt.ivyint.SbtChainResolver import sbt.util.Logger import sbt.internal.util.ConsoleLogger import sbt.internal.util.UnitSpec +import sbt.librarymanagement._ +import ivyint.SbtChainResolver +import Configurations._ trait BaseIvySpecification extends UnitSpec { def currentBase: File = new File(".") diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 48ee003c0..5950fba99 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -1,6 +1,7 @@ -package sbt +package sbt.internal.librarymanagement import sbt.internal.util.ShowLines +import sbt.librarymanagement._ class CachedResolutionSpec extends BaseIvySpecification { import ShowLines._ diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 22923f62f..800f5de0c 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement import java.io.File import java.util.concurrent.Callable diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 33e1f62f2..3f8a608ea 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement import java.io.File import sbt.internal.util.UnitSpec diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index e8319ba2b..62e9edec2 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -1,8 +1,10 @@ +package sbt.internal.librarymanagement + import java.io.File import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact } import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions -import sbt._ +import sbt.librarymanagement._ import sbt.io.IO.withTemporaryDirectory import sbt.util.Logger import sbt.internal.util.ConsoleLogger diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index 532fae381..e35ea9748 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement import java.net.URL import java.io.File @@ -7,13 +7,13 @@ import sbt.internal.util.UnitSpec class DMSerializationSpec extends UnitSpec { "CrossVersion.full" should "roundtrip" in { - roundtripStr(CrossVersion.full: sbt.CrossVersion) + roundtripStr(CrossVersion.full: CrossVersion) } "CrossVersion.binary" should "roundtrip" in { - roundtripStr(CrossVersion.binary: sbt.CrossVersion) + roundtripStr(CrossVersion.binary: CrossVersion) } "CrossVersion.Disabled" should "roundtrip" in { - roundtrip(CrossVersion.Disabled: sbt.CrossVersion) + roundtrip(CrossVersion.Disabled: CrossVersion) } """Artifact("foo")""" should "roundtrip" in { roundtrip(Artifact("foo")) diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index a2f30fb3b..46dea91f2 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -1,4 +1,6 @@ -package sbt +package sbt.librarymanagement + +import sbt.internal.librarymanagement.BaseIvySpecification class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index 343149e85..5bcbcebcd 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -1,6 +1,7 @@ -package sbt +package sbt.internal.librarymanagement import sbt.internal.util.UnitSpec +import sbt.librarymanagement._ // This is a specification to check the inconsistent duplicate warnings class InconsistentDuplicateSpec extends UnitSpec { diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index 5f0513556..726e397b1 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement import java.io.File import sbt.util.Logger diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index adfb9c576..499e86db4 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -1,3 +1,5 @@ +package sbt.librarymanagement + import java.net.URL import sbt._ diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala index 3e7b8c631..9f882f30e 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/librarymanagement/src/test/scala/VersionNumberSpec.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.librarymanagement import sbt.internal.util.UnitSpec From 9a42d645e9e654d3988196ae163b5f32924dbd4b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 7 Sep 2015 04:40:23 -0400 Subject: [PATCH 0451/1030] Publish test artifacts --- build.sbt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 92bca0d1a..87fcf9194 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,9 @@ def commonSettings: Seq[Setting[_]] = Seq( crossScalaVersions := Seq(scala210, scala211), bintrayPackage := (bintrayPackage in ThisBuild).value, bintrayRepository := (bintrayRepository in ThisBuild).value, - resolvers += Resolver.sonatypeRepo("public") + resolvers += Resolver.sonatypeRepo("public"), + publishArtifact in Compile := true, + publishArtifact in Test := true ) lazy val root = (project in file(".")). @@ -43,6 +45,8 @@ lazy val root = (project in file(".")). name := "LM Root", publish := {}, publishLocal := {}, + publishArtifact in Compile := false, + publishArtifact in Test := false, publishArtifact := false ) From dc814a515449c7c516148b116924b08b15f4a9b1 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 31 Aug 2015 15:54:43 +0200 Subject: [PATCH 0452/1030] Add sbt-houserules, formatting --- .../librarymanagement/IvyActions.scala | 8 +- .../internal/librarymanagement/IvyCache.scala | 2 +- .../internal/librarymanagement/MakePom.scala | 3 +- .../librarymanagement/SbtExclusionRule.scala | 10 +- .../cross/CrossVersionUtil.scala | 133 +++++++++--------- .../impl/DependencyBuilders.scala | 6 +- .../ivyint/SbtChainResolver.scala | 13 +- .../librarymanagement/EvictionWarning.scala | 36 ++--- .../sbt/librarymanagement/IvyScala.scala | 3 +- .../sbt/librarymanagement/UpdateOptions.scala | 20 +-- .../sbt/librarymanagement/UpdateReport.scala | 73 +++++----- .../sbt/librarymanagement/VersionNumber.scala | 6 +- project/house.sbt | 1 + 13 files changed, 155 insertions(+), 159 deletions(-) create mode 100644 project/house.sbt diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index d5cc59781..b6a432d63 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -23,7 +23,7 @@ import sbt.librarymanagement._ final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, - val overwrite: Boolean) { + val overwrite: Boolean) { def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) = this(ivyFile, resolverName, artifacts, checksums, logging, false) } @@ -379,9 +379,9 @@ object IvyActions { } } final class ResolveException( - val messages: Seq[String], - val failed: Seq[ModuleID], - val failedPaths: Map[ModuleID, Seq[ModuleID]]) extends RuntimeException(messages.mkString("\n")) { + val messages: Seq[String], + val failed: Seq[ModuleID], + val failedPaths: Map[ModuleID, Seq[ModuleID]]) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = this(messages, failed, Map(failed map { m => m -> Nil }: _*)) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index aee827923..f40543d95 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -17,7 +17,7 @@ import sbt.util.Logger import sbt.librarymanagement._ class NotInCache(val id: ModuleID, cause: Throwable) - extends RuntimeException(NotInCache(id, cause), cause) { + extends RuntimeException(NotInCache(id, cause), cause) { def this(id: ModuleID) = this(id, null) } private object NotInCache { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index a8489119c..384833764 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -372,8 +372,7 @@ class MakePom(val log: Logger) { { g } { a } - - ) + ) } def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala index 1f6c27c47..001a7542b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala @@ -4,11 +4,11 @@ import impl.{ GroupID, GroupArtifactID } import sbt.librarymanagement._ final class SbtExclusionRule( - val organization: String, - val name: String, - val artifact: String, - val configurations: Seq[String], - val crossVersion: CrossVersion) { + val organization: String, + val name: String, + val artifact: String, + val configurations: Seq[String], + val crossVersion: CrossVersion) { def copy(organization: String = this.organization, name: String = this.name, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index fee1ae4ef..f9f6e069e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -1,72 +1,73 @@ package sbt.internal.librarymanagement package cross -object CrossVersionUtil -{ - val trueString = "true" - val falseString = "false" - val fullString = "full" - val noneString = "none" - val disabledString = "disabled" - val binaryString = "binary" - val TransitionScalaVersion = "2.10" - val TransitionSbtVersion = "0.12" +object CrossVersionUtil { + val trueString = "true" + val falseString = "false" + val fullString = "full" + val noneString = "none" + val disabledString = "disabled" + val binaryString = "binary" + val TransitionScalaVersion = "2.10" + val TransitionSbtVersion = "0.12" - def isFull(s: String): Boolean = (s == trueString) || (s == fullString) - def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) - def isBinary(s: String): Boolean = (s == binaryString) + def isFull(s: String): Boolean = (s == trueString) || (s == fullString) + def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) + def isBinary(s: String): Boolean = (s == binaryString) - private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined - /** Returns sbt binary interface x.y API compatible with the given version string v. - * RCs for x.y.0 are considered API compatible. - * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). - */ - private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)([-\w+]*)""".r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } - } - private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined - /** Returns Scala binary interface x.y API compatible with the given version string v. - * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. - */ - private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val BinCompatV = """(\d+)\.(\d+)\.(\d+)-bin(-.*)?""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } - } - private[sbt] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r - private[sbt] def partialVersion(s: String): Option[(Int,Int)] = - s match { - case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) - case _ => None - } - def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) - def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) - private[sbt] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) - private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = - major > minMajor || (major == minMajor && minor >= minMinor) - private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int,Int)]): String = - { - def sub(major: Int, minor: Int) = major + "." + minor - (apiVersion(full), partialVersion(cutoff)) match { - case (Some((major, minor)), None) => sub(major, minor) - case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) - case _ => full - } - } + private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + /** + * Returns sbt binary interface x.y API compatible with the given version string v. + * RCs for x.y.0 are considered API compatible. + * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + */ + private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)([-\w+]*)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + /** + * Returns Scala binary interface x.y API compatible with the given version string v. + * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + */ + private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = + { + val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r + val BinCompatV = """(\d+)\.(\d+)\.(\d+)-bin(-.*)?""".r + val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None + } + } + private[sbt] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + private[sbt] def partialVersion(s: String): Option[(Int, Int)] = + s match { + case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) + case _ => None + } + def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + private[sbt] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = + major > minMajor || (major == minMajor && minor >= minMinor) + private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int, Int)]): String = + { + def sub(major: Int, minor: Int) = major + "." + minor + (apiVersion(full), partialVersion(cutoff)) match { + case (Some((major, minor)), None) => sub(major, minor) + case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) + case _ => full + } + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index f589e7674..66ae42dfc 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -42,9 +42,9 @@ final class GroupID private[sbt] (private[sbt] val groupID: String) { private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" } final class GroupArtifactID private[sbt] ( - private[sbt] val groupID: String, - private[sbt] val artifactID: String, - private[sbt] val crossVersion: CrossVersion) { + private[sbt] val groupID: String, + private[sbt] val artifactID: String, + private[sbt] val crossVersion: CrossVersion) { def %(revision: String): ModuleID = { nonEmpty(revision, "Revision") diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index c67c77b7e..caeb70c7d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -19,11 +19,11 @@ import sbt.util.Logger import sbt.librarymanagement._ private[sbt] case class SbtChainResolver( - name: String, - resolvers: Seq[DependencyResolver], - settings: IvySettings, - updateOptions: UpdateOptions, - log: Logger) extends ChainResolver { + name: String, + resolvers: Seq[DependencyResolver], + settings: IvySettings, + updateOptions: UpdateOptions, + log: Logger) extends ChainResolver { override def equals(o: Any): Boolean = o match { case o: SbtChainResolver => @@ -139,8 +139,7 @@ private[sbt] case class SbtChainResolver( else if (useLatest) temp map { x => (reparseModuleDescriptor(dd, data, resolver, x), resolver) } - else temp map { x => (forcedRevision(x), resolver) } - ) + else temp map { x => (forcedRevision(x), resolver) }) } catch { case ex: Exception => Message.verbose("problem occurred while resolving " + dd + " with " + resolver diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index f7b4523e3..b431aa992 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -8,13 +8,13 @@ import sbt.internal.util.ShowLines import sbt.internal.librarymanagement.{ IvySbt, InlineConfiguration, InlineConfigurationWithExcludes } final class EvictionWarningOptions private[sbt] ( - val configurations: Seq[Configuration], - val warnScalaVersionEviction: Boolean, - val warnDirectEvictions: Boolean, - val warnTransitiveEvictions: Boolean, - val infoAllEvictions: Boolean, - val showCallers: Boolean, - val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { + val configurations: Seq[Configuration], + val warnScalaVersionEviction: Boolean, + val warnDirectEvictions: Boolean, + val warnTransitiveEvictions: Boolean, + val infoAllEvictions: Boolean, + val showCallers: Boolean, + val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { private[sbt] def configStrings = configurations map { _.name } def withConfigurations(configurations: Seq[Configuration]): EvictionWarningOptions = @@ -80,12 +80,12 @@ object EvictionWarningOptions { } final class EvictionPair private[sbt] ( - val organization: String, - val name: String, - val winner: Option[ModuleReport], - val evicteds: Seq[ModuleReport], - val includesDirect: Boolean, - val showCallers: Boolean) { + val organization: String, + val name: String, + val winner: Option[ModuleReport], + val evicteds: Seq[ModuleReport], + val includesDirect: Boolean, + val showCallers: Boolean) { override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString override def equals(o: Any): Boolean = o match { @@ -121,11 +121,11 @@ object EvictionPair { } final class EvictionWarning private[sbt] ( - val options: EvictionWarningOptions, - val scalaEvictions: Seq[EvictionPair], - val directEvictions: Seq[EvictionPair], - val transitiveEvictions: Seq[EvictionPair], - val allEvictions: Seq[EvictionPair]) { + val options: EvictionWarningOptions, + val scalaEvictions: Seq[EvictionPair], + val directEvictions: Seq[EvictionPair], + val transitiveEvictions: Seq[EvictionPair], + val allEvictions: Seq[EvictionPair]) { def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index a399cb9d9..b2647113c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -21,8 +21,7 @@ object ScalaArtifacts { private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version) - ) + scalaToolDependency(org, ScalaArtifacts.LibraryID, version)) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 2ff9bf80f..090a827b4 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -13,16 +13,16 @@ import sbt.util.Logger * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( - /** If set to CircularDependencyLevel.Error, halt the dependency resolution. */ - val circularDependencyLevel: CircularDependencyLevel, - /** If set to true, check all resolvers for snapshots. */ - val latestSnapshots: Boolean, - /** If set to true, use consolidated resolution. */ - val consolidatedResolution: Boolean, - /** If set to true, use cached resolution. */ - val cachedResolution: Boolean, - /** Extention point for an alternative resolver converter. */ - val resolverConverter: UpdateOptions.ResolverConverter) { + /** If set to CircularDependencyLevel.Error, halt the dependency resolution. */ + val circularDependencyLevel: CircularDependencyLevel, + /** If set to true, check all resolvers for snapshots. */ + val latestSnapshots: Boolean, + /** If set to true, use consolidated resolution. */ + val consolidatedResolution: Boolean, + /** If set to true, use cached resolution. */ + val cachedResolution: Boolean, + /** Extention point for an alternative resolver converter. */ + val resolverConverter: UpdateOptions.ResolverConverter) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 8f03a2939..316467f87 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -17,10 +17,10 @@ import sbt.internal.librarymanagement.{ DependencyFilter, ConfigurationFilter, M * @param evicted a sequence of evicted modules */ final class ConfigurationReport( - val configuration: String, - val modules: Seq[ModuleReport], - val details: Seq[OrganizationArtifactReport], - @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { + val configuration: String, + val modules: Seq[ModuleReport], + val details: Seq[OrganizationArtifactReport], + @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = this(configuration, modules, Nil, evicted) @@ -54,9 +54,9 @@ object ConfigurationReport { * which can be used to calculate detailed evction warning etc. */ final class OrganizationArtifactReport private[sbt] ( - val organization: String, - val name: String, - val modules: Seq[ModuleReport]) { + val organization: String, + val name: String, + val modules: Seq[ModuleReport]) { override def toString: String = { val details = modules map { _.detailReport } s"\t$organization:$name\n${details.mkString}\n" @@ -77,24 +77,24 @@ object OrganizationArtifactReport { * @param missingArtifacts the missing artifacts for this module. */ final class ModuleReport( - val module: ModuleID, - val artifacts: Seq[(Artifact, File)], - val missingArtifacts: Seq[Artifact], - val status: Option[String], - val publicationDate: Option[ju.Date], - val resolver: Option[String], - val artifactResolver: Option[String], - val evicted: Boolean, - val evictedData: Option[String], - val evictedReason: Option[String], - val problem: Option[String], - val homepage: Option[String], - val extraAttributes: Map[String, String], - val isDefault: Option[Boolean], - val branch: Option[String], - val configurations: Seq[String], - val licenses: Seq[(String, Option[String])], - val callers: Seq[Caller]) { + val module: ModuleID, + val artifacts: Seq[(Artifact, File)], + val missingArtifacts: Seq[Artifact], + val status: Option[String], + val publicationDate: Option[ju.Date], + val resolver: Option[String], + val artifactResolver: Option[String], + val evicted: Boolean, + val evictedData: Option[String], + val evictedReason: Option[String], + val problem: Option[String], + val homepage: Option[String], + val extraAttributes: Map[String, String], + val isDefault: Option[Boolean], + val branch: Option[String], + val configurations: Seq[String], + val licenses: Seq[(String, Option[String])], + val callers: Seq[Caller]) { private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) override def toString: String = { @@ -164,13 +164,13 @@ object ModuleReport { } final class Caller( - val caller: ModuleID, - val callerConfigurations: Seq[String], - val callerExtraAttributes: Map[String, String], - val isForceDependency: Boolean, - val isChangingDependency: Boolean, - val isTransitiveDependency: Boolean, - val isDirectlyForceDependency: Boolean) { + val caller: ModuleID, + val callerConfigurations: Seq[String], + val callerExtraAttributes: Map[String, String], + val isForceDependency: Boolean, + val isChangingDependency: Boolean, + val isTransitiveDependency: Boolean, + val isDirectlyForceDependency: Boolean) { override def toString: String = s"$caller" } @@ -248,16 +248,14 @@ object UpdateReport { moduleReportMap { (configuration, modReport) => modReport.copy( artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, - missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } - ) + missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }) } def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) modReport.copy( artifacts = f(configuration, modReport.module, modReport.artifacts), - missingArtifacts = Nil - ) + missingArtifacts = Nil) } def toSeq: Seq[(String, ModuleID, Artifact, File)] = @@ -269,8 +267,7 @@ object UpdateReport { def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => modReport.copy( - missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct - ) + missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct) } def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 226126bc3..c4785a680 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -1,9 +1,9 @@ package sbt.librarymanagement final class VersionNumber private[sbt] ( - val numbers: Seq[Long], - val tags: Seq[String], - val extras: Seq[String]) { + val numbers: Seq[Long], + val tags: Seq[String], + val extras: Seq[String]) { def _1: Option[Long] = get(0) def _2: Option[Long] = get(1) def _3: Option[Long] = get(2) diff --git a/project/house.sbt b/project/house.sbt new file mode 100644 index 000000000..eefc29672 --- /dev/null +++ b/project/house.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.1.0") From 6822671f01d631df0272703632d253ddb4bbef6a Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 31 Aug 2015 17:13:19 +0200 Subject: [PATCH 0453/1030] Add recommended compiler flags, fix warnings Remove `JavaNet1Repository` which was deprecated. --- build.sbt | 17 ++- .../librarymanagement/ConvertResolver.scala | 14 +-- .../sbt/internal/librarymanagement/Ivy.scala | 15 +-- .../librarymanagement/IvyActions.scala | 3 +- .../internal/librarymanagement/IvyCache.scala | 5 +- .../librarymanagement/IvyConfigurations.scala | 27 +---- .../librarymanagement/IvyRetrieve.scala | 2 +- .../internal/librarymanagement/JsonUtil.scala | 9 +- .../internal/librarymanagement/MakePom.scala | 2 +- .../CachedResolutionResolveEngine.scala | 11 +- .../ivyint/ErrorMessageAuthenticator.scala | 5 +- .../PomExtraDependencyAttributes.scala | 8 +- .../sbt/librarymanagement/Artifact.scala | 1 + .../sbt/librarymanagement/Configuration.scala | 8 +- .../sbt/librarymanagement/Credentials.scala | 2 +- .../sbt/librarymanagement/CrossVersion.scala | 13 +-- .../sbt/librarymanagement/Resolver.scala | 11 +- .../sbt/librarymanagement/UpdateReport.scala | 15 +-- .../src/test/scala/CachedResolutionSpec.scala | 8 +- .../src/test/scala/ComponentManagerTest.scala | 8 +- .../src/test/scala/CustomPomParserTest.scala | 2 +- .../src/test/scala/DMSerializationSpec.scala | 2 +- .../src/test/scala/EvictionWarningSpec.scala | 102 +++++++++--------- .../src/test/scala/MakePomSpec.scala | 4 +- .../src/test/scala/VersionNumberSpec.scala | 2 - 25 files changed, 125 insertions(+), 171 deletions(-) diff --git a/build.sbt b/build.sbt index 87fcf9194..8702ac687 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,22 @@ def commonSettings: Seq[Setting[_]] = Seq( bintrayRepository := (bintrayRepository in ThisBuild).value, resolvers += Resolver.sonatypeRepo("public"), publishArtifact in Compile := true, - publishArtifact in Test := true + publishArtifact in Test := true, + scalacOptions ++= Seq( + "-encoding", "utf8", + "-deprecation", + "-feature", + "-unchecked", + "-Xlint", + "-language:higherKinds", + "-language:implicitConversions", + "-Xfuture", + "-Yinline-warnings", + "-Xfatal-warnings", + "-Yno-adapted-args", + "-Ywarn-dead-code", + "-Ywarn-numeric-widen", + "-Ywarn-value-discard") ) lazy val root = (project in file(".")). diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 7029f19e0..e2848cb91 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -93,7 +93,7 @@ private[sbt] object ConvertResolver { if (signerName != null) { putSignatureMethod match { case None => () - case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) + case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) ; () } } } @@ -128,17 +128,6 @@ private[sbt] object ConvertResolver { resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns resolver } - // TODO: HTTP repository is no longer recommended. #1541 - // Remove `JavaNet1Repository` when we bump up the API. - case r: JavaNet1Repository => - { - // Thanks to Matthias Pfau for posting how to use the Maven 1 repository on java.net with Ivy: - // http://www.nabble.com/Using-gradle-Ivy-with-special-maven-repositories-td23775489.html - val resolver = new IBiblioResolver with DescriptorRequired { override def convertM2IdForResourceSearch(mrid: ModuleRevisionId) = mrid } - initializeMavenStyle(resolver, JavaNet1Repository.name, "http://download.java.net/maven/1/") - resolver.setPattern("[organisation]/[ext]s/[module]-[revision](-[classifier]).[ext]") - resolver - } case repo: SshRepository => { val resolver = new SshResolver with DescriptorRequired @@ -257,6 +246,7 @@ private[sbt] object ConvertResolver { progress.setTotalLength(totalLength); } FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) + () } catch { case ex: IOException => fireTransferError(ex) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index a2709140a..7bb40bfe2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -171,7 +171,6 @@ final class IvySbt(val configuration: IvyConfiguration) { moduleSettings match { case ic: InlineConfiguration => configureInline(ic.withExcludes, configuration.log) case ic: InlineConfigurationWithExcludes => configureInline(ic, configuration.log) - case ec: EmptyConfiguration => configureEmpty(ec) case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } @@ -238,13 +237,6 @@ final class IvySbt(val configuration: IvyConfiguration) { IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) } private def toURL(file: File) = file.toURI.toURL - private def configureEmpty(ec: EmptyConfiguration) = - { - val defaultConf = ModuleDescriptor.DEFAULT_CONFIGURATION - val mod = newConfiguredModuleID(ec.module, ec.moduleInfo, Seq(Configurations.Default)) - IvySbt.addMainArtifact(mod) - (mod, defaultConf) - } } } @@ -309,7 +301,7 @@ private[sbt] object IvySbt { def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger): Unit = { for (r <- resolvers) { log.debug("\t" + r) - settings.addResolver(ConvertResolver(r, settings, log)) + settings.addResolver(ConvertResolver(r, settings, UpdateOptions(), log)) } } /** @@ -329,7 +321,7 @@ private[sbt] object IvySbt { import IvyPatternHelper._ import PatternMatcher._ if (!existing.contains(resolver.name)) - settings.addResolver(ConvertResolver(resolver, settings, log)) + settings.addResolver(ConvertResolver(resolver, settings, UpdateOptions(), log)) val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) } @@ -441,7 +433,6 @@ private[sbt] object IvySbt { { val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { - case ec: EmptyConfiguration => ec.copy(module = sub(ec.module)) case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) case ic: InlineConfigurationWithExcludes => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) case _ => m @@ -492,7 +483,7 @@ private[sbt] object IvySbt { { dependencies } { // this is because Ivy adds a default artifact if none are specified. - if (dependencies \\ "publications" isEmpty) else NodeSeq.Empty + if ((dependencies \\ "publications").isEmpty) else NodeSeq.Empty } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index b6a432d63..cb873b1e2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -141,7 +141,6 @@ object IvyActions { moduleSettings match { case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) case i: InlineConfigurationWithExcludes => CrossVersion(i.module, i.ivyScala) - case e: EmptyConfiguration => CrossVersion(e.module, e.ivyScala) case _ => None } def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = @@ -213,7 +212,7 @@ object IvyActions { val evictedSet = evicted.map(m => (m.organization, m.name)).toSet val conflicted = confReport.allModules.filter(mod => evictedSet((mod.organization, mod.name))) grouped(grouping)(conflicted ++ evicted) - } toMap; + }.toMap def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = mods groupBy (grouping) mapValues (_.map(_.revision).toSet) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index f40543d95..b5fb6640a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -37,11 +37,12 @@ class IvyCache(val ivyHome: Option[File]) { withDefaultCache(lock, log) { cache => val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) + () } } /** Clears the cache of the jar for the given ID.*/ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { - try { withCachedJar(id, lock, log)(_.delete) } + try { withCachedJar(id, lock, log)(_.delete); () } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ @@ -81,7 +82,7 @@ class IvyCache(val ivyHome: Option[File]) { { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 9b35425ef..4d67fc086 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -80,7 +80,7 @@ final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val this(baseDirectory, uri, lock, extraResolvers, UpdateOptions(), log) type This = ExternalIvyConfiguration - def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, log) + def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, UpdateOptions(), log) } object ExternalIvyConfiguration { def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, UpdateOptions(), log) @@ -230,28 +230,3 @@ object InlineConfigurationWithExcludes { } else explicitConfigurations } - -@deprecated("Define a module using inline Scala (InlineConfiguration), a pom.xml (PomConfiguration), or an ivy.xml (IvyFileConfiguration).", "0.13.0") -final case class EmptyConfiguration(module: ModuleID, moduleInfo: ModuleInfo, ivyScala: Option[IvyScala], validate: Boolean) extends ModuleSettings { - def noScala = copy(ivyScala = None) -} - -object ModuleSettings { - @deprecated("Explicitly select configuration from pom.xml, ivy.xml, or inline Scala.", "0.13.0") - def apply(ivyScala: Option[IvyScala], validate: Boolean, module: => ModuleID, moduleInfo: => ModuleInfo)(baseDirectory: File, log: Logger): ModuleSettings = - { - log.debug("Autodetecting dependencies.") - val defaultPOMFile = IvySbt.defaultPOM(baseDirectory) - if (defaultPOMFile.canRead) - new PomConfiguration(defaultPOMFile, ivyScala, validate, true) - else { - val defaultIvy = IvySbt.defaultIvyFile(baseDirectory) - if (defaultIvy.canRead) - new IvyFileConfiguration(defaultIvy, ivyScala, validate, true) - else { - log.warn("No dependency configuration found, using defaults.") - new EmptyConfiguration(module, moduleInfo, ivyScala, validate) - } - } - } -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 8e10b0633..7b8b705e5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -163,7 +163,7 @@ object IvyRetrieve { def updateStats(report: ResolveReport): UpdateStats = new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport), evicted(confReport)) + new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport)) /** * Tries to find Ivy graph path the from node to target. diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 8842301ea..e0d3052e9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -68,14 +68,9 @@ private[sbt] object JsonUtil { !mr.evicted && mr.problem.isEmpty } } - val evicted = details flatMap { - _.modules filter { mr => - mr.evicted - } - } map { _.module } - new ConfigurationReport(cr.configuration, modules, details, evicted) + new ConfigurationReport(cr.configuration, modules, details) } - new UpdateReport(cachedDescriptor, configReports, stats) + new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 384833764..b7029902b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -412,7 +412,7 @@ class MakePom(val log: Logger) { { id } { name } { root } - { if (name == JavaNet1Repository.name) "legacy" else "default" } + { "default" } /** diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index adabbeb47..19830657b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -33,8 +33,8 @@ private[sbt] object CachedResolutionResolveCache { def graphVersion = "0.13.9C" val buildStartup: Long = System.currentTimeMillis lazy val todayStr: String = toYyyymmdd(buildStartup) - lazy val tomorrowStr: String = toYyyymmdd(buildStartup + (1 day).toMillis) - lazy val yesterdayStr: String = toYyyymmdd(buildStartup - (1 day).toMillis) + lazy val tomorrowStr: String = toYyyymmdd(buildStartup + 1.day.toMillis) + lazy val yesterdayStr: String = toYyyymmdd(buildStartup - 1.day.toMillis) def toYyyymmdd(timeSinceEpoch: Long): String = yyyymmdd.format(new Date(timeSinceEpoch)) lazy val yyyymmdd: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") } @@ -386,12 +386,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { !mr.evicted && mr.problem.isEmpty } } - val evicted = details flatMap { - _.modules filter { mr => - mr.evicted - } - } map { _.module } - new ConfigurationReport(rootModuleConf, modules, details, evicted) + new ConfigurationReport(rootModuleConf, modules, details) } /** * Returns a tuple of (merged org + name combo, newly evicted modules) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 9a889d808..173ae1d35 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -70,8 +70,9 @@ object ErrorMessageAuthenticator { def doInstallIfIvy(original: Option[Authenticator]): Unit = original match { case Some(installed: ErrorMessageAuthenticator) => // Ignore, we're already installed - case Some(ivy: IvyAuthenticator) => installIntoIvy(ivy) - case original => doInstall(original) + case Some(ivy: IvyAuthenticator) => + installIntoIvy(ivy); () + case original => doInstall(original) } doInstallIfIvy(originalAuthenticator) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index a1091aed4..8ae8b8ef1 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -52,12 +52,8 @@ object PomExtraDependencyAttributes { * TODO - maybe we can just parse this directly here. Note the `readFromAether` method uses * whatever we set here. */ - def transferDependencyExtraAttributes(from: Properties, to: java.util.Map[String, AnyRef]): Unit = { - Option(from.getProperty(ExtraAttributesKey, null)) match { - case Some(str) => to.put(ExtraAttributesKey, str) - case None => - } - } + def transferDependencyExtraAttributes(from: Properties, to: java.util.Map[String, AnyRef]): Unit = + Option(from.getProperty(ExtraAttributesKey, null)) foreach (to.put(ExtraAttributesKey, _)) /** * Reads the extra dependency information out of Ivy's notion of POM properties and returns diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 93dc66fcb..2d174f035 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -120,6 +120,7 @@ object Artifact { }) builder.endEntry() builder.popHints() + () } } implicit val unpickler: Unpickler[Artifact] = new Unpickler[Artifact] { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index 95c8119da..50c432682 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -26,7 +26,7 @@ object Configurations { case _ => c } - def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal") extend (ext: _*) hide + def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal").extend(ext: _*).hide def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) @@ -42,9 +42,9 @@ object Configurations { lazy val Optional = config("optional") lazy val Pom = config("pom") - lazy val ScalaTool = config("scala-tool") hide - lazy val CompilerPlugin = config("plugin") hide - lazy val Component = config("component") hide + lazy val ScalaTool = config("scala-tool").hide + lazy val CompilerPlugin = config("plugin").hide + lazy val Component = config("component").hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala index d86a8b774..3f075f2b7 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala @@ -63,7 +63,7 @@ object Credentials { { val properties = new java.util.Properties IO.load(properties, from) - properties map { case (k, v) => (k.toString, v.toString.trim) } toMap; + properties.map { case (k, v) => (k.toString, v.toString.trim) }.toMap } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 63cee85a3..69244a817 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -52,6 +52,7 @@ object CrossVersion { builder.beginEntry(a) builder.endEntry() builder.popHints() + () } } implicit val unpickler: Unpickler[CrossVersion] = new Unpickler[CrossVersion] { @@ -93,8 +94,7 @@ object CrossVersion { private[this] def idFun[T]: T => T = x => x - @deprecated("Will be made private.", "0.13.1") - def append(s: String): Option[String => String] = Some(x => crossName(x, s)) + private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s)) /** * Construct a cross-versioning function given cross-versioning configuration `cross`, @@ -123,15 +123,13 @@ object CrossVersion { case Some(is) => substituteCrossA(artifacts, cross) } - @deprecated("Will be made private.", "0.13.1") - def applyCross(s: String, fopt: Option[String => String]): String = + private[sbt] def applyCross(s: String, fopt: Option[String => String]): String = fopt match { case None => s case Some(fopt) => fopt(s) } - @deprecated("Will be made private.", "0.13.1") - def crossName(name: String, cross: String): String = + private[sbt] def crossName(name: String, cross: String): String = name + "_" + cross /** Cross-versions `exclude` according to its `crossVersion`. */ @@ -145,8 +143,7 @@ object CrossVersion { def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = a.copy(name = applyCross(a.name, cross)) - @deprecated("Will be made private.", "0.13.1") - def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + private[sbt] def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = as.map(art => substituteCross(art, cross)) /** diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index a44615784..1f68b0903 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -64,9 +64,6 @@ final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[Str } } override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode - - @deprecated - def this(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean) = this(ivyPatterns, artifactPatterns, isMavenCompatible, false, false) } object Patterns { implicit def defaultPatterns: Patterns = Resolver.defaultPatterns @@ -167,12 +164,6 @@ import Resolver._ object DefaultMavenRepository extends MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) -@deprecated("HTTP repository is no longer recommended.", "0.13.6") -object JavaNet1Repository extends JavaNet1Repository -@deprecated("HTTP repository is no longer recommended.", "0.13.6") -sealed trait JavaNet1Repository extends Resolver { - def name = "java.net Maven1 Repository" -} object Resolver { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true @@ -285,7 +276,7 @@ object Resolver { def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(new File(baseDirectory.toURI.normalize) getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) + baseRepository(new File(baseDirectory.toURI.normalize).getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) } object url { /** diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 316467f87..3e300c090 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -19,13 +19,13 @@ import sbt.internal.librarymanagement.{ DependencyFilter, ConfigurationFilter, M final class ConfigurationReport( val configuration: String, val modules: Seq[ModuleReport], - val details: Seq[OrganizationArtifactReport], - @deprecated("Use details instead to get better eviction info.", "0.13.6") val evicted: Seq[ModuleID]) { - def this(configuration: String, modules: Seq[ModuleReport], evicted: Seq[ModuleID]) = - this(configuration, modules, Nil, evicted) + val details: Seq[OrganizationArtifactReport]) { + + def evicted: Seq[ModuleID] = + details flatMap (_.modules) filter (_.evicted) map (_.module) override def toString = s"\t$configuration:\n" + - (if (details.isEmpty) modules.mkString + evicted.map("\t\t(EVICTED) " + _ + "\n").mkString + (if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map("\t\t(EVICTED) " + _ + "\n").mkString else details.mkString) /** @@ -36,7 +36,7 @@ final class ConfigurationReport( private[this] def addConfiguration(mod: ModuleID): ModuleID = if (mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details, evicted) + new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) } object ConfigurationReport { implicit val pickler: Pickler[ConfigurationReport] with Unpickler[ConfigurationReport] = PicklerUnpickler.generate[ConfigurationReport] @@ -275,7 +275,7 @@ object UpdateReport { val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, details, evicted) + new ConfigurationReport(configuration, newModules, details) } new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } @@ -316,6 +316,7 @@ object UpdateReport { }) builder.endEntry() builder.popHints() + () } def unpickle(tpe: String, reader: PReader): Any = { diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 5950fba99..fb9e86e3d 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -32,7 +32,7 @@ class CachedResolutionSpec extends BaseIvySpecification { ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed 2") case Left(uw) => - uw.lines should contain allOf("\n\tNote: Unresolved dependencies path:", + uw.lines should contain allOf ("\n\tNote: Unresolved dependencies path:", "\t\tfoundrylogic.vpp:vpp:2.2.1", "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", @@ -55,9 +55,9 @@ class CachedResolutionSpec extends BaseIvySpecification { cleanCachedResolutionCache(m) // second resolution reads from the minigraph val report = ivyUpdate(m) - val modules: Seq[String] = report.configurations.head.modules map {_.toString} - assert(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.0.Final"""}) - assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final"""})) + val modules: Seq[String] = report.configurations.head.modules map { _.toString } + assert(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.0.Final""" }) + assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final""" })) } def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 800f5de0c..5824494fe 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -19,12 +19,14 @@ class ComponentManagerTest extends UnitSpec { "Component manager" should "throw an exception if 'file' is called for a non-existing component" in { withManager { manager => intercept[InvalidComponent] { manager.file(TestID)(Fail) } + () } } it should "throw an exception if 'file' is called for an empty component" in { withManager { manager => manager.define(TestID, Nil) intercept[InvalidComponent] { manager.file(TestID)(Fail) } + () } } it should "return the file for a single-file component" in { @@ -37,6 +39,7 @@ class ComponentManagerTest extends UnitSpec { withManager { manager => defineFiles(manager, TestID, "a", "b") intercept[InvalidComponent] { manager.file(TestID)(Fail) } + () } } it should "return the files for a multi-file component" in { @@ -54,6 +57,7 @@ class ComponentManagerTest extends UnitSpec { it should "throw an exception if 'files' is called for a non-existing component" in { withManager { manager => intercept[InvalidComponent] { manager.files(TestID)(Fail) } + () } } it should "properly cache a file and then retrieve it to an unresolved component" in { @@ -104,8 +108,10 @@ class ComponentManagerTest extends UnitSpec { val location = componentLocation(id) if (location.exists) throw new RuntimeException(s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}") - else + else { IO.copy(files.map { f => f -> new java.io.File(location, f.getName) }) + () + } } override def addToComponent(id: String, files: Array[File]): Boolean = { val location = componentLocation(id) diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 62e9edec2..833336dfe 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -17,7 +17,7 @@ class CustomPomParserTest extends UnitSpec { val repoUrl = getClass.getResource("/test-maven-repo") val local = MavenRepository("Test Repo", repoUrl.toExternalForm) val paths = new IvyPaths(new File("."), Some(cacheDir)) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, log) + val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, UpdateOptions(), log) val ivySbt = new IvySbt(conf) val resolveOpts = new ResolveOptions().setConfs(Array("default")) val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index e35ea9748..ab4d9f78c 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -51,7 +51,7 @@ class DMSerializationSpec extends UnitSpec { new UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) lazy val configurationReportExample = new ConfigurationReport("compile", Vector(moduleReportExample), - Vector(organizationArtifactReportExample), Nil) + Vector(organizationArtifactReportExample)) lazy val organizationArtifactReportExample = new OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) lazy val moduleReportExample = diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 46dea91f2..d1a93c6ae 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -5,38 +5,38 @@ import sbt.internal.librarymanagement.BaseIvySpecification class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - "Eviction of scala-library whose scalaVersion" should "be detected" in scalaVersionWarn1 - it should "not be detected if it's diabled" in scalaVersionWarn2 - it should "print out message about the eviction" in scalaVersionWarn3 - it should "print out message about the eviction with callers" in scalaVersionWarn4 + "Eviction of scala-library whose scalaVersion" should "be detected" in scalaVersionWarn1() + it should "not be detected if it's diabled" in scalaVersionWarn2() + it should "print out message about the eviction" in scalaVersionWarn3() + it should "print out message about the eviction with callers" in scalaVersionWarn4() """Including two (suspect) binary incompatible Java libraries to - direct dependencies""" should "be detected as eviction" in javaLibWarn1 - it should "not be detected if it's disabled" in javaLibWarn2 - it should "print out message about the eviction" in javaLibWarn3 - it should "print out message about the eviction with callers" in javaLibWarn4 + direct dependencies""" should "be detected as eviction" in javaLibWarn1() + it should "not be detected if it's disabled" in javaLibWarn2() + it should "print out message about the eviction" in javaLibWarn3() + it should "print out message about the eviction with callers" in javaLibWarn4() """Including two (suspect) binary compatible Java libraries to - direct dependencies""" should "not be detected as eviction" in javaLibNoWarn1 - it should "print out message about the eviction" in javaLibNoWarn2 + direct dependencies""" should "not be detected as eviction" in javaLibNoWarn1() + it should "print out message about the eviction" in javaLibNoWarn2() """Including two (suspect) transitively binary incompatible Java libraries to - direct dependencies""" should "be not detected as eviction" in javaLibTransitiveWarn1 - it should "be detected if it's enabled" in javaLibTransitiveWarn2 - it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3 + direct dependencies""" should "be not detected as eviction" in javaLibTransitiveWarn1() + it should "be detected if it's enabled" in javaLibTransitiveWarn2() + it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() """Including two (suspect) binary incompatible Scala libraries to - direct dependencies""" should "be detected as eviction" in scalaLibWarn1 - it should "print out message about the eviction" in scalaLibWarn2 + direct dependencies""" should "be detected as eviction" in scalaLibWarn1() + it should "print out message about the eviction" in scalaLibWarn2() """Including two (suspect) binary compatible Scala libraries to - direct dependencies""" should "not be detected as eviction" in scalaLibNoWarn1 - it should "print out message about the eviction" in scalaLibNoWarn2 + direct dependencies""" should "not be detected as eviction" in scalaLibNoWarn1() + it should "print out message about the eviction" in scalaLibNoWarn2() """Including two (suspect) transitively binary incompatible Scala libraries to - direct dependencies""" should "be not detected as eviction" in scalaLibTransitiveWarn1 - it should "be detected if it's enabled" in scalaLibTransitiveWarn2 - it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3 + direct dependencies""" should "be not detected as eviction" in scalaLibTransitiveWarn1() + it should "be detected if it's enabled" in scalaLibTransitiveWarn2() + it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary @@ -58,19 +58,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionDeps = Seq(scala2102, akkaActor230) - def scalaVersionWarn1 = { + def scalaVersionWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size(1) + EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size (1) } - def scalaVersionWarn2 = { + def scalaVersionWarn2() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size(0) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) } - def scalaVersionWarn3 = { + def scalaVersionWarn3() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe @@ -81,7 +81,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "Run 'evicted' to see detailed eviction warnings") } - def scalaVersionWarn4 = { + def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe @@ -93,19 +93,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) - def javaLibWarn1 = { + def javaLibWarn1() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } - def javaLibWarn2 = { + def javaLibWarn2() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions should have size(0) + EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions should have size (0) } - def javaLibWarn3 = { + def javaLibWarn3() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe @@ -115,7 +115,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "Run 'evicted' to see detailed eviction warnings") } - def javaLibWarn4 = { + def javaLibWarn4() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe @@ -124,14 +124,14 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)") } - def javaLibNoWarn1 = { + def javaLibNoWarn1() = { val deps = Seq(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } - def javaLibNoWarn2 = { + def javaLibNoWarn2() = { val deps = Seq(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) @@ -140,19 +140,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveDeps = Seq(unfilteredUploads080, bnfparser10) - def javaLibTransitiveWarn1 = { + def javaLibTransitiveWarn1() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } - def javaLibTransitiveWarn2 = { + def javaLibTransitiveWarn2() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size(1) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) } - def javaLibTransitiveWarn3 = { + def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe @@ -161,14 +161,14 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)") } - def scalaLibWarn1 = { + def scalaLibWarn1() = { val deps = Seq(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } - def scalaLibWarn2 = { + def scalaLibWarn2() = { val deps = Seq(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) @@ -179,14 +179,14 @@ class EvictionWarningSpec extends BaseIvySpecification { "Run 'evicted' to see detailed eviction warnings") } - def scalaLibNoWarn1 = { + def scalaLibNoWarn1() = { val deps = Seq(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } - def scalaLibNoWarn2 = { + def scalaLibNoWarn2() = { val deps = Seq(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) @@ -195,19 +195,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveDeps = Seq(scala2104, bananaSesame04, akkaRemote234) - def scalaLibTransitiveWarn1 = { + def scalaLibTransitiveWarn1() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size(0) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } - def scalaLibTransitiveWarn2 = { + def scalaLibTransitiveWarn2() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size(1) + EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) } - def scalaLibTransitiveWarn3 = { + def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index 726e397b1..d1dec575f 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -71,9 +71,11 @@ class MakePomSpec extends UnitSpec { val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String): Unit = MakePom.makeDependencyVersion(s) shouldBe expected - def beParsedAsError(s: String): Unit = + def beParsedAsError(s: String): Unit = { intercept[Throwable] { MakePom.makeDependencyVersion(s) } + () + } } diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala index 9f882f30e..5e59cada3 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/librarymanagement/src/test/scala/VersionNumberSpec.scala @@ -56,7 +56,6 @@ class VersionNumberSpec extends UnitSpec { "0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) - "2.10.4-20140115-000117-b3a-sources" should "be parsed" in { beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) } @@ -82,7 +81,6 @@ class VersionNumberSpec extends UnitSpec { "space !?string" should "be parsed as an error" in beParsedAsError("space !?string") "blank string" should "be parsed as an error" in beParsedAsError("") - def beParsedAs(s: String, ns: Seq[Long], ts: Seq[String], es: Seq[String]) = s match { case VersionNumber(ns1, ts1, es1) if (ns1 == ns && ts1 == ts && es1 == es) => From d00b7d8b616630ae80b7784fa9457a4d6a85760d Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 31 Aug 2015 18:01:18 +0200 Subject: [PATCH 0454/1030] Fix more warnings Undeprecated `CustomPomParser` because it looks like nothing has replaced it yet. Removed usage of trait `scala.NotNull`, because it has been deprecated as of Scala 2.11 and its support has never been implemented in scalac. --- .../sbt/internal/librarymanagement/ComponentManager.scala | 2 +- .../sbt/internal/librarymanagement/CustomPomParser.scala | 4 ++-- .../src/main/scala/sbt/internal/librarymanagement/Ivy.scala | 3 +-- .../scala/sbt/internal/librarymanagement/IvyCache.scala | 2 +- .../src/main/scala/sbt/librarymanagement/Resolver.scala | 6 +++--- .../main/scala/sbt/librarymanagement/VersionNumber.scala | 2 +- librarymanagement/src/test/scala/ComponentManagerTest.scala | 2 +- 7 files changed, 10 insertions(+), 11 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index ba27eb76c..baed4cfa5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -73,7 +73,7 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { def this(msg: String) = this(msg, null) } -sealed trait IfMissing extends NotNull +sealed trait IfMissing object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index c75565daf..7cee3008c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -16,7 +16,7 @@ import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, S import sbt.io.Hash import sbt.librarymanagement._ -@deprecated("We now use an Aether-based pom parser.", "0.13.8") +// @deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) @@ -30,7 +30,7 @@ final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (Module override def getType() = delegate.getType() override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) } -@deprecated("We now use an Aether-based pom parser.", "0.13.8") +// @deprecated("We now use an Aether-based pom parser.", "0.13.8") object CustomPomParser { // Evil hackery to override the default maven pom mappings. diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 7bb40bfe2..7b4bc1f83 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -349,8 +349,7 @@ private[sbt] object IvySbt { new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, updatedDescriptor, resolved.getReport, resolved.isForce) } - private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean) //, artifactResolver: DependencyResolver) - { + private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean): Unit = { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index b5fb6640a..d7ce761c6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -90,7 +90,7 @@ class IvyCache(val ivyHome: Option[File]) { new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } /** Required by Ivy for copying to the cache.*/ -private class FileDownloader extends ResourceDownloader with NotNull { +private class FileDownloader extends ResourceDownloader { def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { if (dest.exists()) dest.delete() val part = new File(dest.getAbsolutePath + ".part") diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 1f68b0903..48d9c69bf 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -83,7 +83,7 @@ object RepositoryHelpers { def nontransactional() = FileConfiguration(isLocal, Some(false)) def nonlocal() = FileConfiguration(false, isTransactional) } - sealed trait SshAuthentication extends NotNull + sealed trait SshAuthentication final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication } @@ -216,7 +216,7 @@ object Resolver { private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if (nonEmpty) Seq(value) else Nil /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ - sealed abstract class Define[RepositoryType <: SshBasedRepository] extends NotNull { + sealed abstract class Define[RepositoryType <: SshBasedRepository] { /** Subclasses should implement this method to */ protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType /** @@ -347,7 +347,7 @@ object Resolver { def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = { - val pList = ("${ivy.home}/" + id + "/" + localBasePattern) :: Nil + val pList = s"$${ivy.home}/$id/$localBasePattern" :: Nil FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) } def defaultIvyPatterns = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala index c4785a680..1f736398b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -98,7 +98,7 @@ object VersionNumber { private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { case (v1, v2) if (v1.size >= 2) && (v2.size >= 2) => // A normal version number MUST take the form X.Y.Z - (v1._1.get, v1._2.get, v1._3.getOrElse(0), v1.tags, v2._1.get, v2._2.get, v2._3.getOrElse(0), v2.tags) match { + (v1._1.get, v1._2.get, v1._3.getOrElse(0L), v1.tags, v2._1.get, v2._2.get, v2._3.getOrElse(0L), v2.tags) match { case (0L, _, _, _, 0L, _, _, _) => // Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable. equalsIgnoreExtra(v1, v2) diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 5824494fe..00c76143f 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -123,7 +123,7 @@ class ComponentManagerTest extends UnitSpec { } // A stubbed locking API. object locks extends xsbti.GlobalLock { - override def apply[T](lockFile: File, run: Callable[T]): T = { + override def apply[U](lockFile: File, run: Callable[U]): U = { // TODO - do we need to lock? run.call() } From cbde870057b9b56fba82e78dc57be647c4b1f67b Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 11 Sep 2015 10:25:11 +0200 Subject: [PATCH 0455/1030] Remove IfMissing.Fallback It was used by code in ComponentCompiler in sbt/incrementalcompiler, but this code has been removed. --- .../sbt/internal/librarymanagement/ComponentManager.scala | 3 --- 1 file changed, 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index baed4cfa5..5b7034de0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -41,8 +41,6 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr d() if (d.cache) cache(id) getOrElse(notFound) - case f: IfMissing.Fallback => - f() } lockLocalCache { getOrElse(fromGlobal) } @@ -77,7 +75,6 @@ sealed trait IfMissing object IfMissing { object Fail extends IfMissing final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } - final class Fallback(f: => Iterable[File]) extends IfMissing { def apply() = f } } object ComponentManager { lazy val (version, timestamp) = From 699dcfdee5d07d4bc7f8dcc86c641dc2ef901c76 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Wed, 16 Sep 2015 14:57:00 +0200 Subject: [PATCH 0456/1030] Update to latest sbt-houserules, formatting --- build.sbt | 5 +- .../librarymanagement/ConvertResolver.scala | 14 +++-- .../sbt/internal/librarymanagement/Ivy.scala | 6 +- .../librarymanagement/IvyActions.scala | 12 ++-- .../librarymanagement/IvyConfigurations.scala | 44 ++++++++------ .../librarymanagement/IvyRetrieve.scala | 6 +- .../internal/librarymanagement/JsonUtil.scala | 3 +- .../internal/librarymanagement/MakePom.scala | 6 +- .../librarymanagement/SbtExclusionRule.scala | 21 ++++--- .../impl/DependencyBuilders.scala | 3 +- .../CachedResolutionResolveEngine.scala | 12 ++-- .../ivyint/ErrorMessageAuthenticator.scala | 3 +- .../ivyint/SbtChainResolver.scala | 6 +- .../sbt/librarymanagement/CrossVersion.scala | 10 ++-- .../librarymanagement/EvictionWarning.scala | 21 ++++--- .../sbt/librarymanagement/IvyScala.scala | 3 +- .../sbt/librarymanagement/UpdateOptions.scala | 27 ++++++--- .../sbt/librarymanagement/UpdateReport.scala | 60 ++++++++++++------- .../sbt/librarymanagement/VersionNumber.scala | 3 +- .../src/test/scala/BaseIvySpecification.scala | 9 ++- .../src/test/scala/CachedResolutionSpec.scala | 18 ++++-- .../src/test/scala/EvictionWarningSpec.scala | 42 ++++++++----- .../scala/InconsistentDuplicateSpec.scala | 6 +- project/house.sbt | 2 +- 24 files changed, 221 insertions(+), 121 deletions(-) diff --git a/build.sbt b/build.sbt index 8702ac687..b60ba9188 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,6 @@ import Dependencies._ +def baseVersion = "0.1.0" def internalPath = file("internal") def commonSettings: Seq[Setting[_]] = Seq( @@ -40,7 +41,6 @@ lazy val root = (project in file(".")). settings( inThisBuild(Seq( organization := "org.scala-sbt", - version := "0.1.0-SNAPSHOT", homepage := Some(url("https://github.com/sbt/librarymanagement")), description := "Library management module for sbt", licenses := List("BSD New" -> url("https://github.com/sbt/sbt/blob/0.13/LICENSE")), @@ -54,7 +54,8 @@ lazy val root = (project in file(".")). bintrayReleaseOnPublish := false, bintrayOrganization := Some("sbt"), bintrayRepository := "maven-releases", - bintrayPackage := "librarymanagement" + bintrayPackage := "librarymanagement", + git.baseVersion := baseVersion )), commonSettings, name := "LM Root", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index e2848cb91..12fd82100 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -49,13 +49,17 @@ private[sbt] object ConvertResolver { private val signerNameField: Option[java.lang.reflect.Field] = reflectiveLookup(_.getDeclaredField("signerName")) private val putChecksumMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod("putChecksum", + reflectiveLookup(_.getDeclaredMethod( + "putChecksum", classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean], classOf[String])) + classOf[Boolean], classOf[String] + )) private val putSignatureMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod("putSignature", + reflectiveLookup(_.getDeclaredMethod( + "putSignature", classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean])) + classOf[Boolean] + )) } /** * The default behavior of ivy's overwrite flags ignores the fact that a lot of repositories @@ -93,7 +97,7 @@ private[sbt] object ConvertResolver { if (signerName != null) { putSignatureMethod match { case None => () - case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean) ; () + case Some(method) => method.invoke(artifact, src, dest, true: java.lang.Boolean); () } } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 7b4bc1f83..85071af19 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -290,11 +290,13 @@ private[sbt] object IvySbt { val delegate = new ivyint.SbtChainResolver(name + "-delegate", mapResolvers(rest), settings, updateOptions, log) val prs = mapResolvers(projectResolvers) // Here we construct a chain resolver which will FORCE looking at the project resolver first. - new ivyint.SbtChainResolver(name, + new ivyint.SbtChainResolver( + name, prs :+ delegate, settings, UpdateOptions().withLatestSnapshots(false), - log) + log + ) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index cb873b1e2..817d41a69 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -32,7 +32,8 @@ final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val private[sbt] def copy( retrieve: Option[RetrieveConfiguration] = this.retrieve, missingOk: Boolean = this.missingOk, - logging: UpdateLogging.Value = this.logging): UpdateConfiguration = + logging: UpdateLogging.Value = this.logging + ): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging) } final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean, val configurationsToRetrieve: Option[Set[Configuration]]) { @@ -45,7 +46,8 @@ final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclu final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) final class UnresolvedWarningConfiguration private[sbt] ( - val modulePositions: Map[ModuleID, SourcePosition]) + val modulePositions: Map[ModuleID, SourcePosition] +) object UnresolvedWarningConfiguration { def apply(): UnresolvedWarningConfiguration = apply(Map()) def apply(modulePositions: Map[ModuleID, SourcePosition]): UnresolvedWarningConfiguration = @@ -380,7 +382,8 @@ object IvyActions { final class ResolveException( val messages: Seq[String], val failed: Seq[ModuleID], - val failedPaths: Map[ModuleID, Seq[ModuleID]]) extends RuntimeException(messages.mkString("\n")) { + val failedPaths: Map[ModuleID, Seq[ModuleID]] +) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = this(messages, failed, Map(failed map { m => m -> Nil }: _*)) } @@ -390,7 +393,8 @@ final class ResolveException( */ final class UnresolvedWarning private[sbt] ( val resolveException: ResolveException, - val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]]) + val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] +) object UnresolvedWarning { private[sbt] def apply(err: ResolveException, config: UnresolvedWarningConfiguration): UnresolvedWarning = { def modulePosition(m0: ModuleID): Option[SourcePosition] = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 4d67fc086..adcd6a0da 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -21,9 +21,9 @@ sealed trait IvyConfiguration { def updateOptions: UpdateOptions } final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val resolutionCacheDir: Option[File], val updateOptions: UpdateOptions, - val log: Logger) extends IvyConfiguration { + val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], + val checksums: Seq[String], val resolutionCacheDir: Option[File], val updateOptions: UpdateOptions, + val log: Logger) extends IvyConfiguration { @deprecated("Use the variant that accepts resolutionCacheDir and updateOptions.", "0.13.0") def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], @@ -74,7 +74,7 @@ final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resol } } final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], - val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration { + val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration { @deprecated("Use the variant that accepts updateOptions.", "0.13.6") def this(baseDirectory: File, uri: URI, lock: Option[xsbti.GlobalLock], extraResolvers: Seq[Resolver], log: Logger) = this(baseDirectory, uri, lock, extraResolvers, UpdateOptions(), log) @@ -139,23 +139,26 @@ object InlineConfiguration { explicitConfigurations } -final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, - val moduleInfo: ModuleInfo, - val dependencies: Seq[ModuleID], - val overrides: Set[ModuleID], - val excludes: Seq[SbtExclusionRule], - val ivyXML: NodeSeq, - val configurations: Seq[Configuration], - val defaultConfiguration: Option[Configuration], - val ivyScala: Option[IvyScala], - val validate: Boolean, - val conflictManager: ConflictManager) extends ModuleSettings { +final class InlineConfigurationWithExcludes private[sbt] ( + val module: ModuleID, + val moduleInfo: ModuleInfo, + val dependencies: Seq[ModuleID], + val overrides: Set[ModuleID], + val excludes: Seq[SbtExclusionRule], + val ivyXML: NodeSeq, + val configurations: Seq[Configuration], + val defaultConfiguration: Option[Configuration], + val ivyScala: Option[IvyScala], + val validate: Boolean, + val conflictManager: ConflictManager +) extends ModuleSettings { def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) def noScala = copy(ivyScala = None) def withOverrides(overrides: Set[ModuleID]): ModuleSettings = copy(overrides = overrides) - private[sbt] def copy(module: ModuleID = this.module, + private[sbt] def copy( + module: ModuleID = this.module, moduleInfo: ModuleInfo = this.moduleInfo, dependencies: Seq[ModuleID] = this.dependencies, overrides: Set[ModuleID] = this.overrides, @@ -165,7 +168,8 @@ final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, defaultConfiguration: Option[Configuration] = this.defaultConfiguration, ivyScala: Option[IvyScala] = this.ivyScala, validate: Boolean = this.validate, - conflictManager: ConflictManager = this.conflictManager): InlineConfigurationWithExcludes = + conflictManager: ConflictManager = this.conflictManager + ): InlineConfigurationWithExcludes = InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, ivyScala, validate, conflictManager) @@ -206,7 +210,8 @@ final class InlineConfigurationWithExcludes private[sbt] (val module: ModuleID, } } object InlineConfigurationWithExcludes { - def apply(module: ModuleID, + def apply( + module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, @@ -216,7 +221,8 @@ object InlineConfigurationWithExcludes { defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, - conflictManager: ConflictManager = ConflictManager.default): InlineConfigurationWithExcludes = + conflictManager: ConflictManager = ConflictManager.default + ): InlineConfigurationWithExcludes = new InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, ivyScala, validate, conflictManager) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 7b8b705e5..196e0e1ae 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -93,10 +93,12 @@ object IvyRetrieve { val branch = nonEmptyString(revId.getBranch) val (status, publicationDate, resolver, artifactResolver) = dep.isLoaded match { case true => - (nonEmptyString(dep.getDescriptor.getStatus), + ( + nonEmptyString(dep.getDescriptor.getStatus), Some(new ju.Date(dep.getPublication)), nonEmptyString(dep.getModuleRevision.getResolver.getName), - nonEmptyString(dep.getModuleRevision.getArtifactResolver.getName)) + nonEmptyString(dep.getModuleRevision.getArtifactResolver.getName) + ) case _ => (None, None, None, None) } val (evicted, evictedData, evictedReason) = dep.isEvicted(confReport.getConfiguration) match { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index e0d3052e9..b570c7cef 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -39,7 +39,8 @@ private[sbt] object JsonUtil { mr.evicted, mr.evictedData, mr.evictedReason, mr.problem, mr.homepage, mr.extraAttributes, mr.isDefault, mr.branch, mr.configurations, mr.licenses, - filterOutArtificialCallers(mr.callers)) + filterOutArtificialCallers(mr.callers) + ) }) }) }) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index b7029902b..ea4990736 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -244,7 +244,8 @@ class MakePom(val log: Logger) { log.warn( s"""Translating intransitive dependency (${dependency.getDependencyId}) into pom.xml, but maven does not support intransitive dependencies. | Please use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. - """.stripMargin) + """.stripMargin + ) else () val artifacts = dependency.getAllDependencyArtifacts val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) @@ -372,7 +373,8 @@ class MakePom(val log: Logger) { { g } { a } - ) + + ) } def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala index 001a7542b..76e74dcd4 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala @@ -8,18 +8,23 @@ final class SbtExclusionRule( val name: String, val artifact: String, val configurations: Seq[String], - val crossVersion: CrossVersion) { + val crossVersion: CrossVersion +) { - def copy(organization: String = this.organization, + def copy( + organization: String = this.organization, name: String = this.name, artifact: String = this.artifact, configurations: Seq[String] = this.configurations, - crossVersion: CrossVersion = this.crossVersion): SbtExclusionRule = - SbtExclusionRule(organization = organization, + crossVersion: CrossVersion = this.crossVersion + ): SbtExclusionRule = + SbtExclusionRule( + organization = organization, name = name, artifact = artifact, configurations = configurations, - crossVersion = crossVersion) + crossVersion = crossVersion + ) } object SbtExclusionRule { @@ -29,11 +34,13 @@ object SbtExclusionRule { def apply(organization: String, name: String): SbtExclusionRule = new SbtExclusionRule(organization, name, "*", Nil, CrossVersion.Disabled) - def apply(organization: String, + def apply( + organization: String, name: String, artifact: String, configurations: Seq[String], - crossVersion: CrossVersion): SbtExclusionRule = + crossVersion: CrossVersion + ): SbtExclusionRule = new SbtExclusionRule(organization, name, artifact, configurations, crossVersion) implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index 66ae42dfc..517ea1aa0 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -44,7 +44,8 @@ final class GroupID private[sbt] (private[sbt] val groupID: String) { final class GroupArtifactID private[sbt] ( private[sbt] val groupID: String, private[sbt] val artifactID: String, - private[sbt] val crossVersion: CrossVersion) { + private[sbt] val crossVersion: CrossVersion +) { def %(revision: String): ModuleID = { nonEmpty(revision, "Revision") diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 19830657b..4a8a8094e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -492,9 +492,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { breakLoops(loop) // sort the all modules such that less called modules comes earlier - @tailrec def sortModules(cs: Vector[(String, String)], + @tailrec def sortModules( + cs: Vector[(String, String)], acc: Vector[(String, String)], extra: Vector[(String, String)], - n: Int, guard: Int): Vector[(String, String)] = + n: Int, guard: Int + ): Vector[(String, String)] = { // println(s"sortModules: $n / $guard") val keys = cs.toSet @@ -522,8 +524,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { sortModules(cs.tail, acc, extra :+ cs.head, n + 1, guard) } else sortModules(called, acc ++ notCalled, extra, 0, called.size * called.size + 1)) } - def resolveConflicts(cs: List[(String, String)], - allModules: Map[(String, String), Vector[OrganizationArtifactReport]]): List[OrganizationArtifactReport] = + def resolveConflicts( + cs: List[(String, String)], + allModules: Map[(String, String), Vector[OrganizationArtifactReport]] + ): List[OrganizationArtifactReport] = cs match { case Nil => Nil case (organization, name) :: rest => diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 173ae1d35..60d6a59b9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -114,7 +114,8 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato getRequestingPort, getRequestingProtocol, getRequestingPrompt, - getRequestingScheme)) + getRequestingScheme + )) finally Authenticator.setDefault(this) } originalAuthentication.orNull diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index caeb70c7d..031998f36 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -23,7 +23,8 @@ private[sbt] case class SbtChainResolver( resolvers: Seq[DependencyResolver], settings: IvySettings, updateOptions: UpdateOptions, - log: Logger) extends ChainResolver { + log: Logger +) extends ChainResolver { override def equals(o: Any): Boolean = o match { case o: SbtChainResolver => @@ -139,7 +140,8 @@ private[sbt] case class SbtChainResolver( else if (useLatest) temp map { x => (reparseModuleDescriptor(dd, data, resolver, x), resolver) } - else temp map { x => (forcedRevision(x), resolver) }) + else temp map { x => (forcedRevision(x), resolver) } + ) } catch { case ex: Exception => Message.verbose("problem occurred while resolving " + dd + " with " + resolver diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 69244a817..d3cf58d6a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -79,7 +79,7 @@ object CrossVersion { /** * Cross-versions a module with the result of applying `remapVersion` to the full version - * (typically the full Scala version). See also [[sbt.CrossVersion.Full]]. + * (typically the full Scala version). See also [[sbt.librarymanagement.CrossVersion.Full]]. */ def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) @@ -88,7 +88,7 @@ object CrossVersion { /** * Cross-versions a module with the result of applying `remapVersion` to the binary version - * (typically the binary Scala version). See also [[sbt.CrossVersion.Binary]]. + * (typically the binary Scala version). See also [[sbt.librarymanagement.CrossVersion.Binary]]. */ def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) @@ -99,7 +99,7 @@ object CrossVersion { /** * Construct a cross-versioning function given cross-versioning configuration `cross`, * full version `fullVersion` and binary version `binaryVersion`. The behavior of the - * constructed function is as documented for the [[sbt.CrossVersion]] datatypes. + * constructed function is as documented for the [[sbt.librarymanagement.CrossVersion]] datatypes. */ def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { @@ -191,13 +191,13 @@ object CrossVersion { /** * Computes the binary Scala version from the `full` version. - * Full Scala versions earlier than [[sbt.CrossVersion.TransitionScalaVersion]] are returned as is. + * Full Scala versions earlier than [[sbt.librarymanagement.CrossVersion.TransitionScalaVersion]] are returned as is. */ def binaryScalaVersion(full: String): String = CrossVersionUtil.binaryScalaVersion(full) /** * Computes the binary sbt version from the `full` version. - * Full sbt versions earlier than [[sbt.CrossVersion.TransitionSbtVersion]] are returned as is. + * Full sbt versions earlier than [[sbt.librarymanagement.CrossVersion.TransitionSbtVersion]] are returned as is. */ def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index b431aa992..3a05f2e72 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -14,7 +14,8 @@ final class EvictionWarningOptions private[sbt] ( val warnTransitiveEvictions: Boolean, val infoAllEvictions: Boolean, val showCallers: Boolean, - val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]) { + val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] +) { private[sbt] def configStrings = configurations map { _.name } def withConfigurations(configurations: Seq[Configuration]): EvictionWarningOptions = @@ -32,20 +33,24 @@ final class EvictionWarningOptions private[sbt] ( def withGuessCompatible(guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]): EvictionWarningOptions = copy(guessCompatible = guessCompatible) - private[sbt] def copy(configurations: Seq[Configuration] = configurations, + private[sbt] def copy( + configurations: Seq[Configuration] = configurations, warnScalaVersionEviction: Boolean = warnScalaVersionEviction, warnDirectEvictions: Boolean = warnDirectEvictions, warnTransitiveEvictions: Boolean = warnTransitiveEvictions, infoAllEvictions: Boolean = infoAllEvictions, showCallers: Boolean = showCallers, - guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible): EvictionWarningOptions = - new EvictionWarningOptions(configurations = configurations, + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible + ): EvictionWarningOptions = + new EvictionWarningOptions( + configurations = configurations, warnScalaVersionEviction = warnScalaVersionEviction, warnDirectEvictions = warnDirectEvictions, warnTransitiveEvictions = warnTransitiveEvictions, infoAllEvictions = infoAllEvictions, showCallers = showCallers, - guessCompatible = guessCompatible) + guessCompatible = guessCompatible + ) } object EvictionWarningOptions { @@ -85,7 +90,8 @@ final class EvictionPair private[sbt] ( val winner: Option[ModuleReport], val evicteds: Seq[ModuleReport], val includesDirect: Boolean, - val showCallers: Boolean) { + val showCallers: Boolean +) { override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString override def equals(o: Any): Boolean = o match { @@ -125,7 +131,8 @@ final class EvictionWarning private[sbt] ( val scalaEvictions: Seq[EvictionPair], val directEvictions: Seq[EvictionPair], val transitiveEvictions: Seq[EvictionPair], - val allEvictions: Seq[EvictionPair]) { + val allEvictions: Seq[EvictionPair] +) { def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index b2647113c..a399cb9d9 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -21,7 +21,8 @@ object ScalaArtifacts { private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version)) + scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + ) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 090a827b4..47ab13507 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -22,18 +22,23 @@ final class UpdateOptions private[sbt] ( /** If set to true, use cached resolution. */ val cachedResolution: Boolean, /** Extention point for an alternative resolver converter. */ - val resolverConverter: UpdateOptions.ResolverConverter) { + val resolverConverter: UpdateOptions.ResolverConverter +) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) @deprecated("Use withCachedResolution instead.", "0.13.7") def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = - copy(consolidatedResolution = consolidatedResolution, - cachedResolution = consolidatedResolution) + copy( + consolidatedResolution = consolidatedResolution, + cachedResolution = consolidatedResolution + ) def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = - copy(cachedResolution = cachedResoluton, - consolidatedResolution = cachedResolution) + copy( + cachedResolution = cachedResoluton, + consolidatedResolution = cachedResolution + ) /** Extention point for an alternative resolver converter. */ def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = copy(resolverConverter = resolverConverter) @@ -43,12 +48,15 @@ final class UpdateOptions private[sbt] ( latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, - resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter): UpdateOptions = - new UpdateOptions(circularDependencyLevel, + resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter + ): UpdateOptions = + new UpdateOptions( + circularDependencyLevel, latestSnapshots, consolidatedResolution, cachedResolution, - resolverConverter) + resolverConverter + ) override def equals(o: Any): Boolean = o match { case o: UpdateOptions => @@ -79,5 +87,6 @@ object UpdateOptions { latestSnapshots = false, consolidatedResolution = false, cachedResolution = false, - resolverConverter = PartialFunction.empty) + resolverConverter = PartialFunction.empty + ) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 3e300c090..611de450f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -19,7 +19,8 @@ import sbt.internal.librarymanagement.{ DependencyFilter, ConfigurationFilter, M final class ConfigurationReport( val configuration: String, val modules: Seq[ModuleReport], - val details: Seq[OrganizationArtifactReport]) { + val details: Seq[OrganizationArtifactReport] +) { def evicted: Seq[ModuleID] = details flatMap (_.modules) filter (_.evicted) map (_.module) @@ -56,7 +57,8 @@ object ConfigurationReport { final class OrganizationArtifactReport private[sbt] ( val organization: String, val name: String, - val modules: Seq[ModuleReport]) { + val modules: Seq[ModuleReport] +) { override def toString: String = { val details = modules map { _.detailReport } s"\t$organization:$name\n${details.mkString}\n" @@ -94,7 +96,8 @@ final class ModuleReport( val branch: Option[String], val configurations: Seq[String], val licenses: Seq[(String, Option[String])], - val callers: Seq[Caller]) { + val callers: Seq[Caller] +) { private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) override def toString: String = { @@ -113,20 +116,28 @@ final class ModuleReport( reportStr("evictedReason", evictedReason) + reportStr("problem", problem) + reportStr("homepage", homepage) + - reportStr("textraAttributes", + reportStr( + "textraAttributes", if (extraAttributes.isEmpty) None - else { Some(extraAttributes.toString) }) + + else { Some(extraAttributes.toString) } + ) + reportStr("isDefault", isDefault map { _.toString }) + reportStr("branch", branch) + - reportStr("configurations", + reportStr( + "configurations", if (configurations.isEmpty) None - else { Some(configurations.mkString(", ")) }) + - reportStr("licenses", + else { Some(configurations.mkString(", ")) } + ) + + reportStr( + "licenses", if (licenses.isEmpty) None - else { Some(licenses.mkString(", ")) }) + - reportStr("callers", + else { Some(licenses.mkString(", ")) } + ) + + reportStr( + "callers", if (callers.isEmpty) None - else { Some(callers.mkString(", ")) }) + else { Some(callers.mkString(", ")) } + ) private[sbt] def reportStr(key: String, value: Option[String]): String = value map { x => s"\t\t\t$key: $x\n" } getOrElse "" @@ -151,7 +162,8 @@ final class ModuleReport( branch: Option[String] = branch, configurations: Seq[String] = configurations, licenses: Seq[(String, Option[String])] = licenses, - callers: Seq[Caller] = callers): ModuleReport = + callers: Seq[Caller] = callers + ): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } @@ -170,7 +182,8 @@ final class Caller( val isForceDependency: Boolean, val isChangingDependency: Boolean, val isTransitiveDependency: Boolean, - val isDirectlyForceDependency: Boolean) { + val isDirectlyForceDependency: Boolean +) { override def toString: String = s"$caller" } @@ -207,10 +220,12 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con def allConfigurations: Seq[String] = configurations.map(_.configuration) private[sbt] def withStats(us: UpdateStats): UpdateReport = - new UpdateReport(this.cachedDescriptor, + new UpdateReport( + this.cachedDescriptor, this.configurations, us, - this.stamps) + this.stamps + ) } object UpdateReport { @@ -248,14 +263,16 @@ object UpdateReport { moduleReportMap { (configuration, modReport) => modReport.copy( artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, - missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }) + missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } + ) } def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) modReport.copy( artifacts = f(configuration, modReport.module, modReport.artifacts), - missingArtifacts = Nil) + missingArtifacts = Nil + ) } def toSeq: Seq[(String, ModuleID, Artifact, File)] = @@ -267,7 +284,8 @@ object UpdateReport { def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => modReport.copy( - missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct) + missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct + ) } def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = @@ -338,10 +356,12 @@ object UpdateReport { final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") private[sbt] def withCached(c: Boolean): UpdateStats = - new UpdateStats(resolveTime = this.resolveTime, + new UpdateStats( + resolveTime = this.resolveTime, downloadTime = this.downloadTime, downloadSize = this.downloadSize, - cached = c) + cached = c + ) } object UpdateStats { implicit val pickler: Pickler[UpdateStats] with Unpickler[UpdateStats] = PicklerUnpickler.generate[UpdateStats] diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 1f736398b..674ffc363 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -3,7 +3,8 @@ package sbt.librarymanagement final class VersionNumber private[sbt] ( val numbers: Seq[Long], val tags: Seq[String], - val extras: Seq[String]) { + val extras: Seq[String] +) { def _1: Option[Long] = get(0) def _2: Option[Long] = get(1) def _3: Option[Long] = get(2) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 7ac8a3014..b0744fd3b 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -29,7 +29,8 @@ trait BaseIvySpecification extends UnitSpec { configurations = Nil, checkExplicit = true, filterImplicit = false, - overrideScalaVersion = false) + overrideScalaVersion = false + ) } val moduleSetting: ModuleSettings = InlineConfiguration( @@ -37,7 +38,8 @@ trait BaseIvySpecification extends UnitSpec { moduleInfo = ModuleInfo("foo"), dependencies = deps, configurations = configurations, - ivyScala = ivyScala) + ivyScala = ivyScala + ) val ivySbt = new IvySbt(mkIvyConfiguration(uo)) new ivySbt.Module(moduleSetting) } @@ -81,7 +83,8 @@ trait BaseIvySpecification extends UnitSpec { artifacts = artifacts, checksums = Seq(), logging = UpdateLogging.Full, - overwrite = true) + overwrite = true + ) } def ivyPublish(module: IvySbt#Module, config: PublishConfiguration) = { diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index fb9e86e3d..4fc6faa3e 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -8,8 +8,10 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving the same module twice" should "work" in { cleanIvyCache() - val m = module(ModuleID("com.example", "foo", "0.1.0", Some("compile")), - Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + val m = module( + ModuleID("com.example", "foo", "0.1.0", Some("compile")), + Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + ) val report = ivyUpdate(m) cleanCachedResolutionCache(m) val report2 = ivyUpdate(m) @@ -22,8 +24,10 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving the unsolvable module should" should "not work" in { // log.setLevel(Level.Debug) - val m = module(ModuleID("com.example", "foo", "0.2.0", Some("compile")), - Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + val m = module( + ModuleID("com.example", "foo", "0.2.0", Some("compile")), + Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + ) ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed") case Left(uw) => @@ -47,9 +51,11 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving a module with a pseudo-conflict" should "work" in { // log.setLevel(Level.Debug) cleanIvyCache() - val m = module(ModuleID("com.example", "foo", "0.3.0", Some("compile")), + val m = module( + ModuleID("com.example", "foo", "0.3.0", Some("compile")), Seq(avro177, dataAvro1940, netty320), - Some("2.10.2"), UpdateOptions().withCachedResolution(true)) + Some("2.10.2"), UpdateOptions().withCachedResolution(true) + ) // first resolution creates the minigraph val report0 = ivyUpdate(m) cleanCachedResolutionCache(m) diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index d1a93c6ae..5dd65a494 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -74,21 +74,25 @@ class EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe - List("Scala version was updated by one of library dependencies:", + List( + "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", "To force scalaVersion, add the following:", "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", - "Run 'evicted' to see detailed eviction warnings") + "Run 'evicted' to see detailed eviction warnings" + ) } def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe - List("Scala version was updated by one of library dependencies:", + List( + "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", "To force scalaVersion, add the following:", - "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }") + "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" + ) } def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) @@ -109,19 +113,23 @@ class EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe - List("There may be incompatibilities among your library dependencies.", + List( + "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* commons-io:commons-io:1.4 -> 2.4", - "Run 'evicted' to see detailed eviction warnings") + "Run 'evicted' to see detailed eviction warnings" + ) } def javaLibWarn4() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe - List("There may be incompatibilities among your library dependencies.", + List( + "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)") + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" + ) } def javaLibNoWarn1() = { @@ -156,9 +164,11 @@ class EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe - List("There may be incompatibilities among your library dependencies.", + List( + "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)") + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)" + ) } def scalaLibWarn1() = { @@ -173,10 +183,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe - List("There may be incompatibilities among your library dependencies.", + List( + "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4", - "Run 'evicted' to see detailed eviction warnings") + "Run 'evicted' to see detailed eviction warnings" + ) } def scalaLibNoWarn1() = { @@ -211,8 +223,10 @@ class EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe - List("There may be incompatibilities among your library dependencies.", + List( + "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)") + "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)" + ) } } diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index 5bcbcebcd..3d99a0804 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -7,8 +7,10 @@ import sbt.librarymanagement._ class InconsistentDuplicateSpec extends UnitSpec { "Duplicate with different version" should "be warned" in { IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) shouldBe - List("Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", - " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)") + List( + "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", + " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)" + ) } "Duplicate with same version" should "not be warned" in { diff --git a/project/house.sbt b/project/house.sbt index eefc29672..fede298d1 100644 --- a/project/house.sbt +++ b/project/house.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.1.0") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.2.1") From a217178d02f52e657b2435c0ad0b7e26816a1bef Mon Sep 17 00:00:00 2001 From: Eugene Platonov Date: Thu, 17 Sep 2015 11:39:38 -0400 Subject: [PATCH 0457/1030] add toString to UpdateOptions --- .../sbt/librarymanagement/UpdateOptions.scala | 9 ++++++- .../src/test/scala/UpdateOptionsSpec.scala | 27 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 librarymanagement/src/test/scala/UpdateOptionsSpec.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 090a827b4..4404d7dd6 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -1,6 +1,5 @@ package sbt.librarymanagement -import java.io.File import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings import sbt.util.Logger @@ -50,6 +49,14 @@ final class UpdateOptions private[sbt] ( cachedResolution, resolverConverter) + override def toString(): String = + s"""UpdateOptions( + | circularDependencyLevel = $circularDependencyLevel, + | latestSnapshots = $latestSnapshots, + | consolidatedResolution = $consolidatedResolution, + | cachedResolution = $cachedResolution + |)""".stripMargin + override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && diff --git a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala new file mode 100644 index 000000000..c347ef0e6 --- /dev/null +++ b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala @@ -0,0 +1,27 @@ +package sbt.librarymanagement + +import sbt.internal.util.UnitSpec + +class UpdateOptionsSpec extends UnitSpec { + + "UpdateOptions" should "have proper toString defined" in { + UpdateOptions().toString() should be( + """|UpdateOptions( + | circularDependencyLevel = warn, + | latestSnapshots = false, + | consolidatedResolution = false, + | cachedResolution = false + |)""".stripMargin) + + UpdateOptions() + .withCircularDependencyLevel(CircularDependencyLevel.Error) + .withCachedResolution(true) + .withLatestSnapshots(true).toString() should be( + """|UpdateOptions( + | circularDependencyLevel = error, + | latestSnapshots = true, + | consolidatedResolution = false, + | cachedResolution = true + |)""".stripMargin) + } +} From 9cd670ac346b4d2b9f0ae8c4e323d1feb737f784 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 18 Sep 2015 00:57:18 +0100 Subject: [PATCH 0458/1030] Remove redundant Bintray settings --- build.sbt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/build.sbt b/build.sbt index b60ba9188..3ef70886c 100644 --- a/build.sbt +++ b/build.sbt @@ -14,8 +14,6 @@ def commonSettings: Seq[Setting[_]] = Seq( javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala210, scala211), - bintrayPackage := (bintrayPackage in ThisBuild).value, - bintrayRepository := (bintrayRepository in ThisBuild).value, resolvers += Resolver.sonatypeRepo("public"), publishArtifact in Compile := true, publishArtifact in Test := true, @@ -51,9 +49,6 @@ lazy val root = (project in file(".")). Developer("jsuereth", "Josh Suereth", "@jsuereth", url("https://github.com/jsuereth")), Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")) ), - bintrayReleaseOnPublish := false, - bintrayOrganization := Some("sbt"), - bintrayRepository := "maven-releases", bintrayPackage := "librarymanagement", git.baseVersion := baseVersion )), From 9a2b007a926dca934df4413f3c8b0bdd0e94ba30 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Fri, 18 Sep 2015 09:05:43 +0100 Subject: [PATCH 0459/1030] Remove more redundant settings --- build.sbt | 8 -------- 1 file changed, 8 deletions(-) diff --git a/build.sbt b/build.sbt index 3ef70886c..47d78deb5 100644 --- a/build.sbt +++ b/build.sbt @@ -38,17 +38,9 @@ lazy val root = (project in file(".")). aggregate(lm). settings( inThisBuild(Seq( - organization := "org.scala-sbt", homepage := Some(url("https://github.com/sbt/librarymanagement")), description := "Library management module for sbt", - licenses := List("BSD New" -> url("https://github.com/sbt/sbt/blob/0.13/LICENSE")), scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git")), - developers := List( - Developer("harrah", "Mark Harrah", "@harrah", url("https://github.com/harrah")), - Developer("eed3si9n", "Eugene Yokota", "@eed3si9n", url("https://github.com/eed3si9n")), - Developer("jsuereth", "Josh Suereth", "@jsuereth", url("https://github.com/jsuereth")), - Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")) - ), bintrayPackage := "librarymanagement", git.baseVersion := baseVersion )), From e6a401b4c37f56fa3244313a50683072453faeac Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 1 Oct 2015 21:33:58 +0100 Subject: [PATCH 0460/1030] Add localIfFile to MavenRepository & use it port of sbt/sbt#2172, fixes sbt/librarymanagement#7 --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 2 +- .../src/main/scala/sbt/librarymanagement/Resolver.scala | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 12fd82100..99b731f89 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -127,7 +127,7 @@ private[sbt] object ConvertResolver { } } val resolver = new PluginCapableResolver - resolver.setRepository(new LocalIfFileRepo) + if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) initializeMavenStyle(resolver, repo.name, repo.root) resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns resolver diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 48d9c69bf..e081ae370 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -32,9 +32,10 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver { sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver /** An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts. */ -sealed case class MavenRepository(name: String, root: String) extends Resolver { - override def toString = name + ": " + root +sealed case class MavenRepository(name: String, root: String, localIfFile: Boolean = true) extends Resolver { + override def toString = s"$name: $root" def isCache: Boolean = false + def withLocalIfFile(value: Boolean) = MavenRepository(name, root, value) } /** @@ -42,7 +43,7 @@ sealed case class MavenRepository(name: String, root: String) extends Resolver { * the metadata is different (see Aether ML discussion). */ final class MavenCache(name: String, val rootFile: File) extends MavenRepository(name, rootFile.toURI.toURL.toString) { - override val toString = "cache:" + name + ": " + rootFile.getAbsolutePath + override val toString = s"cache:$name: ${rootFile.getAbsolutePath}" override def isCache: Boolean = true } object MavenCache { From 8d12cdac63fe530e725c3e0ade6ad3d4a8a2436b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Oct 2015 21:57:25 -0400 Subject: [PATCH 0461/1030] Split RichUpdateReport into internal --- deltag.sh | 7 ++ .../librarymanagement/RichUpdateReport.scala | 75 +++++++++++++++++++ .../internal/librarymanagement/syntax.scala | 10 +++ .../sbt/librarymanagement/UpdateReport.scala | 70 ----------------- 4 files changed, 92 insertions(+), 70 deletions(-) create mode 100755 deltag.sh create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala diff --git a/deltag.sh b/deltag.sh new file mode 100755 index 000000000..d9510e9b5 --- /dev/null +++ b/deltag.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +for t in `git tag` +do + git tag -d $t +done + diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala new file mode 100644 index 000000000..3c43e863a --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -0,0 +1,75 @@ +package sbt +package internal +package librarymanagement + +import java.io.File +import java.net.URL +import sbt.librarymanagement._ + +/** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ +final class RichUpdateReport(report: UpdateReport) { + def recomputeStamps(): UpdateReport = + { + val files = report.cachedDescriptor +: allFiles + val stamps = files.map(f => (f, f.lastModified)).toMap + new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) + } + + import DependencyFilter._ + + /** Obtains all successfully retrieved files in all configurations and modules. */ + def allFiles: Seq[File] = matching(DependencyFilter.allPass) + + /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ + def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + + /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ + def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = + matching(DependencyFilter.make(configuration, module, artifact)) + + private[this] def select0(f: DependencyFilter): Seq[File] = + for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { + if (file == null) sys.error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) + file + } + + /** Constructs a new report that only contains files matching the specified filter.*/ + private[sbt] def filter(f: DependencyFilter): UpdateReport = + moduleReportMap { (configuration, modReport) => + modReport.copy( + artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, + missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } + ) + } + def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = + moduleReportMap { (configuration, modReport) => + val newArtifacts = f(configuration, modReport.module, modReport.artifacts) + modReport.copy( + artifacts = f(configuration, modReport.module, modReport.artifacts), + missingArtifacts = Nil + ) + } + + def toSeq: Seq[(String, ModuleID, Artifact, File)] = + for (confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) + + def allMissing: Seq[(String, ModuleID, Artifact)] = + for (confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield (confReport.configuration, modReport.module, artifact) + + def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = + moduleReportMap { (configuration, modReport) => + modReport.copy( + missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct + ) + } + + def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = + { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = modules map { modReport => f(configuration, modReport) } + new ConfigurationReport(configuration, newModules, details, evicted) + } + new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) + } +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala new file mode 100644 index 000000000..4ddc5d243 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala @@ -0,0 +1,10 @@ +package sbt +package internal +package librarymanagement + +import sbt.librarymanagement._ + +object syntax { + implicit def richUpateReport(ur: UpdateReport): RichUpdateReport = + new RichUpdateReport(ur) +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 611de450f..e2f19827f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -229,76 +229,6 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con } object UpdateReport { - implicit def richUpdateReport(report: UpdateReport): RichUpdateReport = new RichUpdateReport(report) - - /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ - final class RichUpdateReport(report: UpdateReport) { - def recomputeStamps(): UpdateReport = - { - val files = report.cachedDescriptor +: allFiles - val stamps = files.map(f => (f, f.lastModified)).toMap - new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) - } - - import DependencyFilter._ - - /** Obtains all successfully retrieved files in all configurations and modules. */ - def allFiles: Seq[File] = matching(DependencyFilter.allPass) - - /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - private[sbt] def matching(f: DependencyFilter): Seq[File] = select0(f).distinct - - /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ - private[sbt] def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = - matching(DependencyFilter.make(configuration, module, artifact)) - - private[this] def select0(f: DependencyFilter): Seq[File] = - for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { - if (file == null) sys.error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) - file - } - - /** Constructs a new report that only contains files matching the specified filter.*/ - private[sbt] def filter(f: DependencyFilter): UpdateReport = - moduleReportMap { (configuration, modReport) => - modReport.copy( - artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, - missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } - ) - } - def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = - moduleReportMap { (configuration, modReport) => - val newArtifacts = f(configuration, modReport.module, modReport.artifacts) - modReport.copy( - artifacts = f(configuration, modReport.module, modReport.artifacts), - missingArtifacts = Nil - ) - } - - def toSeq: Seq[(String, ModuleID, Artifact, File)] = - for (confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) - - def allMissing: Seq[(String, ModuleID, Artifact)] = - for (confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield (confReport.configuration, modReport.module, artifact) - - def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = - moduleReportMap { (configuration, modReport) => - modReport.copy( - missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct - ) - } - - def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = - { - val newConfigurations = report.configurations.map { confReport => - import confReport._ - val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, details) - } - new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) - } - } - private val vectorConfigurationReportPickler = implicitly[Pickler[Vector[ConfigurationReport]]] private val vectorConfigurationReportUnpickler = implicitly[Unpickler[Vector[ConfigurationReport]]] private val updateStatsPickler = implicitly[Pickler[UpdateStats]] From 82282a20907bf0a475688a77ecbea9663488a99a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Oct 2015 21:57:37 -0400 Subject: [PATCH 0462/1030] bump util --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ee5217690..f07eb3e1d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ object Dependencies { lazy val scala210 = "2.10.5" lazy val scala211 = "2.11.7" - val utilVersion = "0.1.0-M3" + val utilVersion = "0.1.0-M5" val ioVersion = "1.0.0-M3" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion From 5af540628f76606370668c06f295177c24a1d8a0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Oct 2015 23:44:10 -0400 Subject: [PATCH 0463/1030] use the internal syntax --- .../main/scala/sbt/internal/librarymanagement/IvyActions.scala | 1 + .../main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala | 1 + .../scala/sbt/internal/librarymanagement/RichUpdateReport.scala | 2 +- .../ivyint/CachedResolutionResolveEngine.scala | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 817d41a69..6353530cd 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -20,6 +20,7 @@ import sbt.io.{ IO, PathFinder } import sbt.util.Logger import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } import sbt.librarymanagement._ +import sbt.internal.librarymanagement.syntax._ final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 196e0e1ae..765af3ab1 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -15,6 +15,7 @@ import resolve.{ IvyNode, IvyNodeCallers } import IvyNodeCallers.{ Caller => IvyCaller } import ivyint.SbtDefaultDependencyDescriptor import sbt.librarymanagement._ +import sbt.internal.librarymanagement.syntax._ object IvyRetrieve { def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala index 3c43e863a..61675fd2d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -68,7 +68,7 @@ final class RichUpdateReport(report: UpdateReport) { val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, details, evicted) + new ConfigurationReport(configuration, newModules, details) } new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 4a8a8094e..c566fea30 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -25,6 +25,7 @@ import sbt.io.{ DirectoryFilter, Hash, IO, Path } import sbt.util.Logger import sbt.librarymanagement._ import Configurations.{ System => _, _ } +import sbt.internal.librarymanagement.syntax._ private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = From c97563a0c0df4c0c35421ed33e78495ab6e50dc4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Oct 2015 23:57:58 -0400 Subject: [PATCH 0464/1030] change Scaladoc style comment --- .../scala/sbt/librarymanagement/UpdateOptions.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 47ab13507..be2ad412f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -13,15 +13,15 @@ import sbt.util.Logger * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( - /** If set to CircularDependencyLevel.Error, halt the dependency resolution. */ + // If set to CircularDependencyLevel.Error, halt the dependency resolution. val circularDependencyLevel: CircularDependencyLevel, - /** If set to true, check all resolvers for snapshots. */ + // If set to true, check all resolvers for snapshots. val latestSnapshots: Boolean, - /** If set to true, use consolidated resolution. */ + // If set to true, use consolidated resolution. val consolidatedResolution: Boolean, - /** If set to true, use cached resolution. */ + // If set to true, use cached resolution. val cachedResolution: Boolean, - /** Extention point for an alternative resolver converter. */ + // Extention point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter ) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = From c740f4c29e69716c91ada2152db33955e2d9ffb2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 2 Oct 2015 02:47:44 -0400 Subject: [PATCH 0465/1030] Remove deltag.sh --- deltag.sh | 7 ------- 1 file changed, 7 deletions(-) delete mode 100755 deltag.sh diff --git a/deltag.sh b/deltag.sh deleted file mode 100755 index d9510e9b5..000000000 --- a/deltag.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -for t in `git tag` -do - git tag -d $t -done - From 4831da8f4b080dba1b1cb08f842ad0e1a436cca5 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Wed, 11 Nov 2015 15:12:05 +0100 Subject: [PATCH 0466/1030] Don't warn on inconsistent versions in different configurations (This is a port of sbt/sbt#2258) sbt was reporting warning abouts inconsistent versions of dependencies even if these dependencies didn't have the same configuration (as in `provided` vs `compile`). This commit fixes this problem by comparing the dependencies by organization, artifact name and configuration. --- .../main/scala/sbt/internal/librarymanagement/Ivy.scala | 8 ++++++-- .../src/test/scala/InconsistentDuplicateSpec.scala | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 85071af19..c39c30565 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -529,14 +529,18 @@ private[sbt] object IvySbt { { import IvyRetrieve.toModuleID val dds = moduleID.getDependencies - inconsistentDuplicateWarning(dds map { dd => toModuleID(dd.getDependencyRevisionId) }) + val deps = dds flatMap { dd => + val module = toModuleID(dd.getDependencyRevisionId) + dd.getModuleConfigurations map (c => module.copy(configurations = Some(c))) + } + inconsistentDuplicateWarning(deps) } def inconsistentDuplicateWarning(dependencies: Seq[ModuleID]): List[String] = { val warningHeader = "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:" val out: mutable.ListBuffer[String] = mutable.ListBuffer() - (dependencies groupBy { dep => (dep.organization, dep.name) }) foreach { + (dependencies groupBy { dep => (dep.organization, dep.name, dep.configurations) }) foreach { case (k, vs) if vs.size > 1 => val v0 = vs.head (vs find { _.revision != v0.revision }) foreach { v => diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index 3d99a0804..ab910609c 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -13,6 +13,10 @@ class InconsistentDuplicateSpec extends UnitSpec { ) } + it should "not be warned if in different configurations" in { + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230Test)) shouldBe Nil + } + "Duplicate with same version" should "not be warned" in { IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil } From 0cef0c3680652de78d35719b396d79b78d7f742e Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 24 Nov 2015 18:19:35 +0000 Subject: [PATCH 0467/1030] Add Resolver.bintrayIvyRepo --- .../src/main/scala/sbt/librarymanagement/Resolver.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index e081ae370..6f7bd607c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -201,6 +201,7 @@ object Resolver { def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) def bintrayRepo(owner: String, repo: String) = new MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") + def bintrayIvyRepo(owner: String, repo: String) = url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))(Resolver.ivyStylePatterns) def jcenterRepo = JCenterRepository /** Add the local and Maven Central repositories to the user repositories. */ From ac571371c6ef0b15969675b73ffd404119ab40ad Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Thu, 3 Dec 2015 15:53:29 +0100 Subject: [PATCH 0468/1030] Fixes sbt/sbt#2264. Use explicit artifacts if any, fallback to hardcoded Even though it's not really used, updateClassifiers constructs dependency graph based on the result from update. The direct cause of sbt/sbt#2264 came from the fact that the `allModules` returned from ConfigurationReport did not include dependency configurations. For example it returned "compile" instead of "compile->runtime". I've identified that in #2264 and was fixed by @Duhemm in sbt/sbt@f49fb33. Martin identified that the fix still does not address the fact that updateClassifier hardcodes the classifiers to be tried. This commit adds the fallback behavior so for Ivy-published modules it will use the explicit list of artifacts, and for others it will fallback to the hardcoded list of classifiers. --- .../librarymanagement/IvyActions.scala | 30 +++++++++++++++---- .../sbt/librarymanagement/UpdateReport.scala | 27 +++++++++++++++-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 817d41a69..d6ce9b20d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -236,20 +236,24 @@ object IvyActions { throw w.resolveException } val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, log) + updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) } @deprecated("This is no longer public.", "0.13.6") def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) + updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) + // artifacts can be obtained from calling toSeq on UpdateReport private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): UpdateReport = + uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], + artifacts: Vector[(String, ModuleID, Artifact, File)], + log: Logger): UpdateReport = { import config.{ configuration => c, module => mod, _ } import mod.{ configurations => confs, _ } assert(classifiers.nonEmpty, "classifiers cannot be empty") val baseModules = modules map { m => restrictedCopy(m, true) } - val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude) + // Adding list of explicit artifacts here. + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) @@ -259,7 +263,23 @@ object IvyActions { throw w.resolveException } } - def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = + // This version adds explicit artifact + private[sbt] def classifiedArtifacts( + classifiers: Seq[String], + exclude: Map[ModuleID, Set[String]], + artifacts: Vector[(String, ModuleID, Artifact, File)] + )(m: ModuleID): Option[ModuleID] = { + def sameModule(m1: ModuleID, m2: ModuleID): Boolean = m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision + def explicitArtifacts = + { + val arts = (artifacts collect { case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art }).distinct + if (arts.isEmpty) None + else Some(m.copy(isTransitive = false, explicitArtifacts = arts)) + } + def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) + explicitArtifacts orElse hardcodedArtifacts + } + private def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) val included = classifiers filterNot excluded diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 611de450f..c51617dee 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -33,8 +33,14 @@ final class ConfigurationReport( * All resolved modules for this configuration. * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. */ - def allModules: Seq[ModuleID] = modules.map(mr => addConfiguration(mr.module)) - private[this] def addConfiguration(mod: ModuleID): ModuleID = if (mod.configurations.isEmpty) mod.copy(configurations = Some(configuration)) else mod + def allModules: Seq[ModuleID] = modules map addConfiguration + private[this] def addConfiguration(mr: ModuleReport): ModuleID = { + val module = mr.module + if (module.configurations.isEmpty) { + val conf = mr.configurations map (c => s"$configuration->$c") mkString ";" + module.copy(configurations = Some(conf)) + } else module + } def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) @@ -208,7 +214,22 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString /** All resolved modules in all configurations. */ - def allModules: Seq[ModuleID] = configurations.flatMap(_.allModules).distinct + def allModules: Seq[ModuleID] = + { + val key = (m: ModuleID) => (m.organization, m.name, m.revision) + configurations.flatMap(_.allModules).groupBy(key).toSeq map { + case (k, v) => + v reduceLeft { (agg, x) => + agg.copy( + configurations = (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } + ) + } + } + } def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) From b87fb4627e8d8fc9b0e97b80eb9c86ba3aa21487 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Dec 2015 02:02:20 -0500 Subject: [PATCH 0469/1030] Update util to 0.1.0-M8 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f07eb3e1d..9c78cc053 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,11 +2,11 @@ import sbt._ import Keys._ object Dependencies { - lazy val scala210 = "2.10.5" + lazy val scala210 = "2.10.6" lazy val scala211 = "2.11.7" - val utilVersion = "0.1.0-M5" val ioVersion = "1.0.0-M3" + val utilVersion = "0.1.0-M8" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion From 84e7c5a360d724990ffed2d7ea4bff6af52c8f87 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Thu, 24 Dec 2015 09:07:02 +0100 Subject: [PATCH 0470/1030] Bump Scala version in .travis.yml and build.sbt --- .travis.yml | 2 +- build.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a5b73c0d8..8dc242caf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: scala scala: - - 2.10.5 + - 2.10.6 - 2.11.7 diff --git a/build.sbt b/build.sbt index 47d78deb5..ed06b97a0 100644 --- a/build.sbt +++ b/build.sbt @@ -4,7 +4,7 @@ def baseVersion = "0.1.0" def internalPath = file("internal") def commonSettings: Seq[Setting[_]] = Seq( - scalaVersion := "2.10.5", + scalaVersion := scala210, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), From f87eabdc9874a884e916c1bb64958fd8c61bac5f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 16 Jan 2016 15:44:55 +0000 Subject: [PATCH 0471/1030] FPORT: Make Make JCenter opt in Forward-port of sbt/sbt#2335. --- .../sbt/librarymanagement/Resolver.scala | 32 ++++++++++++++++++- .../src/test/scala/EvictionWarningSpec.scala | 30 +++++++++-------- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 6f7bd607c..6831a2520 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -206,15 +206,45 @@ object Resolver { /** Add the local and Maven Central repositories to the user repositories. */ def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = - withDefaultResolvers(userResolvers, true) + withDefaultResolvers(userResolvers, mavenCentral = true) + /** * Add the local Ivy repository to the user repositories. * If `mavenCentral` is true, add the Maven Central repository. */ def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = + withDefaultResolvers(userResolvers, jcenter = false, mavenCentral) + + /** + * Add the local Ivy repository to the user repositories. + * If `jcenter` is true, add the JCenter. + * If `mavenCentral` is true, add the Maven Central repository. + */ + def withDefaultResolvers(userResolvers: Seq[Resolver], jcenter: Boolean, mavenCentral: Boolean): Seq[Resolver] = Seq(Resolver.defaultLocal) ++ userResolvers ++ + single(JCenterRepository, jcenter) ++ single(DefaultMavenRepository, mavenCentral) + + /** + * Reorganize the built-in resolvers that is configured for this application by the sbt launcher. + * If `jcenter` is true, add the JCenter. + * If `mavenCentral` is true, add the Maven Central repository. + */ + private[sbt] def reorganizeAppResolvers(appResolvers: Seq[Resolver], jcenter: Boolean, mavenCentral: Boolean): Seq[Resolver] = + appResolvers.partition(_ == Resolver.defaultLocal) match { + case (locals, xs) => + locals ++ + (xs.partition(_ == JCenterRepository) match { + case (jc, xs) => + single(JCenterRepository, jcenter) ++ + (xs.partition(_ == DefaultMavenRepository) match { + case (m, xs) => + single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates? + }) + }) + } + private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if (nonEmpty) Seq(value) else Nil /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 5dd65a494..35b3e994b 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -5,36 +5,38 @@ import sbt.internal.librarymanagement.BaseIvySpecification class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - "Eviction of scala-library whose scalaVersion" should "be detected" in scalaVersionWarn1() + """Eviction of scala-library whose scalaVersion + """ should "be detected" in scalaVersionWarn1() it should "not be detected if it's diabled" in scalaVersionWarn2() it should "print out message about the eviction" in scalaVersionWarn3() it should "print out message about the eviction with callers" in scalaVersionWarn4() - """Including two (suspect) binary incompatible Java libraries to - direct dependencies""" should "be detected as eviction" in javaLibWarn1() + """Including two (suspect) binary incompatible Java libraries to direct dependencies + """ should "be detected as eviction" in javaLibWarn1() it should "not be detected if it's disabled" in javaLibWarn2() it should "print out message about the eviction" in javaLibWarn3() it should "print out message about the eviction with callers" in javaLibWarn4() - """Including two (suspect) binary compatible Java libraries to - direct dependencies""" should "not be detected as eviction" in javaLibNoWarn1() + """Including two (suspect) binary compatible Java libraries to direct dependencies + """ should "not be detected as eviction" in javaLibNoWarn1() it should "print out message about the eviction" in javaLibNoWarn2() - """Including two (suspect) transitively binary incompatible Java libraries to - direct dependencies""" should "be not detected as eviction" in javaLibTransitiveWarn1() + """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies + """ should "be not detected as eviction" in javaLibTransitiveWarn1() it should "be detected if it's enabled" in javaLibTransitiveWarn2() - it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() - """Including two (suspect) binary incompatible Scala libraries to - direct dependencies""" should "be detected as eviction" in scalaLibWarn1() + //it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() + + """Including two (suspect) binary incompatible Scala libraries to direct dependencies + """ should "be detected as eviction" in scalaLibWarn1() it should "print out message about the eviction" in scalaLibWarn2() - """Including two (suspect) binary compatible Scala libraries to - direct dependencies""" should "not be detected as eviction" in scalaLibNoWarn1() + """Including two (suspect) binary compatible Scala libraries to direct dependencies + """ should "not be detected as eviction" in scalaLibNoWarn1() it should "print out message about the eviction" in scalaLibNoWarn2() - """Including two (suspect) transitively binary incompatible Scala libraries to - direct dependencies""" should "be not detected as eviction" in scalaLibTransitiveWarn1() + """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies + """ should "be not detected as eviction" in scalaLibTransitiveWarn1() it should "be detected if it's enabled" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() From 368866bce92c01bc563ca1d0c54054d00557de5d Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Wed, 30 Dec 2015 22:38:55 +0100 Subject: [PATCH 0472/1030] Make sbt aware of Dotty This small set of changes, together with the compiler-bridge I wrote (https://github.com/smarter/dotty-bridge) enables us to compile code using Dotty in sbt, see https://github.com/smarter/dotty-example-project for an example. Partial forward port of sbt/sbt#2344. --- .../scala/sbt/librarymanagement/IvyScala.scala | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index a399cb9d9..b12f5d27e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -17,12 +17,20 @@ object ScalaArtifacts { val LibraryID = "scala-library" val CompilerID = "scala-compiler" val ReflectID = "scala-reflect" + val DottyIDPrefix = "dotty" + + def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" + def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) - private[sbt] def toolDependencies(org: String, version: String): Seq[ModuleID] = Seq( - scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version) - ) + private[sbt] def toolDependencies(org: String, version: String, isDotty: Boolean = false): Seq[ModuleID] = + if (isDotty) + Seq(ModuleID(org, DottyIDPrefix, version, Some(Configurations.ScalaTool.name + "->compile"), + crossVersion = CrossVersion.binary)) + else + Seq(scalaToolDependency(org, ScalaArtifacts.CompilerID, version), + scalaToolDependency(org, ScalaArtifacts.LibraryID, version)) + private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) } From 17397249ae92144efa194dae464faad3c59406c1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 30 Dec 2015 13:41:31 -0500 Subject: [PATCH 0473/1030] Move intransitive warning to update. Ref #2127 --- .../main/scala/sbt/CompatibilityWarning.scala | 25 ++++++++++++ .../internal/librarymanagement/MakePom.scala | 38 +++++++------------ 2 files changed, 39 insertions(+), 24 deletions(-) create mode 100644 ivy/src/main/scala/sbt/CompatibilityWarning.scala diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala new file mode 100644 index 000000000..7c7a7c1fb --- /dev/null +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -0,0 +1,25 @@ +package sbt + +private[sbt] object CompatibilityWarning { + def apply(module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { + if (mavenStyle) { + processIntransitive(module, log) + } + } + + def processIntransitive(module: IvySbt#Module, log: Logger): Unit = { + val directDependencies: Seq[ModuleID] = module.moduleSettings match { + case x: InlineConfiguration => x.dependencies + case x: InlineConfigurationWithExcludes => x.dependencies + case _ => Seq() + } + directDependencies foreach { m => + if (!m.isTransitive) { + log.warn( + s"""Found intransitive dependency ($m), but maven does not support intransitive dependencies. + | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. + """.stripMargin) + } else () + } + } +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index ea4990736..e52bb165b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -238,31 +238,21 @@ class MakePom(val log: Logger) { def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = makeDependency(dependency, includeTypes, Nil) - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = { - def warnIntransitve(): Unit = - if (!dependency.isTransitive) - log.warn( - s"""Translating intransitive dependency (${dependency.getDependencyId}) into pom.xml, but maven does not support intransitive dependencies. - | Please use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. - """.stripMargin - ) - else () - val artifacts = dependency.getAllDependencyArtifacts - val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) - if (artifacts.isEmpty) { - val configs = dependency.getModuleConfigurations - if (!configs.forall(Set("sources", "docs"))) { - warnIntransitve() - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None, excludes) - } else NodeSeq.Empty - } else if (includeArtifacts.isEmpty) { - NodeSeq.Empty - } else { - warnIntransitve() - NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) + def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = + { + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if (artifacts.isEmpty) { + val configs = dependency.getModuleConfigurations + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None, excludes) + } else NodeSeq.Empty + } else if (includeArtifacts.isEmpty) + NodeSeq.Empty + else + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) } - } @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = From 6fb70aedf135a05566576608453706da4f6ce771 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 00:25:21 -0500 Subject: [PATCH 0474/1030] Reproduce "configuration not public" on local test->test. #1827 --- .../chainresolver/build.sbt | 36 +++++++++++++++++++ .../dependency-management/chainresolver/test | 3 ++ 2 files changed, 39 insertions(+) create mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/build.sbt create mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/test diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt b/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt new file mode 100644 index 000000000..f9454c341 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt @@ -0,0 +1,36 @@ +lazy val check = taskKey[Unit]("Runs the check") + +def commonSettings: Seq[Def.Setting[_]] = + Seq( + ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((target in LocalRootProject).value / "ivy-cache")), + scalaVersion in ThisBuild := "2.11.7", + organization in ThisBuild := "com.example", + version in ThisBuild := "0.1.0-SNAPSHOT", + autoScalaLibrary := false, + crossPaths := false + ) + +lazy val realCommonsIoClient = project. + settings( + commonSettings, + name := "a", + libraryDependencies := Seq( + "commons-io" % "commons-io" % "1.3" + ), + fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project") + ) + +lazy val fakeCommonsIo = project. + settings( + commonSettings, + organization := "commons-io", + name := "commons-io", + version := "1.3" + ) + +lazy val fakeCommonsIoClient = project. + dependsOn(fakeCommonsIo % "test->test"). + settings( + commonSettings, + name := "c" + ) diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/test b/sbt/src/sbt-test/dependency-management/chainresolver/test new file mode 100644 index 000000000..c3786f997 --- /dev/null +++ b/sbt/src/sbt-test/dependency-management/chainresolver/test @@ -0,0 +1,3 @@ +> realCommonsIoClient/update + +> fakeCommonsIoClient/update From b705d4e99801b4455f1c45aac59a2661f8c7e682 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 00:41:23 -0500 Subject: [PATCH 0475/1030] Update warning message a bit. --- ivy/src/main/scala/sbt/CompatibilityWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala index 7c7a7c1fb..10ef1685d 100644 --- a/ivy/src/main/scala/sbt/CompatibilityWarning.scala +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -16,7 +16,7 @@ private[sbt] object CompatibilityWarning { directDependencies foreach { m => if (!m.isTransitive) { log.warn( - s"""Found intransitive dependency ($m), but maven does not support intransitive dependencies. + s"""Found intransitive dependency ($m), but Maven repositories do not support intransitive dependencies. | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. """.stripMargin) } else () From eef906e09a1021c3d15cdb492ed31c390e38d251 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 01:22:27 -0500 Subject: [PATCH 0476/1030] Fixes #1827. Adds withInterProjectFirst to update option. withInterProjectFirst when set to true will prioritize inter-project resolver over all other resolver and Ivy cache. This aimed to workaround the fact that on Maven Test configuration is considered private, and thus project dependency with `test->test` configuration may not under some condition. The condition is when someone resolves `x:y:1.0` and you have a subproject named and versioned exactly that, and some other subproject tries to depend on it. This happens when the project does not change the version number on the Github. --- .../ivyint/SbtChainResolver.scala | 106 ++++++++++-------- .../sbt/librarymanagement/UpdateOptions.scala | 9 ++ 2 files changed, 66 insertions(+), 49 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 031998f36..c325d4af3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -115,6 +115,7 @@ private[sbt] case class SbtChainResolver( else resolvedOrCached // Cast resolvers to something useful. TODO - we dropping anything here? val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + val interProjResolver = resolvers find { x => x.getName == ProjectResolver.InterProject } // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything @@ -122,7 +123,7 @@ private[sbt] case class SbtChainResolver( // RETURNS: Left -> Error // Right -> Some(resolved module) // Found in this resolver, can use this result. // Right -> None // Do not use this resolver - val results = resolvers map { x => + lazy val results = resolvers map { x => // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. if (isReturnFirst && temp.isDefined && !useLatest) Right(None) else { @@ -153,54 +154,61 @@ private[sbt] case class SbtChainResolver( } } } - val errors = results collect { case Left(e) => e } - val foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } - val sorted = - if (useLatest) (foundRevisions.sortBy { - case (rmr, resolver) => - Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") - // Just issue warning about issues with publication date, and fake one on it for now. - Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { - case None => - (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { - case (null, _) => - // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file - if (dd.isChanging) - Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") - 0L - case (ivf, dmd: DefaultModuleDescriptor) => - val lmd = new java.util.Date(ivf.getLastModified) - Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") - dmd.setPublicationDate(lmd) - ivf.getLastModified - case _ => - Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") - 0L - } - case Some(date) => // All other cases ok - date.getTime - } - }).reverse.headOption map { - case (rmr, resolver) => - Message.warn(s"Choosing $resolver for ${rmr.getId}") - // Now that we know the real latest revision, let's force Ivy to use it - val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) - artifactOpt match { - case None if resolver.getName == "inter-project" => // do nothing - case None if resolver.isInstanceOf[CustomMavenResolver] => - // do nothing for now.... - // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... - case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") - case Some(artifactRef) => - val systemMd = toSystem(rmr.getDescriptor) - getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, - toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) - } - rmr - } - else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + lazy val errors = results collect { case Left(e) => e } + // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. - val mrOpt: Option[ResolvedModuleRevision] = sorted orElse resolvedOrCached + val mrOpt: Option[ResolvedModuleRevision] = { + val interProj: Option[ResolvedModuleRevision] = + if (updateOptions.interProjectFirst) interProjResolver flatMap { x => Option(x.getDependency(dd, data)) } + else None + def foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } + def sorted = + if (useLatest) (foundRevisions.sortBy { + case (rmr, resolver) => + Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") + // Just issue warning about issues with publication date, and fake one on it for now. + Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { + case None => + (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { + case (null, _) => + // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file + if (dd.isChanging) + Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + 0L + case (ivf, dmd: DefaultModuleDescriptor) => + val lmd = new java.util.Date(ivf.getLastModified) + Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + dmd.setPublicationDate(lmd) + ivf.getLastModified + case _ => + Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + 0L + } + case Some(date) => // All other cases ok + date.getTime + } + }).reverse.headOption map { + case (rmr, resolver) => + Message.warn(s"Choosing $resolver for ${rmr.getId}") + // Now that we know the real latest revision, let's force Ivy to use it + val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) + artifactOpt match { + case None if resolver.getName == "inter-project" => // do nothing + case None if resolver.isInstanceOf[CustomMavenResolver] => + // do nothing for now.... + // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... + case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") + case Some(artifactRef) => + val systemMd = toSystem(rmr.getDescriptor) + getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, + toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) + } + rmr + } + else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + + interProj orElse sorted orElse resolvedOrCached + } mrOpt match { case None if errors.size == 1 => errors.head match { @@ -305,4 +313,4 @@ private[sbt] case class SbtChainResolver( oldLatest case _ => None } -} \ No newline at end of file +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index be2ad412f..8b70c3971 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -15,6 +15,8 @@ import sbt.util.Logger final class UpdateOptions private[sbt] ( // If set to CircularDependencyLevel.Error, halt the dependency resolution. val circularDependencyLevel: CircularDependencyLevel, + // If set to true, prioritize inter-project resolver + val interProjectFirst: Boolean, // If set to true, check all resolvers for snapshots. val latestSnapshots: Boolean, // If set to true, use consolidated resolution. @@ -26,6 +28,8 @@ final class UpdateOptions private[sbt] ( ) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) + def withInterProjectFirst(interProjectFirst: Boolean): UpdateOptions = + copy(interProjectFirst = interProjectFirst) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) @deprecated("Use withCachedResolution instead.", "0.13.7") @@ -45,6 +49,7 @@ final class UpdateOptions private[sbt] ( private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, + interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, @@ -52,6 +57,7 @@ final class UpdateOptions private[sbt] ( ): UpdateOptions = new UpdateOptions( circularDependencyLevel, + interProjectFirst, latestSnapshots, consolidatedResolution, cachedResolution, @@ -61,6 +67,7 @@ final class UpdateOptions private[sbt] ( override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && + this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && this.resolverConverter == o.resolverConverter @@ -71,6 +78,7 @@ final class UpdateOptions private[sbt] ( { var hash = 1 hash = hash * 31 + this.circularDependencyLevel.## + hash = hash * 31 + this.interProjectFirst.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## hash = hash * 31 + this.resolverConverter.## @@ -84,6 +92,7 @@ object UpdateOptions { def apply(): UpdateOptions = new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, + interProjectFirst = true, latestSnapshots = false, consolidatedResolution = false, cachedResolution = false, From 54fa9dd4169baf9c463a9b90614c424160234ee3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 31 Dec 2015 22:36:04 -0500 Subject: [PATCH 0477/1030] Improve warning message --- ivy/src/main/scala/sbt/CompatibilityWarning.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/ivy/src/main/scala/sbt/CompatibilityWarning.scala index 10ef1685d..ead6b517b 100644 --- a/ivy/src/main/scala/sbt/CompatibilityWarning.scala +++ b/ivy/src/main/scala/sbt/CompatibilityWarning.scala @@ -16,8 +16,9 @@ private[sbt] object CompatibilityWarning { directDependencies foreach { m => if (!m.isTransitive) { log.warn( - s"""Found intransitive dependency ($m), but Maven repositories do not support intransitive dependencies. - | Use exclusions instead so transitive dependencies will be correctly excluded in dependent projects. + s"""Found intransitive dependency ($m) while publishMavenStyle is true, but Maven repositories + | do not support intransitive dependencies. Use exclusions instead so transitive dependencies + | will be correctly excluded in dependent projects. """.stripMargin) } else () } From 409d1a7f4e26f67d918ab92fac3a56813314bf4f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 14 Dec 2015 16:59:55 -0500 Subject: [PATCH 0478/1030] Fixes #1514. Enable latest SNAPSHOT option by default to check all resolvers to find the latest snapshot artifacts. This behavior did not work well with Maven repositories where sbt was failing to calculate the correct publication dates. Now that #2075 fixes the Maven integration issue we should enable this flag back again. The build user can opt out by: updateOptions := updateOptions.value.withLatestSnapshots(false) --- .../src/main/scala/sbt/librarymanagement/UpdateOptions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 8b70c3971..ed63b4c48 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -93,7 +93,7 @@ object UpdateOptions { new UpdateOptions( circularDependencyLevel = CircularDependencyLevel.Warn, interProjectFirst = true, - latestSnapshots = false, + latestSnapshots = true, consolidatedResolution = false, cachedResolution = false, resolverConverter = PartialFunction.empty From 33ae4440411f10fbb1f1a5a46b5bf55392f30ed0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 30 Dec 2015 04:07:39 -0500 Subject: [PATCH 0479/1030] Bump up ivy to 2.3.0-sbt-39ece6f17e1af62c2e89a9d88b59c0c3aad56145 Ref sbt/ivy#21 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9c78cc053..10466124d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,7 +13,7 @@ object Dependencies { lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" - lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-927bc9ded7f8fba63297cddd0d5a3d01d6ad5d8d" + lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-39ece6f17e1af62c2e89a9d88b59c0c3aad56145" lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } From bd792c3bb829094bb6d83e311effd2f479513bba Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 30 Dec 2015 04:46:20 -0500 Subject: [PATCH 0480/1030] Fixes #1616. Fixes the "latest snapshot" chain resolver The "latest snapshot" chain resolver was assuming that there's at least one artifact per module. I think that was the root cause of #1616. --- .../librarymanagement/ivyint/SbtChainResolver.scala | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index c325d4af3..e621ac7a0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -193,15 +193,11 @@ private[sbt] case class SbtChainResolver( // Now that we know the real latest revision, let's force Ivy to use it val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) artifactOpt match { - case None if resolver.getName == "inter-project" => // do nothing - case None if resolver.isInstanceOf[CustomMavenResolver] => - // do nothing for now.... - // We want to see if the maven caching is sufficient and we do not need to duplicate within the ivy cache... - case None => throw new RuntimeException(s"\t${resolver.getName}: no ivy file nor artifact found for $rmr") case Some(artifactRef) => val systemMd = toSystem(rmr.getDescriptor) getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) + case None => // do nothing. There are modules without artifacts } rmr } From 660d66ef1f9e83b296aadf7f2ec073476ddae1d6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 30 Dec 2015 07:21:07 -0500 Subject: [PATCH 0481/1030] Bump up ivy to 2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 10466124d..4a46dfaaf 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,7 +13,7 @@ object Dependencies { lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" - lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-39ece6f17e1af62c2e89a9d88b59c0c3aad56145" + lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } From d693d0cde9207c0af82edc0f353dbc729df92e3c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 17 Jan 2016 19:58:57 +0000 Subject: [PATCH 0482/1030] Move CompatibilityWarning to sbt.internal.librarymanagement --- .../sbt/internal/librarymanagement}/CompatibilityWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename {ivy/src/main/scala/sbt => librarymanagement/src/main/scala/sbt/internal/librarymanagement}/CompatibilityWarning.scala (96%) diff --git a/ivy/src/main/scala/sbt/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala similarity index 96% rename from ivy/src/main/scala/sbt/CompatibilityWarning.scala rename to librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index ead6b517b..aa290c2a2 100644 --- a/ivy/src/main/scala/sbt/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -1,4 +1,4 @@ -package sbt +package sbt.internal.librarymanagement private[sbt] object CompatibilityWarning { def apply(module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { From 0a8402a8a9a8b8f64d85f6d26f4ef0a39631cd5e Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 17 Jan 2016 21:12:27 +0000 Subject: [PATCH 0483/1030] Add missing imports --- .../sbt/internal/librarymanagement/CompatibilityWarning.scala | 3 +++ 1 file changed, 3 insertions(+) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index aa290c2a2..985b4bfbd 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -1,5 +1,8 @@ package sbt.internal.librarymanagement +import sbt.librarymanagement._ +import sbt.util.Logger + private[sbt] object CompatibilityWarning { def apply(module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { if (mavenStyle) { From ffcec2fa35ae7990546e02e7840b75e1359aae74 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 17 Jan 2016 21:12:36 +0000 Subject: [PATCH 0484/1030] Commit auto-formatted code --- .../internal/librarymanagement/CompatibilityWarning.scala | 3 ++- .../src/main/scala/sbt/librarymanagement/IvyScala.scala | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index 985b4bfbd..9bd00be7c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -22,7 +22,8 @@ private[sbt] object CompatibilityWarning { s"""Found intransitive dependency ($m) while publishMavenStyle is true, but Maven repositories | do not support intransitive dependencies. Use exclusions instead so transitive dependencies | will be correctly excluded in dependent projects. - """.stripMargin) + """.stripMargin + ) } else () } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index b12f5d27e..e5808eef9 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -28,8 +28,10 @@ object ScalaArtifacts { Seq(ModuleID(org, DottyIDPrefix, version, Some(Configurations.ScalaTool.name + "->compile"), crossVersion = CrossVersion.binary)) else - Seq(scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version)) + Seq( + scalaToolDependency(org, ScalaArtifacts.CompilerID, version), + scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + ) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) From 77a1e5d871425b3b0c1174336b21f95e50806c87 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 16 Jan 2016 15:15:00 +0000 Subject: [PATCH 0485/1030] Target Oracle JDK 7 & 8 in Travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8dc242caf..bb23581e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,3 +2,6 @@ language: scala scala: - 2.10.6 - 2.11.7 +jdk: + - oraclejdk8 + - oraclejdk7 From 8f88a359223fa079dc7edf35721868bd9d320855 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Jan 2016 01:39:00 -0500 Subject: [PATCH 0486/1030] Adds CompatibilityWarningOptions. Fixes #2347 This addresses 0.13.10 regression, which currently warns users about Maven incompatibility on a private configuration. This adds a config class so the build user can control the level of the warning as well as the target configuration to be monitored. By default, we are only going to look at `Compile` and `Runtime`. --- .../CompatibilityWarning.scala | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index 9bd00be7c..c039109d3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -1,23 +1,48 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ -import sbt.util.Logger +import sbt.util.{ Level, Logger } + +import Configurations._ + +final class CompatibilityWarningOptions private[sbt] ( + val configurations: Seq[Configuration], + val level: Level.Value +) + +object CompatibilityWarningOptions { + def default: CompatibilityWarningOptions = + apply(configurations = List(Compile, Runtime), level = Level.Warn) + def apply( + configurations: List[Configuration], + level: Level.Value + ): CompatibilityWarningOptions = + new CompatibilityWarningOptions( + configurations = configurations, + level = level + ) +} private[sbt] object CompatibilityWarning { - def apply(module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { + def run(config: CompatibilityWarningOptions, module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { if (mavenStyle) { - processIntransitive(module, log) + processIntransitive(config, module, log) } } - - def processIntransitive(module: IvySbt#Module, log: Logger): Unit = { + def processIntransitive(config: CompatibilityWarningOptions, module: IvySbt#Module, log: Logger): Unit = { + val monitoredConfigsStr: Set[String] = (config.configurations map { _.name }).toSet val directDependencies: Seq[ModuleID] = module.moduleSettings match { case x: InlineConfiguration => x.dependencies case x: InlineConfigurationWithExcludes => x.dependencies case _ => Seq() } + def inMonitoredConfigs(configOpt: Option[String]): Boolean = + configOpt match { + case Some(c) => (c.split(",").toSet intersect monitoredConfigsStr).nonEmpty + case None => monitoredConfigsStr contains "compile" + } directDependencies foreach { m => - if (!m.isTransitive) { + if (!m.isTransitive && inMonitoredConfigs(m.configurations)) { log.warn( s"""Found intransitive dependency ($m) while publishMavenStyle is true, but Maven repositories | do not support intransitive dependencies. Use exclusions instead so transitive dependencies From cf0fef5a85e54200c699267d00ce0ece5f179aba Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 13 Jan 2016 12:56:28 -0500 Subject: [PATCH 0487/1030] Inter-project dependency tracking. Fixes #2266 Adds `trackInternalDependencies` and `exportToInternal` settings. These can be used to control whether to trigger compilation of a dependent subprojects when you call `compile`. Both keys will take one of three values: `TrackLevel.NoTracking`, `TrackLevel.TrackIfMissing`, and `TrackLevel.TrackAlways`. By default they are both set to `TrackLevel.TrackAlways`. When `trackInternalDependencies` is set to `TrackLevel.TrackIfMissing`, sbt will no longer try to compile internal (inter-project) dependencies automatically, unless there are no `*.class` files (or JAR file when `exportJars` is `true`) in the output directory. When the setting is set to `TrackLevel.NoTracking`, the compilation of internal dependencies will be skipped. Note that the classpath will still be appended, and dependency graph will still show them as dependencies. The motivation is to save the I/O overhead of checking for the changes on a build with many subprojects during development. Here's how to set all subprojects to `TrackIfMissing`. lazy val root = (project in file(".")). aggregate(....). settings( inThisBuild(Seq( trackInternalDependencies := TrackLevel.TrackIfMissing, exportJars := true )) ) The `exportToInternal` setting allows the dependee subprojects to opt out of the internal tracking, which might be useful if you want to track most subprojects except for a few. The intersection of the `trackInternalDependencies` and `exportToInternal` settings will be used to determine the actual track level. Here's an example to opt-out one project: lazy val dontTrackMe = (project in file("dontTrackMe")). settings( exportToInternal := TrackLevel.NoTracking ) --- .../sbt/librarymanagement/TrackLevel.scala | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala new file mode 100644 index 000000000..e92b37d68 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala @@ -0,0 +1,33 @@ +package sbt.librarymanagement + +/** + * An enumeration defining the tracking of dependencies. A level includes all of the levels + * with id larger than its own id. For example, Warn (id=3) includes Error (id=4). + */ +object TrackLevel { + case object NoTracking extends TrackLevel { + override def id: Int = 0 + } + case object TrackIfMissing extends TrackLevel { + override def id: Int = 1 + } + case object TrackAlways extends TrackLevel { + override def id: Int = 10 + } + + private[sbt] def apply(x: Int): TrackLevel = + x match { + case 0 => NoTracking + case 1 => TrackIfMissing + case 10 => TrackAlways + } + + def intersection(a: TrackLevel, b: TrackLevel): TrackLevel = + if (a.id < b.id) a + else b + def intersectionAll(vs: List[TrackLevel]): TrackLevel = vs reduceLeft intersection +} + +sealed trait TrackLevel { + def id: Int +} From 565acc4e2aae5147a1d86ce754b4e82e66ced44d Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 28 Nov 2013 13:17:17 +0000 Subject: [PATCH 0488/1030] Get rid of sources/docs configurations --- .../sbt/librarymanagement/Artifact.scala | 49 ++++++++++++------- .../sbt/librarymanagement/Configuration.scala | 4 +- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 2d174f035..d45dd395a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -8,10 +8,10 @@ import java.net.URL import sbt.serialization._ final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String, String]) { - def extra(attributes: (String, String)*) = Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes ++ ModuleID.checkE(attributes)) + def extra(attributes: (String, String)*) = copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) } -import Configurations.{ config, Docs, Optional, Pom, Sources, Test } +import Configurations.{ config, Optional, Pom, Test } object Artifact { def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) @@ -30,12 +30,23 @@ object Artifact { def javadoc(name: String) = classified(name, DocClassifier) def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) - val DocClassifier = "javadoc" - val SourceClassifier = "sources" - val DocType = "doc" - val SourceType = "src" - val PomType = "pom" - val TestsClassifier = "tests" + // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs + val DefaultSourceTypes = Set("src", "source", "sources") + val DefaultDocTypes = Set("doc", "docs", "javadoc", "javadocs") + + val DocClassifier = "javadoc" + val SourceClassifier = "sources" + + val TestsClassifier = "tests" + // Artifact types used when: + // * artifacts are explicitly created for Maven dependency resolution (see updateClassifiers) + // * declaring artifacts as part of publishing Ivy files. + val DocType = "doc" + val SourceType = "src" + val PomType = "pom" + + assert (DefaultDocTypes contains DocType) + assert (DefaultSourceTypes contains SourceType) def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = @@ -62,18 +73,18 @@ object Artifact { base + "-" + module.revision + classifierStr + "." + artifact.extension } - val classifierConfMap = Map(SourceClassifier -> Sources, DocClassifier -> Docs) - val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - def classifierConf(classifier: String): Configuration = - if (classifier.startsWith(TestsClassifier)) - Test - else - classifierConfMap.getOrElse(classifier, Optional) - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) - def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) + val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) + // TODO this function shouldn't exist. Configuration should not just be conjured up like that. + def classifierConf(classifier: String): Configuration = + if(classifier.startsWith(TestsClassifier)) + Test + else + Optional + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) + def classified(name: String, classifier: String): Artifact = + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) - private val optStringPickler = implicitly[Pickler[Option[String]]] + private val optStringPickler = implicitly[Pickler[Option[String]]] private val optStringUnpickler = implicitly[Unpickler[Option[String]]] private val vectorConfigurationPickler = implicitly[Pickler[Vector[Configuration]]] private val vectorConfigurationUnpickler = implicitly[Unpickler[Vector[Configuration]]] diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index 50c432682..f860d4abc 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -10,7 +10,7 @@ object Configurations { def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Sources, Docs, Pom) + def auxiliary: Seq[Configuration] = Seq(Pom) def names(cs: Seq[Configuration]) = cs.map(_.name) lazy val RuntimeInternal = optionalInternal(Runtime) @@ -34,10 +34,8 @@ object Configurations { lazy val Compile = config("compile") lazy val IntegrationTest = config("it") extend (Runtime) lazy val Provided = config("provided") - lazy val Docs = config("docs") lazy val Runtime = config("runtime") extend (Compile) lazy val Test = config("test") extend (Runtime) - lazy val Sources = config("sources") lazy val System = config("system") lazy val Optional = config("optional") lazy val Pom = config("pom") From 83fbb212d9c1055f5bdd39002aca58c58b738f27 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 09:33:21 +0000 Subject: [PATCH 0489/1030] Add include rules to ModuleID --- .../main/scala/sbt/internal/librarymanagement/Ivy.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index c39c30565..467e9d137 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -140,7 +140,8 @@ final class IvySbt(val configuration: IvyConfiguration) { /** * Cleans cached resolution cache. - * @param md - module descriptor of the original Ivy graph. + * + * @param md - module descriptor of the original Ivy graph. */ private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = withIvy(log) { i => @@ -620,6 +621,12 @@ private[sbt] object IvySbt { dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) } } + for (incls <- dependency.inclusions) { + for (conf <- dependencyDescriptor.getModuleConfigurations) { + dependencyDescriptor.addIncludeRule(conf, IvyScala.includeRule(incls.organization, incls.name, incls.configurations, incls.artifact)) + } + } + dependencyDescriptor } def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = From c7dfbbf7051e919413b275fa005235df442d0451 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 09:37:53 +0000 Subject: [PATCH 0490/1030] Add ArtifactTypeFilter --- .../sbt/librarymanagement/IvyInterface.scala | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index b582a51ed..62842755e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -8,6 +8,8 @@ import java.net.{ URI, URL } import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } import org.apache.ivy.util.url.CredentialsStore +import org.apache.ivy.core.module.descriptor +import org.apache.ivy.util.filter.{Filter => IvyFilter} import sbt.serialization._ /** Additional information about a project module */ @@ -31,6 +33,25 @@ object ExclusionRule { implicit val pickler: Pickler[ExclusionRule] with Unpickler[ExclusionRule] = PicklerUnpickler.generate[ExclusionRule] } +/** Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) + * @param types represents the artifact types that we should try to resolve for (as in the allowed values of + * `artifact[type]` from a dependency `` section). One can use this to filter + * source / doc artifacts. + * @param inverted whether to invert the types filter (i.e. allow only types NOT in the set) */ +case class ArtifactTypeFilter(types: Set[String], inverted: Boolean) { + def invert = copy(inverted = !inverted) + def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted +} + +object ArtifactTypeFilter { + def allow(types: Set[String]) = ArtifactTypeFilter(types, false) + def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) + + implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { + override def accept(o: Object): Boolean = Option(o) exists { case a: descriptor.Artifact => f.apply(a) } + } +} + final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) object ModuleConfiguration { def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) From 00bcd222e678a77c8169fd01a7ca8adf8e83ff29 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 09:38:22 +0000 Subject: [PATCH 0491/1030] ExclusionRule -> InclExclRule --- .../sbt/librarymanagement/IvyInterface.scala | 15 +++++++++++---- .../scala/sbt/librarymanagement/ModuleID.scala | 4 ++-- .../scala/sbt/librarymanagement/package.scala | 9 +++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/package.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 62842755e..ed99f6bd1 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -27,10 +27,17 @@ final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Opti final case class Developer(id: String, name: String, email: String, url: URL) -/** Rule to exclude unwanted dependencies pulled in transitively by a module. */ -final case class ExclusionRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) -object ExclusionRule { - implicit val pickler: Pickler[ExclusionRule] with Unpickler[ExclusionRule] = PicklerUnpickler.generate[ExclusionRule] +/** Rule to either: + *
    + *
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • + *
  • include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
  • + *
+ * Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases. */ +final case class InclExclRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) +object InclExclRule { + def everything = InclExclRule("*", "*", "*", Nil) + + implicit val pickler: Pickler[InclExclRule] with Unpickler[InclExclRule] = PicklerUnpickler.generate[InclExclRule] } /** Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 46b63ce39..d2071780c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -70,10 +70,10 @@ final case class ModuleID(organization: String, name: String, revision: String, * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify * both the exact organization and name and nothing else will be included in a pom.xml. */ - def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + def excludeAll(rules: InclExclRule*) = copy(exclusions = this.exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = excludeAll(ExclusionRule(org, name)) + def exclude(org: String, name: String) = excludeAll(InclExclRule(org, name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala new file mode 100644 index 000000000..24e6eee19 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala @@ -0,0 +1,9 @@ +package sbt + +package object librarymanagement { + type ExclusionRule = InclExclRule + val ExclusionRule = InclExclRule + + type InclusionRule = InclExclRule + val InclusionRule = InclExclRule +} From 789ebee0f1c2d63d3f6e8b17913d36acf1a93a5a Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 09:48:46 +0000 Subject: [PATCH 0492/1030] ModuleID + inclusions --- .../scala/sbt/librarymanagement/IvyScala.scala | 15 +++++++++++++-- .../scala/sbt/librarymanagement/ModuleID.scala | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index e5808eef9..a9b5f54e4 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -6,8 +6,7 @@ package sbt.librarymanagement import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.core.module.descriptor.{ DefaultExcludeRule, ExcludeRule } -import org.apache.ivy.core.module.descriptor.{ DependencyDescriptor, DefaultModuleDescriptor, ModuleDescriptor, OverrideDependencyDescriptorMediator } +import org.apache.ivy.core.module.descriptor._ import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher import sbt.util.Logger @@ -125,4 +124,16 @@ private[sbt] object IvyScala { configurationNames.foreach(rule.addConfiguration) rule } + + /** + * Creates an IncludeRule that includes artifacts with the given module organization and name for + * the given configurations. + */ + private[sbt] def includeRule(organization: String, name: String, configurationNames: Iterable[String], includeTypePattern: String): IncludeRule = + { + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", includeTypePattern, "*") + val rule = new DefaultIncludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index d2071780c..3e2948394 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -8,7 +8,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import sbt.serialization._ -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, inclusions: Seq[InclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { override def toString: String = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + From 9db3e86fd94f9893faf31add53cfe8364a9a09db Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 10:11:27 +0000 Subject: [PATCH 0493/1030] [1/2] Add {source,doc}ArtifactTypes settings, use them in update* tasks in conjunction with ArtifactTypeFilter --- .../librarymanagement/IvyActions.scala | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 8d646ee65..3bb0cbfc7 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -29,21 +29,27 @@ final class PublishConfiguration(val ivyFile: Option[File], val resolverName: St this(ivyFile, resolverName, artifacts, checksums, logging, false) } -final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value) { +final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value, val artifactFilter: ArtifactTypeFilter) { + @deprecated("You should use the constructor that provides an artifactFilter", "1.0.x") + def this(retrieve: Option[RetrieveConfiguration], missingOk: Boolean, logging: UpdateLogging.Value) { + this(retrieve, missingOk, logging, ArtifactTypeFilter.forbid(Set("src", "doc"))) // allow everything but "src", "doc" by default + } + private[sbt] def copy( retrieve: Option[RetrieveConfiguration] = this.retrieve, missingOk: Boolean = this.missingOk, - logging: UpdateLogging.Value = this.logging + logging: UpdateLogging.Value = this.logging, + artifactFilter: ArtifactTypeFilter = this.artifactFilter ): UpdateConfiguration = - new UpdateConfiguration(retrieve, missingOk, logging) + new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter) } final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean, val configurationsToRetrieve: Option[Set[Configuration]]) { def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) def this(retrieveDirectory: File, outputPattern: String, sync: Boolean) = this(retrieveDirectory, outputPattern, sync, None) } final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) -// exclude is a map on a restricted ModuleID -final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala]) +/** @param exclude is a map from ModuleID to classifiers that were previously tried and failed, so should now be excluded */ +final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], sourceArtifactTypes: Set[String], docArtifactTypes: Set[String]) final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) final class UnresolvedWarningConfiguration private[sbt] ( @@ -180,6 +186,7 @@ object IvyActions { val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(md) resolveOptions.setResolveId(resolveId) + resolveOptions.setArtifactFilter(configuration.artifactFilter) resolveOptions.setLog(ivyLogLevel(configuration.logging)) x.customResolve(md, configuration.missingOk, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { case Left(x) => @@ -194,7 +201,7 @@ object IvyActions { case (ivy, md, default) => val iw = IvySbt.inconsistentDuplicateWarning(md) iw foreach { log.warn(_) } - val (report, err) = resolve(configuration.logging)(ivy, md, default) + val (report, err) = resolve(configuration.logging)(ivy, md, default, configuration.artifactFilter) err match { case Some(x) if !configuration.missingOk => Left(UnresolvedWarning(x, uwconfig)) @@ -298,11 +305,13 @@ object IvyActions { private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None) - private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = + + private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(module) resolveOptions.setResolveId(resolveId) + resolveOptions.setArtifactFilter(filter) resolveOptions.setLog(ivyLogLevel(logging)) ResolutionCache.cleanModule(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) val resolveReport = ivy.resolve(module, resolveOptions) From 055859ea9aab298cd39a7fd768d63e095886a314 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Fri, 29 Nov 2013 10:17:13 +0000 Subject: [PATCH 0494/1030] [2/2] updateClassifiers to 1) filter artifacts by type 2) ALSO retrieve artifacts defined in Ivy publications --- .../librarymanagement/IvyActions.scala | 50 +++++++++++++++++-- 1 file changed, 45 insertions(+), 5 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 3bb0cbfc7..8d43601fe 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -250,7 +250,15 @@ object IvyActions { def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) - // artifacts can be obtained from calling toSeq on UpdateReport + /** + * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This + * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy + * that sbt generates for them either.
+ * Artifacts can be obtained from calling toSeq on UpdateReport.
+ * In addition, retrieves specific Ivy artifacts if they have one of the requested `config.configuration.types`. + * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to + * "classified" artifacts (sources and javadocs). + */ private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], artifacts: Vector[(String, ModuleID, Artifact, File)], @@ -259,14 +267,27 @@ object IvyActions { import config.{ configuration => c, module => mod, _ } import mod.{ configurations => confs, _ } assert(classifiers.nonEmpty, "classifiers cannot be empty") + assert(c.artifactFilter.types.nonEmpty, "UpdateConfiguration must filter on some types") val baseModules = modules map { m => restrictedCopy(m, true) } // Adding list of explicit artifacts here. val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) - val upConf = new UpdateConfiguration(c.retrieve, true, c.logging) + // c.copy ensures c.types is preserved too + val upConf = c.copy(missingOk = true) updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { - case Right(r) => r + case Right(r) => + // The artifacts that came from Ivy don't have their classifier set, let's set it according to + // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They + val typeClassifierMap: Map[String, String] = + ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) + :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap + r.substitute { (conf, mid, artFileSeq) => + artFileSeq map { case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.copy(classifier = art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + } + } case Left(w) => throw w.resolveException } @@ -282,7 +303,7 @@ object IvyActions { { val arts = (artifacts collect { case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art }).distinct if (arts.isEmpty) None - else Some(m.copy(isTransitive = false, explicitArtifacts = arts)) + else Some(intransitiveModuleWithExplicitArts(m, arts)) } def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) explicitArtifacts orElse hardcodedArtifacts @@ -291,8 +312,27 @@ object IvyActions { { val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) val included = classifiers filterNot excluded - if (included.isEmpty) None else Some(m.copy(isTransitive = false, explicitArtifacts = classifiedArtifacts(m.name, included))) + if (included.isEmpty) None else { + Some(intransitiveModuleWithExplicitArts(module = m, arts = classifiedArtifacts(m.name, included))) + } } + + /** + * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, + * [[org.apache.ivy.core.resolve.IvyNode#getArtifacts]] (in Ivy 2.3.0-rc1) will not merge in the descriptor's + * artifacts and will only keep the explicitArtifacts. + *
+ * Look for the comment saying {{{ + * // and now we filter according to include rules + * }}} + * in `IvyNode`, which iterates on `includes`, which will ordinarily be empty because higher up, in {{{ + * addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf)); + * }}} + * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. + */ + private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Seq[Artifact]): ModuleID = + module.copy(isTransitive = false, explicitArtifacts = arts, inclusions = InclExclRule.everything :: Nil) + def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = From 55d13bd8cd30f1d9b772b7a896b7a1193e29e828 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 4 Dec 2013 13:29:35 +0000 Subject: [PATCH 0495/1030] Fix artifact, deprecate stuff --- .../main/scala/sbt/librarymanagement/Artifact.scala | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index d45dd395a..b5b209bcb 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -40,7 +40,7 @@ object Artifact { val TestsClassifier = "tests" // Artifact types used when: // * artifacts are explicitly created for Maven dependency resolution (see updateClassifiers) - // * declaring artifacts as part of publishing Ivy files. + // * declaring artifacts as part of creating Ivy files. val DocType = "doc" val SourceType = "src" val PomType = "pom" @@ -74,15 +74,19 @@ object Artifact { } val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - // TODO this function shouldn't exist. Configuration should not just be conjured up like that. + @deprecated("Configuration should not be decided from the classifier.", "1.0") def classifierConf(classifier: String): Configuration = if(classifier.startsWith(TestsClassifier)) Test else Optional def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) + + /** Create a classified explicit artifact, to be used when trying to resolve sources|javadocs from Maven. This is + * necessary because those artifacts are not published in the Ivy generated from the Pom of the module in question. + * The artifact is created under the default configuration. */ def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), classifierConf(classifier) :: Nil, None) + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Nil, None) private val optStringPickler = implicitly[Pickler[Option[String]]] private val optStringUnpickler = implicitly[Unpickler[Option[String]]] From dc81a1813d0a4362b6a9b9786b80c928a1637930 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 5 Dec 2013 18:11:12 +0000 Subject: [PATCH 0496/1030] Fix UpdateReport.substitute to not drop missing artifacts --- .../sbt/internal/librarymanagement/RichUpdateReport.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala index 61675fd2d..e4005ef21 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -45,8 +45,8 @@ final class RichUpdateReport(report: UpdateReport) { moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) modReport.copy( - artifacts = f(configuration, modReport.module, modReport.artifacts), - missingArtifacts = Nil + artifacts = newArtifacts, + missingArtifacts = modReport.missingArtifacts ) } From 31440bb1473c2ccb388d629af73456807a50df50 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Mon, 8 Feb 2016 17:12:31 +0000 Subject: [PATCH 0497/1030] Fix BaseIvySpeficiation's init of UpdateConfiguration with a sensible default ArtifactTypeFilter --- librarymanagement/src/test/scala/BaseIvySpecification.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index b0744fd3b..c6ceb1020 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -61,7 +61,7 @@ trait BaseIvySpecification extends UnitSpec { def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) - val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full) + val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } From 0d4336bbaa8e870a62d86ece49e5136e4b39c330 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Mon, 8 Feb 2016 17:14:04 +0000 Subject: [PATCH 0498/1030] Apply style fixes --- .../sbt/internal/librarymanagement/Ivy.scala | 4 +- .../librarymanagement/IvyActions.scala | 47 +++++++-------- .../sbt/librarymanagement/Artifact.scala | 58 ++++++++++--------- .../sbt/librarymanagement/IvyInterface.scala | 38 ++++++------ .../sbt/librarymanagement/IvyScala.scala | 12 ++-- 5 files changed, 83 insertions(+), 76 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 467e9d137..f6d449c4a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -140,8 +140,8 @@ final class IvySbt(val configuration: IvyConfiguration) { /** * Cleans cached resolution cache. - * - * @param md - module descriptor of the original Ivy graph. + * + * @param md - module descriptor of the original Ivy graph. */ private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = withIvy(log) { i => diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 8d43601fe..8fc1d4866 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -251,14 +251,14 @@ object IvyActions { updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) /** - * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This - * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy - * that sbt generates for them either.
- * Artifacts can be obtained from calling toSeq on UpdateReport.
- * In addition, retrieves specific Ivy artifacts if they have one of the requested `config.configuration.types`. - * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to - * "classified" artifacts (sources and javadocs). - */ + * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This + * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy + * that sbt generates for them either.
+ * Artifacts can be obtained from calling toSeq on UpdateReport.
+ * In addition, retrieves specific Ivy artifacts if they have one of the requested `config.configuration.types`. + * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to + * "classified" artifacts (sources and javadocs). + */ private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], artifacts: Vector[(String, ModuleID, Artifact, File)], @@ -283,9 +283,10 @@ object IvyActions { ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.copy(classifier = art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + artFileSeq map { + case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.copy(classifier = art.classifier orElse typeClassifierMap.get(art.`type`)) -> f } } case Left(w) => @@ -318,18 +319,18 @@ object IvyActions { } /** - * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, - * [[org.apache.ivy.core.resolve.IvyNode#getArtifacts]] (in Ivy 2.3.0-rc1) will not merge in the descriptor's - * artifacts and will only keep the explicitArtifacts. - *
- * Look for the comment saying {{{ - * // and now we filter according to include rules - * }}} - * in `IvyNode`, which iterates on `includes`, which will ordinarily be empty because higher up, in {{{ - * addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf)); - * }}} - * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. - */ + * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, + * [[org.apache.ivy.core.resolve.IvyNode#getArtifacts]] (in Ivy 2.3.0-rc1) will not merge in the descriptor's + * artifacts and will only keep the explicitArtifacts. + *
+ * Look for the comment saying {{{ + * // and now we filter according to include rules + * }}} + * in `IvyNode`, which iterates on `includes`, which will ordinarily be empty because higher up, in {{{ + * addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf)); + * }}} + * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. + */ private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Seq[Artifact]): ModuleID = module.copy(isTransitive = false, explicitArtifacts = arts, inclusions = InclExclRule.everything :: Nil) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index b5b209bcb..8bf97bc05 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -30,23 +30,23 @@ object Artifact { def javadoc(name: String) = classified(name, DocClassifier) def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) - // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs - val DefaultSourceTypes = Set("src", "source", "sources") - val DefaultDocTypes = Set("doc", "docs", "javadoc", "javadocs") + // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs + val DefaultSourceTypes = Set("src", "source", "sources") + val DefaultDocTypes = Set("doc", "docs", "javadoc", "javadocs") - val DocClassifier = "javadoc" - val SourceClassifier = "sources" + val DocClassifier = "javadoc" + val SourceClassifier = "sources" - val TestsClassifier = "tests" - // Artifact types used when: - // * artifacts are explicitly created for Maven dependency resolution (see updateClassifiers) - // * declaring artifacts as part of creating Ivy files. - val DocType = "doc" - val SourceType = "src" - val PomType = "pom" + val TestsClassifier = "tests" + // Artifact types used when: + // * artifacts are explicitly created for Maven dependency resolution (see updateClassifiers) + // * declaring artifacts as part of creating Ivy files. + val DocType = "doc" + val SourceType = "src" + val PomType = "pom" - assert (DefaultDocTypes contains DocType) - assert (DefaultSourceTypes contains SourceType) + assert(DefaultDocTypes contains DocType) + assert(DefaultSourceTypes contains SourceType) def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = @@ -73,22 +73,24 @@ object Artifact { base + "-" + module.revision + classifierStr + "." + artifact.extension } - val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) - @deprecated("Configuration should not be decided from the classifier.", "1.0") - def classifierConf(classifier: String): Configuration = - if(classifier.startsWith(TestsClassifier)) - Test - else - Optional - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) + val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) + @deprecated("Configuration should not be decided from the classifier.", "1.0") + def classifierConf(classifier: String): Configuration = + if (classifier.startsWith(TestsClassifier)) + Test + else + Optional + def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) - /** Create a classified explicit artifact, to be used when trying to resolve sources|javadocs from Maven. This is - * necessary because those artifacts are not published in the Ivy generated from the Pom of the module in question. - * The artifact is created under the default configuration. */ - def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Nil, None) + /** + * Create a classified explicit artifact, to be used when trying to resolve sources|javadocs from Maven. This is + * necessary because those artifacts are not published in the Ivy generated from the Pom of the module in question. + * The artifact is created under the default configuration. + */ + def classified(name: String, classifier: String): Artifact = + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Nil, None) - private val optStringPickler = implicitly[Pickler[Option[String]]] + private val optStringPickler = implicitly[Pickler[Option[String]]] private val optStringUnpickler = implicitly[Unpickler[Option[String]]] private val vectorConfigurationPickler = implicitly[Pickler[Vector[Configuration]]] private val vectorConfigurationUnpickler = implicitly[Unpickler[Vector[Configuration]]] diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index ed99f6bd1..964fe7447 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -9,7 +9,7 @@ import scala.xml.NodeSeq import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } import org.apache.ivy.util.url.CredentialsStore import org.apache.ivy.core.module.descriptor -import org.apache.ivy.util.filter.{Filter => IvyFilter} +import org.apache.ivy.util.filter.{ Filter => IvyFilter } import sbt.serialization._ /** Additional information about a project module */ @@ -27,12 +27,14 @@ final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Opti final case class Developer(id: String, name: String, email: String, url: URL) -/** Rule to either: - *
    - *
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • - *
  • include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
  • - *
- * Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases. */ +/** + * Rule to either: + *
    + *
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • + *
  • include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
  • + *
+ * Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases. + */ final case class InclExclRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) object InclExclRule { def everything = InclExclRule("*", "*", "*", Nil) @@ -40,23 +42,25 @@ object InclExclRule { implicit val pickler: Pickler[InclExclRule] with Unpickler[InclExclRule] = PicklerUnpickler.generate[InclExclRule] } -/** Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) - * @param types represents the artifact types that we should try to resolve for (as in the allowed values of - * `artifact[type]` from a dependency `` section). One can use this to filter - * source / doc artifacts. - * @param inverted whether to invert the types filter (i.e. allow only types NOT in the set) */ +/** + * Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) + * @param types represents the artifact types that we should try to resolve for (as in the allowed values of + * `artifact[type]` from a dependency `` section). One can use this to filter + * source / doc artifacts. + * @param inverted whether to invert the types filter (i.e. allow only types NOT in the set) + */ case class ArtifactTypeFilter(types: Set[String], inverted: Boolean) { def invert = copy(inverted = !inverted) def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted } object ArtifactTypeFilter { - def allow(types: Set[String]) = ArtifactTypeFilter(types, false) - def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) + def allow(types: Set[String]) = ArtifactTypeFilter(types, false) + def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) - implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { case a: descriptor.Artifact => f.apply(a) } - } + implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { + override def accept(o: Object): Boolean = Option(o) exists { case a: descriptor.Artifact => f.apply(a) } + } } final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index a9b5f54e4..d2df9b4cf 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -130,10 +130,10 @@ private[sbt] object IvyScala { * the given configurations. */ private[sbt] def includeRule(organization: String, name: String, configurationNames: Iterable[String], includeTypePattern: String): IncludeRule = - { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", includeTypePattern, "*") - val rule = new DefaultIncludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) - configurationNames.foreach(rule.addConfiguration) - rule - } + { + val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", includeTypePattern, "*") + val rule = new DefaultIncludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } } From fcd52ee2834cdde9eed8b9c276fb83ce2925c46b Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 10 Feb 2016 13:12:54 +0000 Subject: [PATCH 0499/1030] Expose the default UpdateConfiguration in BaseIvyConfiguration --- .../src/test/scala/BaseIvySpecification.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index c6ceb1020..260ac3517 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -58,10 +58,14 @@ trait BaseIvySpecification extends UnitSpec { new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) } + def makeUpdateConfiguration: UpdateConfiguration = { + val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) + new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) + } + def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) - val config = new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) + val config = makeUpdateConfiguration IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) } From 01030a197a53f3ebb4eca43a01c2d7a23b8ecd5f Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 10 Feb 2016 13:14:42 +0000 Subject: [PATCH 0500/1030] Add IvyRepoSpec which tests that source artifacts (in this case, with type=src, though in the same "compile" configuration) are resolved correctly when using IvyActions.updateClassifiers, and NOT resolved when using the normal IvyActions.updateEither. --- .../module-with-srcs/0.1.00/ivys/ivy.xml | 23 +++++ .../0.1.00/jars/libmodule.jar | Bin 0 -> 341 bytes .../0.1.00/srcs/libmodule-source.jar | Bin 0 -> 341 bytes .../librarymanagement/IvyRepoSpec.scala | 89 ++++++++++++++++++ 4 files changed, 112 insertions(+) create mode 100755 librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml create mode 100644 librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar create mode 100644 librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml b/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml new file mode 100755 index 000000000..ab045d5cb --- /dev/null +++ b/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml @@ -0,0 +1,23 @@ + + + + + Just a test module that publishes both a binary jar and a src jar in the 'compile' configuration. + + + + + + + + + + + + + + + + + + diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar b/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar new file mode 100644 index 0000000000000000000000000000000000000000..b21d53c7baf1086d25cdb54e4fe86d41ed542b27 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3xD)E-!GHuf8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAZm_uOz literal 0 HcmV?d00001 diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar b/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar new file mode 100644 index 0000000000000000000000000000000000000000..b21d53c7baf1086d25cdb54e4fe86d41ed542b27 GIT binary patch literal 341 zcmWIWW@Zs#;Nak3xD)E-!GHuf8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1gx0>v$BCyF#%yMkUj+BFaQAZm_uOz literal 0 HcmV?d00001 diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala new file mode 100644 index 000000000..9e15fbc01 --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -0,0 +1,89 @@ +package sbt.internal.librarymanagement + +import org.scalatest.Inside +import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.librarymanagement._ + +class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { + + val ourModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) + + def makeModuleForDepWithSources = { + // By default a module seems to only have [compile, test, runtime], yet deps automatically map to + // default->compile(default) ... so I guess we have to explicitly use e.g. "compile" + val dep = "com.test" % "module-with-srcs" % "0.1.00" % "compile" + + module( + ourModuleID, + Seq(dep), None //, UpdateOptions().withCachedResolution(true) + ) + } + + "ivyUpdate from ivy repository" should "resolve only binary artifact from module which also contains a sources artifact under the same configuration." in { + cleanIvyCache() + + val m = makeModuleForDepWithSources + + val report = ivyUpdate(m) + + import Inside._ + inside(report.configuration("compile").map(_.modules)) { + case Some(Seq(mr)) => + inside(mr.artifacts) { + case Seq((ar, _)) => + ar.`type` shouldBe "jar" + ar.extension shouldBe "jar" + } + } + } + + it should "resolve only sources artifact of an acceptable artifact type, \"src\", when calling updateClassifiers." in { + cleanIvyCache() + + val m = makeModuleForDepWithSources + + // the "default" configuration used in updateEither. + val c = makeUpdateConfiguration + + val ivyScala = m.moduleSettings.ivyScala + val srcTypes = Set("src") + val docTypes = Set("javadoc") + // These will be the default classifiers that SBT should try, in case a dependency is Maven. + // In this case though, they will be tried and should fail gracefully - only the + val attemptedClassifiers = Seq("sources", "javadoc") + + // The dep that we want to get the "classifiers" (i.e. sources / docs) for. + // We know it has only one source artifact in the "compile" configuration. + val dep = "com.test" % "module-with-srcs" % "0.1.00" % "compile" + + val clMod = { + import language.implicitConversions + implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision) + val externalModules = Seq(dep) + // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) + GetClassifiersModule(ourModuleID, externalModules, Seq(Configurations.Compile), attemptedClassifiers) + } + + val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.copy(artifactFilter = c.artifactFilter.invert), ivyScala, srcTypes, docTypes) + + val report2 = IvyActions.updateClassifiers(m.owner, gcm, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) + + import Inside._ + inside(report2.configuration("compile").map(_.modules)) { + case Some(Seq(mr)) => + inside(mr.artifacts) { + case Seq((ar, _)) => + ar.name shouldBe "libmodule-source" + ar.`type` shouldBe "src" + ar.extension shouldBe "jar" + } + } + } + + override lazy val resolvers: Seq[Resolver] = Seq(testIvy) + + lazy val testIvy = { + val repoUrl = getClass.getResource("/test-ivy-repo") + Resolver.url("Test Repo", repoUrl)(Resolver.ivyStylePatterns) + } +} From a9b215409207ecb1c94478e5d6d3ccb1ed6dfbcc Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 29 May 2014 15:20:38 +0100 Subject: [PATCH 0501/1030] ModuleID to have a branch now, that ends up in the ModuleRevisionId too. Also, add branch when converting ModuleID -> Ivy XML and include it in IvyActions.substitute. --- .../scala/sbt/internal/librarymanagement/Ivy.scala | 5 +++-- .../sbt/internal/librarymanagement/IvyActions.scala | 2 +- .../main/scala/sbt/librarymanagement/ModuleID.scala | 10 +++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index c39c30565..21c6cf6e2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -422,7 +422,7 @@ private[sbt] object IvySbt { def toID(m: ModuleID) = { import m._ - ModuleRevisionId.newInstance(organization, name, revision, javaMap(extraAttributes)) + ModuleRevisionId.newInstance(organization, name, branchName.orNull, revision, javaMap(extraAttributes)) } private def substituteCross(m: ModuleSettings): ModuleSettings = @@ -490,7 +490,8 @@ private[sbt] object IvySbt { } private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { import module._ - + val base = + branchName.fold(base) { br => base % new scala.xml.UnprefixedAttribute("branch", br, scala.xml.Null) } } private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = (elem /: extra) { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 8d646ee65..64249a6c6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -365,7 +365,7 @@ object IvyActions { { val mextra = IvySbt.javaMap(mid.extraAttributes, true) val aextra = IvySbt.extra(art, true) - IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.revision, art.name, art.`type`, art.extension, conf, mextra, aextra) + IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.branchName.orNull, mid.revision, art.name, art.`type`, art.extension, conf, null, mextra, aextra) } import UpdateLogging.{ Quiet, Full, DownloadOnly, Default } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 46b63ce39..1da5a1e0a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -8,7 +8,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import sbt.serialization._ -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled) { +final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled, branchName: Option[String] = None) { override def toString: String = organization + ":" + name + ":" + revision + (configurations match { case Some(s) => ":" + s; case None => "" }) + @@ -118,7 +118,15 @@ final case class ModuleID(organization: String, name: String, revision: String, * as when adding a dependency on an artifact with a classifier. */ def jar() = artifacts(Artifact(name)) + + /** + * Sets the Ivy branch of this module. + */ + def branch(branchName: String) = copy(branchName = Some(branchName)) + + def branch(branchName: Option[String]) = copy(branchName = branchName) } + object ModuleID { implicit val pickler: Pickler[ModuleID] with Unpickler[ModuleID] = PicklerUnpickler.generate[ModuleID] From 5ea0e0e07ae9c8a194b2ff2690dc093f8ef237ec Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 2 Jul 2014 09:24:24 +0100 Subject: [PATCH 0502/1030] [branch] as part of Resolver.localBasePattern --- .../src/main/scala/sbt/librarymanagement/Resolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 6831a2520..62227ce18 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -349,7 +349,7 @@ object Resolver { def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/" + PluginPattern + "[revision]/[type]s/[artifact](-[classifier]).[ext]" + def localBasePattern = "[organisation]/[module]/" + PluginPattern + "(/[branch])/[revision]/[type]s/[artifact](-[classifier]).[ext]" def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" private[this] def mavenLocalDir: File = { From 0fd248a19b8e34dfa71593e0ec75693c1d7232aa Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Tue, 29 Jul 2014 11:49:04 +0100 Subject: [PATCH 0503/1030] Add [branch] to pattern for sbt's resolution cache --- .../scala/sbt/internal/librarymanagement/ResolutionCache.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index 26b85b0b7..a480c8ed3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -88,5 +88,5 @@ private[sbt] object ResolutionCache { private val Name = "sbt-resolution-cache" // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions - private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "[revision]/[artifact].[ext]" + private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" } From 797fe0aa63f5e212e1e8bbc0db1d6de73c1fe91b Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 2 Apr 2015 17:14:48 +0100 Subject: [PATCH 0504/1030] Fix IvyActions.restrictedCopy to respect branch --- .../main/scala/sbt/internal/librarymanagement/IvyActions.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 64249a6c6..6f131f049 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -298,6 +298,8 @@ object IvyActions { private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None) + .branch(m.branchName) + private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions From 2324c720c4821501d0fb1391954293c06c8e485f Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Thu, 2 Apr 2015 17:21:49 +0100 Subject: [PATCH 0505/1030] Set branch onto the ModuleID when constructing a ModuleReport --- .../main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 765af3ab1..0432719d5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -154,6 +154,7 @@ object IvyRetrieve { def toModuleID(revID: ModuleRevisionId): ModuleID = ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID)) + .branch(nonEmptyString(revID.getBranch)) def toArtifact(art: IvyArtifact): Artifact = { From 1bcefc6686c69a56ea541f38196d56bf0975f226 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 14 Feb 2016 16:47:07 +0000 Subject: [PATCH 0506/1030] Bump sbt-houserules to add MiMa See sbt/sbt#2383 --- build.sbt | 12 ++++++++---- project/house.sbt | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index ed06b97a0..aff64779d 100644 --- a/build.sbt +++ b/build.sbt @@ -1,4 +1,5 @@ import Dependencies._ +import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "0.1.0" def internalPath = file("internal") @@ -15,8 +16,6 @@ def commonSettings: Seq[Setting[_]] = Seq( incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala210, scala211), resolvers += Resolver.sonatypeRepo("public"), - publishArtifact in Compile := true, - publishArtifact in Test := true, scalacOptions ++= Seq( "-encoding", "utf8", "-deprecation", @@ -31,7 +30,10 @@ def commonSettings: Seq[Setting[_]] = Seq( "-Yno-adapted-args", "-Ywarn-dead-code", "-Ywarn-numeric-widen", - "-Ywarn-value-discard") + "-Ywarn-value-discard"), + previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), + publishArtifact in Compile := true, + publishArtifact in Test := true ) lazy val root = (project in file(".")). @@ -62,5 +64,7 @@ lazy val lm = (project in file("librarymanagement")). utilTesting % Test, utilCollection, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, - name := "librarymanagement" + name := "librarymanagement", + binaryIssueFilters ++= Seq( + ) ) diff --git a/project/house.sbt b/project/house.sbt index fede298d1..555559b37 100644 --- a/project/house.sbt +++ b/project/house.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.2.1") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.1") From 9e78b1cd9c5253322ea1893bb914ceb1dd4545f4 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 10 Feb 2016 17:44:00 +0000 Subject: [PATCH 0507/1030] Get rid of InlineConfiguration --- .../CompatibilityWarning.scala | 1 - .../sbt/internal/librarymanagement/Ivy.scala | 2 -- .../librarymanagement/IvyActions.scala | 1 - .../librarymanagement/IvyConfigurations.scala | 23 ------------------- .../librarymanagement/EvictionWarning.scala | 3 +-- .../src/test/scala/BaseIvySpecification.scala | 2 +- 6 files changed, 2 insertions(+), 30 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index c039109d3..d5bb8af3d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -32,7 +32,6 @@ private[sbt] object CompatibilityWarning { def processIntransitive(config: CompatibilityWarningOptions, module: IvySbt#Module, log: Logger): Unit = { val monitoredConfigsStr: Set[String] = (config.configurations map { _.name }).toSet val directDependencies: Seq[ModuleID] = module.moduleSettings match { - case x: InlineConfiguration => x.dependencies case x: InlineConfigurationWithExcludes => x.dependencies case _ => Seq() } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 400710b67..3421f12f2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -170,7 +170,6 @@ final class IvySbt(val configuration: IvyConfiguration) { { val (baseModule, baseConfiguration) = moduleSettings match { - case ic: InlineConfiguration => configureInline(ic.withExcludes, configuration.log) case ic: InlineConfigurationWithExcludes => configureInline(ic, configuration.log) case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) @@ -435,7 +434,6 @@ private[sbt] object IvySbt { { val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { - case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) case ic: InlineConfigurationWithExcludes => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) case _ => m } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index b197b75e0..b56689b3f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -148,7 +148,6 @@ object IvyActions { } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { - case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) case i: InlineConfigurationWithExcludes => CrossVersion(i.module, i.ivyScala) case _ => None } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index adcd6a0da..d61a90f32 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -115,29 +115,6 @@ final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], valida def noScala = copy(ivyScala = None) } -// TODO: When we go sbt 1.0 we should rename InlineConfigurationWithExcludes to InlineConfiguration. -@deprecated("Use InlineConfigurationWithExcludes.", "0.13.8") -final case class InlineConfiguration(module: ModuleID, moduleInfo: ModuleInfo, dependencies: Seq[ModuleID], overrides: Set[ModuleID] = Set.empty, ivyXML: NodeSeq = NodeSeq.Empty, configurations: Seq[Configuration] = Nil, defaultConfiguration: Option[Configuration] = None, ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default) extends ModuleSettings { - def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) - def noScala = copy(ivyScala = None) - def withExcludes: InlineConfigurationWithExcludes = - InlineConfigurationWithExcludes(this.module, this.moduleInfo, this.dependencies, this.overrides, Nil, this.ivyXML, - this.configurations, this.defaultConfiguration, this.ivyScala, this.validate, this.conflictManager) - def withOverrides(overrides: Set[ModuleID]): ModuleSettings = - copy(overrides = overrides) -} -object InlineConfiguration { - @deprecated("Use InlineConfigurationWithExcludes.explicitConfigurations.", "0.13.8") - def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = - if (explicitConfigurations.isEmpty) { - defaultConfiguration match { - case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil - case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations - case _ => Nil - } - } else - explicitConfigurations -} final class InlineConfigurationWithExcludes private[sbt] ( val module: ModuleID, diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 3a05f2e72..3e74775ad 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -5,7 +5,7 @@ import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } import sbt.util.Logger import sbt.internal.util.ShowLines -import sbt.internal.librarymanagement.{ IvySbt, InlineConfiguration, InlineConfigurationWithExcludes } +import sbt.internal.librarymanagement.{ IvySbt, InlineConfigurationWithExcludes } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], @@ -167,7 +167,6 @@ object EvictionWarning { private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { val directDependencies = module.moduleSettings match { - case x: InlineConfiguration => x.dependencies case x: InlineConfigurationWithExcludes => x.dependencies case _ => Seq() } diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 260ac3517..58cfb7f1b 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -33,7 +33,7 @@ trait BaseIvySpecification extends UnitSpec { ) } - val moduleSetting: ModuleSettings = InlineConfiguration( + val moduleSetting: ModuleSettings = InlineConfigurationWithExcludes( module = moduleId, moduleInfo = ModuleInfo("foo"), dependencies = deps, From 19c7a85cd73772aead6a70439292e05703357649 Mon Sep 17 00:00:00 2001 From: Dan Sanduleac Date: Wed, 10 Feb 2016 17:46:25 +0000 Subject: [PATCH 0508/1030] Rename InlineConfigurationWithExcludes -> InlineConfiguration --- .../CompatibilityWarning.scala | 4 ++-- .../sbt/internal/librarymanagement/Ivy.scala | 12 ++++++------ .../internal/librarymanagement/IvyActions.scala | 8 ++++---- .../librarymanagement/IvyConfigurations.scala | 17 ++++++++--------- .../sbt/librarymanagement/EvictionWarning.scala | 6 +++--- .../src/test/scala/BaseIvySpecification.scala | 2 +- 6 files changed, 24 insertions(+), 25 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index d5bb8af3d..0a4f9febb 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -32,8 +32,8 @@ private[sbt] object CompatibilityWarning { def processIntransitive(config: CompatibilityWarningOptions, module: IvySbt#Module, log: Logger): Unit = { val monitoredConfigsStr: Set[String] = (config.configurations map { _.name }).toSet val directDependencies: Seq[ModuleID] = module.moduleSettings match { - case x: InlineConfigurationWithExcludes => x.dependencies - case _ => Seq() + case x: InlineConfiguration => x.dependencies + case _ => Seq() } def inMonitoredConfigs(configOpt: Option[String]): Boolean = configOpt match { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 3421f12f2..4e908fb66 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -170,15 +170,15 @@ final class IvySbt(val configuration: IvyConfiguration) { { val (baseModule, baseConfiguration) = moduleSettings match { - case ic: InlineConfigurationWithExcludes => configureInline(ic, configuration.log) - case pc: PomConfiguration => configurePom(pc) - case ifc: IvyFileConfiguration => configureIvyFile(ifc) + case ic: InlineConfiguration => configureInline(ic, configuration.log) + case pc: PomConfiguration => configurePom(pc) + case ifc: IvyFileConfiguration => configureIvyFile(ifc) } moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } - private def configureInline(ic: InlineConfigurationWithExcludes, log: Logger) = + private def configureInline(ic: InlineConfiguration, log: Logger) = { import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) @@ -434,8 +434,8 @@ private[sbt] object IvySbt { { val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { - case ic: InlineConfigurationWithExcludes => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) - case _ => m + case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) + case _ => m } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index b56689b3f..d87001653 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -148,8 +148,8 @@ object IvyActions { } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { - case i: InlineConfigurationWithExcludes => CrossVersion(i.module, i.ivyScala) - case _ => None + case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) + case _ => None } def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = { @@ -236,7 +236,7 @@ object IvyActions { import config.{ configuration => c, ivyScala, module => mod } import mod.{ id, modules => deps } val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) - val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { case Right(r) => r case Left(w) => @@ -271,7 +271,7 @@ object IvyActions { // Adding list of explicit artifacts here. val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) - val module = new ivySbt.Module(InlineConfigurationWithExcludes(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) + val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) // c.copy ensures c.types is preserved too val upConf = c.copy(missingOk = true) updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index d61a90f32..d71f959ec 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -115,8 +115,7 @@ final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], valida def noScala = copy(ivyScala = None) } - -final class InlineConfigurationWithExcludes private[sbt] ( +final class InlineConfiguration private[sbt] ( val module: ModuleID, val moduleInfo: ModuleInfo, val dependencies: Seq[ModuleID], @@ -146,16 +145,16 @@ final class InlineConfigurationWithExcludes private[sbt] ( ivyScala: Option[IvyScala] = this.ivyScala, validate: Boolean = this.validate, conflictManager: ConflictManager = this.conflictManager - ): InlineConfigurationWithExcludes = - InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, + ): InlineConfiguration = + InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, ivyScala, validate, conflictManager) override def toString: String = - s"InlineConfigurationWithExcludes($module, $moduleInfo, $dependencies, $overrides, $excludes, " + + s"InlineConfiguration($module, $moduleInfo, $dependencies, $overrides, $excludes, " + s"$ivyXML, $configurations, $defaultConfiguration, $ivyScala, $validate, $conflictManager)" override def equals(o: Any): Boolean = o match { - case o: InlineConfigurationWithExcludes => + case o: InlineConfiguration => this.module == o.module && this.moduleInfo == o.moduleInfo && this.dependencies == o.dependencies && @@ -186,7 +185,7 @@ final class InlineConfigurationWithExcludes private[sbt] ( hash } } -object InlineConfigurationWithExcludes { +object InlineConfiguration { def apply( module: ModuleID, moduleInfo: ModuleInfo, @@ -199,8 +198,8 @@ object InlineConfigurationWithExcludes { ivyScala: Option[IvyScala] = None, validate: Boolean = false, conflictManager: ConflictManager = ConflictManager.default - ): InlineConfigurationWithExcludes = - new InlineConfigurationWithExcludes(module, moduleInfo, dependencies, overrides, excludes, ivyXML, + ): InlineConfiguration = + new InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, ivyScala, validate, conflictManager) def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 3e74775ad..2c93719ec 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -5,7 +5,7 @@ import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } import sbt.util.Logger import sbt.internal.util.ShowLines -import sbt.internal.librarymanagement.{ IvySbt, InlineConfigurationWithExcludes } +import sbt.internal.librarymanagement.{ InlineConfiguration, IvySbt } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[Configuration], @@ -167,8 +167,8 @@ object EvictionWarning { private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { val directDependencies = module.moduleSettings match { - case x: InlineConfigurationWithExcludes => x.dependencies - case _ => Seq() + case x: InlineConfiguration => x.dependencies + case _ => Seq() } val pairs = reports map { detail => val evicteds = detail.modules filter { _.evicted } diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 58cfb7f1b..260ac3517 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -33,7 +33,7 @@ trait BaseIvySpecification extends UnitSpec { ) } - val moduleSetting: ModuleSettings = InlineConfigurationWithExcludes( + val moduleSetting: ModuleSettings = InlineConfiguration( module = moduleId, moduleInfo = ModuleInfo("foo"), dependencies = deps, From 195d35c07d1ffca40f2994dabb749349127f6368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joa=CC=83o=20Costa?= Date: Wed, 23 Mar 2016 11:34:33 +0000 Subject: [PATCH 0509/1030] Fix typo ("Sorrting" should be "Sorting") --- .../internal/librarymanagement/ivyint/SbtChainResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index e621ac7a0..df397f354 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -165,7 +165,7 @@ private[sbt] case class SbtChainResolver( def sorted = if (useLatest) (foundRevisions.sortBy { case (rmr, resolver) => - Message.warn(s"Sorrting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") + Message.warn(s"Sorting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") // Just issue warning about issues with publication date, and fake one on it for now. Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { case None => From 65adc869d4dd437f6f943db854a01b7dac8504e9 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Wed, 6 Apr 2016 11:52:51 +0200 Subject: [PATCH 0510/1030] Implement static launcher for sbt This is a combination of 13 commits. I squashed these 13 commits to make forward porting those changes easier, since some commit undo the changes of other commits. The PRs that include these changes can be found at https://github.com/sbt/sbt/pull/2564 and https://github.com/sbt/sbt/pull/2576. Static launcher, get bridge sources from resources This commit introduces a new "static" launcher that does not use Ivy to gather all the artifacts that it requires, but rather expect them to be immediately available. To be able to use sbt without Internet access, we add a new `ComponentCompiler` that is able to retrieve the bridge sources from the resources on classpath and compile it. Fix classpath issues in static launcher The launcher defines a top classloader that willbe used by all `ScalaInstance`s. Previously, this top classloader had a parent that contained the scala library 2.10, which prevented the correct compilation of the compiler bridge for scala 2.11. Also, we no longer need the scala-reflect JAR. Tests for FakeResolver Add `scala-reflect.jar` to JARs of `StaticScalaProvider` It turns out we need to have `scala-reflect.jar` on classpath to compile the compiler bridge for the static scala instance of the launcher. Comply to Ivy's specification in `FakeResolver` Remove `CompilerBridgeProvider` and `ResourceBridgeProvider` It turns out that we can leverage the`FakeResolver` that has been implemented to use with the static launcher, and resolve a "fake compiler bridge" using it, rather than copying it from the resources. This also has the advantage of not requiring to change the build definition. Fix NPE in FakeResolver Add compiler bridge sources to fake resolver This allows sbt to resolve the compiler bridge sources when using the static launcher Don't hardcode sbt version in static launcher Add scala compiler and library to fake resolver This allows us to still resolve them if we have no other resolver configured. Add `RepositoriesParser` This parser is used by the static launcher to parse the definition of resolvers that override the build resolvers. Support repositories override in static launcher The static launcher will now parse user-defined repositories like the usual launcher does. Specifically, the static launcher now uses the following configuration: - `sbt.boot.directory`: specifies the boot directory that sbt will use. Defaults to `~/.sbt/boot`. - `sbt.override.build.repos`: indicate whether we want to override the build resolvers. Defaults to false. - `sbt.repository.config`: specifies the path to the files that contains repositories definition. Defaults to `${sbt.boot.directory}/repositories`. Notes for sbt/sbt#2564 & sbt/sbt#2576 --- build.sbt | 2 +- .../librarymanagement/FakeResolver.scala | 194 ++++++++++++++++++ .../RepositoriesParser.scala | 91 ++++++++ .../sbt/librarymanagement/Resolver.scala | 4 + .../src/test/resources/artifact1.jar | Bin 0 -> 313 bytes .../src/test/resources/artifact2.txt | 0 .../FakeResolverSpecification.scala | 78 +++++++ .../RepositoriesParserSpecification.scala | 145 +++++++++++++ project/Dependencies.scala | 1 + 9 files changed, 514 insertions(+), 1 deletion(-) create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala create mode 100644 librarymanagement/src/test/resources/artifact1.jar create mode 100644 librarymanagement/src/test/resources/artifact2.txt create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala diff --git a/build.sbt b/build.sbt index aff64779d..a37e69249 100644 --- a/build.sbt +++ b/build.sbt @@ -62,7 +62,7 @@ lazy val lm = (project in file("librarymanagement")). utilLogging, (utilLogging % Test).classifier("tests"), sbtIO, (sbtIO % Test).classifier("tests"), utilTesting % Test, - utilCollection, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, name := "librarymanagement", binaryIssueFilters ++= Seq( diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala new file mode 100644 index 000000000..197922940 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -0,0 +1,194 @@ +package sbt + +import java.io.File +import java.net.URL + +import org.apache.ivy.core.cache.ArtifactOrigin +import org.apache.ivy.core.cache.{ DefaultRepositoryCacheManager, RepositoryCacheManager } +import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, DefaultModuleDescriptor, DependencyArtifactDescriptor, DependencyDescriptor } +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.report.ArtifactDownloadReport +import org.apache.ivy.core.report.{ DownloadReport, DownloadStatus } +import org.apache.ivy.core.report.MetadataArtifactDownloadReport +import org.apache.ivy.core.resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } +import org.apache.ivy.core.search.{ ModuleEntry, OrganisationEntry, RevisionEntry } +import org.apache.ivy.core.settings.IvySettings +import org.apache.ivy.plugins.namespace.Namespace +import org.apache.ivy.plugins.repository.url.URLResource +import org.apache.ivy.plugins.resolver.{ DependencyResolver, ResolverSettings } +import org.apache.ivy.plugins.resolver.util.ResolvedResource + +import FakeResolver._ + +/** + * A fake `DependencyResolver` that statically serves predefined artifacts. + */ +private[sbt] class FakeResolver(private var name: String, cacheDir: File, modules: ModulesMap) extends DependencyResolver { + + private object Artifact { + def unapply(art: IvyArtifact): Some[(String, String, String)] = { + val revisionID = art.getModuleRevisionId() + val organisation = revisionID.getOrganisation + val name = revisionID.getName + val revision = revisionID.getRevision + Some((organisation, name, revision)) + } + + def unapply(dd: DependencyDescriptor): Some[(String, String, String)] = { + val module = dd.getDependencyId() + val organisation = module.getOrganisation + val name = module.getName + val mrid = dd.getDependencyRevisionId() + val revision = mrid.getRevision() + Some((organisation, name, revision)) + } + } + + override def publish(artifact: IvyArtifact, src: File, overwrite: Boolean): Unit = + throw new UnsupportedOperationException("This resolver doesn't support publishing.") + + override def abortPublishTransaction(): Unit = + throw new UnsupportedOperationException("This resolver doesn't support publishing.") + + override def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean): Unit = + throw new UnsupportedOperationException("This resolver doesn't support publishing.") + + override def commitPublishTransaction(): Unit = + throw new UnsupportedOperationException("This resolver doesn't support publishing.") + + override def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = { + + val report = new ArtifactDownloadReport(artifact.getArtifact) + val path = new URL(artifact.getLocation).toURI.getPath + val localFile = new File(path) + + if (path.nonEmpty && localFile.exists) { + report.setLocalFile(localFile) + report.setDownloadStatus(DownloadStatus.SUCCESSFUL) + report.setSize(localFile.length) + } else { + report.setDownloadStatus(DownloadStatus.FAILED) + } + + report + } + + override def download(artifacts: Array[IvyArtifact], options: DownloadOptions): DownloadReport = { + val report = new DownloadReport + + artifacts foreach { art => + val artifactOrigin = locate(art) + Option(locate(art)) foreach (o => report.addArtifactReport(download(o, options))) + } + + report + } + + override def dumpSettings(): Unit = () + + override def exists(artifact: IvyArtifact): Boolean = { + val Artifact(organisation, name, revision) = artifact + modules.get((organisation, name, revision)).isDefined + } + + // This is a fake resolver and we don't have Ivy files. Ivy's spec says we can return `null` if + // we can't find the module descriptor. + override def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData): ResolvedResource = null + + override def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = { + + val Artifact(organisation, name, revision) = dd + val mrid = dd.getDependencyRevisionId() + + val artifact = modules get ((organisation, name, revision)) map { arts => + + val artifacts: Array[DependencyArtifactDescriptor] = arts.toArray map (_ artifactOf dd) + val moduleDescriptor = DefaultModuleDescriptor.newDefaultInstance(mrid, artifacts) + val defaultArtifact = arts.headOption match { + case Some(FakeArtifact(name, tpe, ext, _)) => new DefaultArtifact(mrid, new java.util.Date, name, tpe, ext) + case None => null + } + val metadataReport = new MetadataArtifactDownloadReport(defaultArtifact) + metadataReport.setDownloadStatus(DownloadStatus.SUCCESSFUL) + + new ResolvedModuleRevision(this, this, moduleDescriptor, metadataReport) + } + + artifact.orNull + + } + + override def getName(): String = name + + override val getNamespace: Namespace = { + val ns = new Namespace() + ns.setName(name) + ns + } + + override val getRepositoryCacheManager: RepositoryCacheManager = { + val cacheName = name + "-cache" + val ivySettings = new IvySettings() + val baseDir = cacheDir + new DefaultRepositoryCacheManager(cacheName, ivySettings, baseDir) + } + + override def listModules(organisation: OrganisationEntry): Array[ModuleEntry] = + modules.keys.collect { + case (o, m, _) if o == organisation.getOrganisation => + val organisationEntry = new OrganisationEntry(this, o) + new ModuleEntry(organisationEntry, m) + }.toArray + + override def listOrganisations(): Array[OrganisationEntry] = + modules.keys.map { case (o, _, _) => new OrganisationEntry(this, o) }.toArray + + override def listRevisions(module: ModuleEntry): Array[RevisionEntry] = + modules.keys.collect { + case (o, m, v) if o == module.getOrganisation && m == module.getModule => + new RevisionEntry(module, v) + }.toArray + + override def listTokenValues(tokens: Array[String], criteria: java.util.Map[_, _]): Array[java.util.Map[_, _]] = + Array.empty + + override def listTokenValues(token: String, otherTokenValues: java.util.Map[_, _]): Array[String] = + Array.empty + + override def locate(art: IvyArtifact): ArtifactOrigin = { + val Artifact(moduleOrganisation, moduleName, moduleRevision) = art + val artifact = + for { + artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) + artifact <- artifacts find (a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt) + } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) + + artifact.orNull + + } + + override def reportFailure(art: IvyArtifact): Unit = () + override def reportFailure(): Unit = () + + override def setName(name: String): Unit = { + this.name = name + getNamespace.setName(name) + } + + override def setSettings(settings: ResolverSettings): Unit = () + + private class LocalURLResource(jar: File) extends URLResource(jar.toURI.toURL) { + override def isLocal(): Boolean = true + } + +} + +private[sbt] object FakeResolver { + + type ModulesMap = Map[(String, String, String), Seq[FakeArtifact]] + + final case class FakeArtifact(name: String, tpe: String, ext: String, file: File) { + def artifactOf(dd: DependencyDescriptor): DependencyArtifactDescriptor = + new DefaultDependencyArtifactDescriptor(dd, name, tpe, ext, file.toURI.toURL, new java.util.HashMap) + } +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala new file mode 100644 index 000000000..852c6d0f4 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala @@ -0,0 +1,91 @@ +package sbt +package internal +package librarymanagement + +import java.io.File +import java.net.URL + +import scala.io.Source +import sbt.internal.util.complete.Parser +import sbt.internal.util.complete.DefaultParsers._ + +private[sbt] object RepositoriesParser { + + private case class AfterPattern(artifactPattern: Option[String], flags: Int) + final case class PredefinedRepository(override val id: xsbti.Predefined) extends xsbti.PredefinedRepository + final case class MavenRepository(override val id: String, override val url: URL) extends xsbti.MavenRepository + final case class IvyRepository(override val id: String, override val url: URL, override val ivyPattern: String, + override val artifactPattern: String, override val mavenCompatible: Boolean, override val skipConsistencyCheck: Boolean, + override val descriptorOptional: Boolean, val bootOnly: Boolean) extends xsbti.IvyRepository + + // Predefined repositories + def local: Parser[xsbti.Repository] = "local" ^^^ new PredefinedRepository(xsbti.Predefined.Local) + def mavenLocal: Parser[xsbti.Repository] = "maven-local" ^^^ new PredefinedRepository(xsbti.Predefined.MavenLocal) + def mavenCentral: Parser[xsbti.Repository] = "maven-central" ^^^ new PredefinedRepository(xsbti.Predefined.MavenCentral) + def predefinedResolver: Parser[xsbti.Repository] = local | mavenLocal | mavenCentral + + // Options + def descriptorOptional: Parser[Int] = "descriptorOptional" ^^^ Flags.descriptorOptionalFlag + def skipConsistencyCheck: Parser[Int] = "skipConsistencyCheck" ^^^ Flags.skipConsistencyCheckFlag + def bootOnly: Parser[Int] = "bootOnly" ^^^ Flags.bootOnlyFlag + def mavenCompatible: Parser[Int] = "mavenCompatible" ^^^ Flags.mavenCompatibleFlag + + def option: Parser[Int] = descriptorOptional | skipConsistencyCheck | bootOnly | mavenCompatible + def options: Parser[Int] = rep1sep(option, separator) map (_ reduce (_ | _)) + + def name: Parser[String] = ID + def separator: Parser[String] = "," ~> charClass(c => c == ' ' || c == '\t').*.string + def nonComma: Parser[String] = charClass(_ != ',').*.string + def ivyPattern: Parser[String] = nonComma + def artifactPattern: Parser[String] = nonComma + private def afterPattern: Parser[AfterPattern] = { + def onlyOptions = options map (AfterPattern(None, _)) + def both = artifactPattern ~ (separator ~> options).? map { + case ap ~ opts => AfterPattern(Some(ap), opts getOrElse 0) + } + onlyOptions | both + } + + def customResolver: Parser[xsbti.Repository] = + name ~ ": " ~ basicUri ~ (separator ~> ivyPattern).? ~ (separator ~> afterPattern).? map { + case name ~ ": " ~ uri ~ None ~ _ => + new MavenRepository(name, uri.toURL) + case name ~ ": " ~ uri ~ Some(ivy) ~ None => + new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false) + case name ~ ": " ~ uri ~ Some(ivy) ~ Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) => + new IvyRepository(name, uri.toURL, ivy, artifactPattern getOrElse ivy, mc, sc, dOpt, bo) + } + + def resolver: Parser[xsbti.Repository] = + predefinedResolver | customResolver + + def getResolver[T](in: String)(parser: Parser[T]): Option[T] = + Parser.parse(in.trim, parser).right.toOption + + def apply(lines: Iterator[String]): Seq[xsbti.Repository] = + if (lines.isEmpty) Nil + else { + if (lines.next != "[repositories]") throw new Exception("Repositories file must start with '[repositories]'") + lines.flatMap(getResolver(_)(resolver)).toList + } + def apply(str: String): Seq[xsbti.Repository] = apply(str.lines) + def apply(file: File): Seq[xsbti.Repository] = { + if (!file.exists) Nil + else apply(Source.fromFile(file).getLines) + } + + object Flags { + val descriptorOptionalFlag = 1 << 0 + val skipConsistencyCheckFlag = 1 << 1 + val bootOnlyFlag = 1 << 2 + val mavenCompatibleFlag = 1 << 3 + + def unapply(flags: Int): Some[(Boolean, Boolean, Boolean, Boolean)] = { + val dOpt = (flags & descriptorOptionalFlag) != 0 + val sc = (flags & skipConsistencyCheckFlag) != 0 + val bo = (flags & bootOnlyFlag) != 0 + val mc = (flags & mavenCompatibleFlag) != 0 + Some((dOpt, sc, bo, mc)) + } + } +} \ No newline at end of file diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 62227ce18..37224ccca 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -159,6 +159,10 @@ final case class SftpRepository(name: String, connection: SshConnection, pattern protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) } +/** A repository that conforms to sbt launcher's interface */ +private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Repository { + def rawRepository = new RawRepository(resolver) +} import Resolver._ diff --git a/librarymanagement/src/test/resources/artifact1.jar b/librarymanagement/src/test/resources/artifact1.jar new file mode 100644 index 0000000000000000000000000000000000000000..be043359eecf5f14458fb95d21a04b9bcd94a4e4 GIT binary patch literal 313 zcmWIWW@Zs#U|`^25O(bFaM{qyG!@9(0L1JJG7J%V$vKI|#i1db49rix*u$RzacKoN z10%~gt7+KnxZ_pE^%o7nR| zQ$pO>>gJ!>6SDu(oh4TmO*pbdW&uZdL0x8G(W+>*j>BRLr%#QTcH;1XLkCWsI3RKG zgaX5(*Uwd+Eq(o4J$0$tbOQ||1ID+Ej0?CXI4PWDdvdbrClAk>sN0ef=1og)HmXQR z2&f!oTryL_f-%6Gkx7mjm%k){zJq`zjUXECOIC<4(R>)-&B_K+#t4MIK>8Yp!vFwy C*jvj0 literal 0 HcmV?d00001 diff --git a/librarymanagement/src/test/resources/artifact2.txt b/librarymanagement/src/test/resources/artifact2.txt new file mode 100644 index 000000000..e69de29bb diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala new file mode 100644 index 000000000..60e9f2dd7 --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -0,0 +1,78 @@ +package sbt +package internal +package librarymanagement + +import java.io.File + +import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport } + +class FakeResolverSpecification extends BaseIvySpecification { + import FakeResolver._ + + val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT", Some("compile")) + val example = ModuleID("com.example", "example", "1.0.0", Some("compile")) + val anotherExample = ModuleID("com.example", "another-example", "1.0.0", Some("compile")) + val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3", Some("compile")) + + "The FakeResolver" should "find modules with only one artifact" in { + val m = getModule(myModule) + val report = ivyUpdate(m) + val allFiles = getAllFiles(report) + + report.allModules.length shouldBe 1 + report.configurations.length shouldBe 3 + allFiles.toSet.size shouldBe 1 + allFiles(1).getName shouldBe "artifact1-0.0.1-SNAPSHOT.jar" + } + + it should "find modules with more than one artifact" in { + val m = getModule(example) + val report = ivyUpdate(m) + val allFiles = getAllFiles(report).toSet + + report.allModules.length shouldBe 1 + report.configurations.length shouldBe 3 + allFiles.toSet.size shouldBe 2 + allFiles map (_.getName) shouldBe Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt") + } + + it should "fail gracefully when asked for unknown modules" in { + val m = getModule(nonExisting) + a[ResolveException] should be thrownBy ivyUpdate(m) + } + + it should "fail gracefully when some artifacts cannot be found" in { + val m = getModule(anotherExample) + the[ResolveException] thrownBy ivyUpdate(m) should have message "download failed: com.example#another-example;1.0.0!non-existing.txt" + } + + private def artifact1 = new File(getClass.getResource("/artifact1.jar").toURI.getPath) + private def artifact2 = new File(getClass.getResource("/artifact2.txt").toURI.getPath) + + private def modules = Map( + ("org.example", "my-module", "0.0.1-SNAPSHOT") -> List( + FakeArtifact("artifact1", "jar", "jar", artifact1) + ), + + ("com.example", "example", "1.0.0") -> List( + FakeArtifact("artifact1", "jar", "jar", artifact1), + FakeArtifact("artifact2", "txt", "txt", artifact2) + ), + + ("com.example", "another-example", "1.0.0") -> List( + FakeArtifact("artifact1", "jar", "jar", artifact1), + FakeArtifact("non-existing", "txt", "txt", new File("non-existing-file")) + ) + ) + + private def fakeResolver = new FakeResolver("FakeResolver", new File("tmp"), modules) + override def resolvers: Seq[Resolver] = Seq(new RawRepository(fakeResolver)) + private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Seq(myModule), None) + private def getAllFiles(report: UpdateReport) = + for { + conf <- report.configurations + m <- conf.modules + (_, f) <- m.artifacts + } yield f + +} \ No newline at end of file diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala new file mode 100644 index 000000000..7859c71ee --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala @@ -0,0 +1,145 @@ +package sbt +package internal +package librarymanagement + +import sbt.internal.util.UnitSpec + +import java.net.URL + +/** + * Tests that we can correctly parse repositories definitions. + */ +class RepositoriesParserSpecification extends UnitSpec { + import RepositoriesParser._ + + "The RepositoriesParser" should "check that repositories file starts with [repositories]" in { + val file = """local + |maven-central""".stripMargin + a[Exception] should be thrownBy RepositoriesParser(file) + } + + it should "parse the local repository" in { + val file = """[repositories] + | local""".stripMargin + val repos = RepositoriesParser(file) + repos.size shouldBe 1 + repos(0) shouldBe PredefinedRepository(xsbti.Predefined.Local) + + } + + it should "parse the local maven repository" in { + val file = """[repositories] + | maven-local""".stripMargin + val repos = RepositoriesParser(file) + repos.size shouldBe 1 + repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenLocal) + } + + it should "parse Maven Central repository" in { + val file = """[repositories] + | maven-central""".stripMargin + val repos = RepositoriesParser(file) + repos.size shouldBe 1 + repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenCentral) + } + + it should "parse simple Maven repository" in { + val file = """[repositories] + | mavenRepo: https://repo1.maven.org""".stripMargin + val repos = RepositoriesParser(file) + repos.size shouldBe 1 + repos(0) shouldBe MavenRepository("mavenRepo", new URL("https://repo1.maven.org")) + } + + it should "parse `bootOnly` option" in { + val file = """[repositories] + | ivyRepo: https://repo1.maven.org, [orgPath], bootOnly""".stripMargin + val repos = RepositoriesParser(file) + val expected = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + mavenCompatible = false, + skipConsistencyCheck = false, + descriptorOptional = false, + bootOnly = true) + repos.size shouldBe 1 + repos(0) shouldBe expected + } + + it should "parse `mavenCompatible` option" in { + val file = """[repositories] + | ivyRepo: https://repo1.maven.org, [orgPath], mavenCompatible""".stripMargin + val repos = RepositoriesParser(file) + val expected = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + mavenCompatible = true, + skipConsistencyCheck = false, + descriptorOptional = false, + bootOnly = false) + repos.size shouldBe 1 + repos(0) shouldBe expected + } + + it should "parse `skipConsistencyCheck` option" in { + val file = """[repositories] + | ivyRepo: https://repo1.maven.org, [orgPath], skipConsistencyCheck""".stripMargin + val repos = RepositoriesParser(file) + val expected = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + mavenCompatible = false, + skipConsistencyCheck = true, + descriptorOptional = false, + bootOnly = false) + repos.size shouldBe 1 + repos(0) shouldBe expected + } + + it should "parse `descriptorOptional` option" in { + val file = """[repositories] + | ivyRepo: https://repo1.maven.org, [orgPath], descriptorOptional""".stripMargin + val repos = RepositoriesParser(file) + val expected = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + mavenCompatible = false, + skipConsistencyCheck = false, + descriptorOptional = true, + bootOnly = false) + repos.size shouldBe 1 + repos(0) shouldBe expected + } + + it should "parse complex ivy repository definition" in { + val file = """[repositories] + | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck""".stripMargin + val repos = RepositoriesParser(file) + val expected = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", + mavenCompatible = false, + skipConsistencyCheck = true, + descriptorOptional = true, + bootOnly = false) + repos.size shouldBe 1 + repos(0) shouldBe expected + } + + it should "parse multiple repositories defined together" in { + val file = """[repositories] + | local + | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck + | mavenRepo: https://repo1.maven.org""".stripMargin + val expected0 = PredefinedRepository(xsbti.Predefined.Local) + val expected1 = + IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", + mavenCompatible = false, + skipConsistencyCheck = true, + descriptorOptional = true, + bootOnly = false) + val expected2 = MavenRepository("mavenRepo", new URL("https://repo1.maven.org")) + + val repos = RepositoriesParser(file) + repos.size shouldBe 3 + repos(0) shouldBe expected0 + repos(1) shouldBe expected1 + repos(2) shouldBe expected2 + } + +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 4a46dfaaf..12d73358b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -11,6 +11,7 @@ object Dependencies { lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion + lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" From ed0f2af66baaac91b9ee62fed0eab1fb22559336 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Wed, 27 Apr 2016 10:33:02 +0200 Subject: [PATCH 0511/1030] Fix warning with Scala 2.11 We get a warning about the exhaustivity check, but the warning disappears if we increase the maximum recursion depth. --- .../librarymanagement/RepositoriesParser.scala | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala index 852c6d0f4..1f56dbb6f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala @@ -50,10 +50,14 @@ private[sbt] object RepositoriesParser { name ~ ": " ~ basicUri ~ (separator ~> ivyPattern).? ~ (separator ~> afterPattern).? map { case name ~ ": " ~ uri ~ None ~ _ => new MavenRepository(name, uri.toURL) - case name ~ ": " ~ uri ~ Some(ivy) ~ None => - new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false) - case name ~ ": " ~ uri ~ Some(ivy) ~ Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) => - new IvyRepository(name, uri.toURL, ivy, artifactPattern getOrElse ivy, mc, sc, dOpt, bo) + case name ~ ": " ~ uri ~ Some(ivy) ~ ap => + // scalac complains about the recursion depth if we pattern match over `ap` directly. + ap match { + case Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) => + new IvyRepository(name, uri.toURL, ivy, artifactPattern getOrElse ivy, mc, sc, dOpt, bo) + case None => + new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false) + } } def resolver: Parser[xsbti.Repository] = From d304a95b241a323c14a5111fbd46c9ac7f642e2f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 4 May 2016 22:49:03 -0400 Subject: [PATCH 0512/1030] Bump dependencies --- .gitignore | 2 ++ .../ivyint/CachedResolutionResolveEngine.scala | 4 ++-- .../src/test/scala/BaseIvySpecification.scala | 2 +- project/Dependencies.scala | 8 ++++---- 4 files changed, 9 insertions(+), 7 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..3cedeeb25 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +tmp/ +target/ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index c566fea30..6f4a69065 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -137,7 +137,7 @@ private[sbt] class CachedResolutionResolveCache() { } def getOrElseUpdateMiniGraph(md: ModuleDescriptor, changing0: Boolean, logicalClock: LogicalClock, miniGraphPath: File, cachedDescriptor: File, log: Logger)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = { - import Path._ + import sbt.io.syntax._ val mrid = md.getResolvedModuleRevisionId val (pathOrg, pathName, pathRevision) = md match { case x: ArtificialModuleDescriptor => @@ -288,7 +288,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { */ def customResolve(md0: ModuleDescriptor, missingOk: Boolean, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = cachedResolutionResolveCache.getOrElseUpdateProjectReport(md0.getModuleRevisionId, logicalClock) { - import Path._ + import sbt.io.syntax._ val start = System.currentTimeMillis val miniGraphPath = depDir / "module" val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 260ac3517..4a1f4e6ab 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -1,7 +1,7 @@ package sbt.internal.librarymanagement -import sbt.io.Path._ import sbt.io.IO +import sbt.io.syntax._ import java.io.File import cross.CrossVersionUtil import sbt.util.Logger diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 12d73358b..9d523d920 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,17 +3,17 @@ import Keys._ object Dependencies { lazy val scala210 = "2.10.6" - lazy val scala211 = "2.11.7" + lazy val scala211 = "2.11.8" - val ioVersion = "1.0.0-M3" - val utilVersion = "0.1.0-M8" + val ioVersion = "1.0.0-M5" + val utilVersion = "0.1.0-M12" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion - lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0-M1" + lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" From bd082a562bbc24658a6be5fa8ec161ed35c48122 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 7 Mar 2016 11:44:34 +0100 Subject: [PATCH 0513/1030] Check that default artifact exists when trying to retrieve it. When concatenating the artifacts coming from two modules, we sometimes attempted to create a default artifact from the organization and name of the module. However, this may fail because a module a % b "1.0" may not have an artifact named "b.jar" (see sbt/sbt#2431). Fixes sbt/sbt#2431. --- .../librarymanagement/ivyint/MergeDescriptors.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 03e043043..390266a69 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -79,8 +79,8 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc { if (as.isEmpty) if (bs.isEmpty) as - else defaultArtifact(a) +: explicitConfigurations(b, bs) - else if (bs.isEmpty) explicitConfigurations(a, as) :+ defaultArtifact(b) + else defaultArtifact(a) ++ explicitConfigurations(b, bs) + else if (bs.isEmpty) explicitConfigurations(a, as) ++ defaultArtifact(b) else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) } private[this] def explicitConfigurations(base: DependencyDescriptor, arts: Array[DependencyArtifactDescriptor]): Array[DependencyArtifactDescriptor] = @@ -93,11 +93,11 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc else art } - private[this] def defaultArtifact(a: DependencyDescriptor): DependencyArtifactDescriptor = + private[this] def defaultArtifact(a: DependencyDescriptor): Array[DependencyArtifactDescriptor] = { val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) addConfigurations(dd, a.getModuleConfigurations) - dd + a.getAllDependencyArtifacts.filter(_ == dd) } private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = { From 8e333984f2e48c0d9ad7cc8f9531619dca4c10b0 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 14 Mar 2016 08:51:25 +0100 Subject: [PATCH 0514/1030] Create default artifact for deps from POM files Dependency descriptors that are created from POM files do not specify their artifacts. In those cases, it is correct to create a default artifact. --- .../internal/librarymanagement/ivyint/MergeDescriptors.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 390266a69..475e6056f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -97,7 +97,10 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc { val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) addConfigurations(dd, a.getModuleConfigurations) - a.getAllDependencyArtifacts.filter(_ == dd) + // If the dependency descriptor is empty, then it means that it has been created from a POM file. In this case, + // it is correct to create a seemingly non-existent dependency artifact. + if (a.getAllDependencyArtifacts.isEmpty) Array(dd) + else a.getAllDependencyArtifacts filter (_ == dd) } private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = { From a70c79a73114f7bb84b93581172c9f96c30b56de Mon Sep 17 00:00:00 2001 From: ddworak Date: Sun, 8 May 2016 12:53:19 +0200 Subject: [PATCH 0515/1030] fix typos --- .../ivyint/ErrorMessageAuthenticator.scala | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 60d6a59b9..48cb3bb83 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -1,14 +1,10 @@ package sbt.internal.librarymanagement package ivyint -import java.lang.reflect.Field -import java.lang.reflect.Method -import java.net.Authenticator -import java.net.PasswordAuthentication -import org.apache.ivy.util.Credentials +import java.net.{ Authenticator, PasswordAuthentication } + import org.apache.ivy.util.Message import org.apache.ivy.util.url.IvyAuthenticator -import org.apache.ivy.util.url.CredentialsStore /** * Helper to install an Authenticator that works with the IvyAuthenticator to provide better error messages when @@ -19,9 +15,9 @@ object ErrorMessageAuthenticator { private def originalAuthenticator: Option[Authenticator] = { try { - val f = classOf[Authenticator].getDeclaredField("theAuthenticator"); - f.setAccessible(true); - Option(f.get(null).asInstanceOf[Authenticator]) + val field = classOf[Authenticator].getDeclaredField("theAuthenticator") + field.setAccessible(true) + Option(field.get(null).asInstanceOf[Authenticator]) } catch { // TODO - Catch more specific errors. case t: Throwable => @@ -48,7 +44,7 @@ object ErrorMessageAuthenticator { case originalOpt => installIntoIvyImpl(originalOpt) } catch { case t: Throwable => - Message.debug("Error occurred will trying to install debug messages into Ivy Authentication" + t.getMessage) + Message.debug("Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage) } Some(ivy) } @@ -60,8 +56,8 @@ object ErrorMessageAuthenticator { try Authenticator.setDefault(new ErrorMessageAuthenticator(original)) catch { case e: SecurityException if !securityWarningLogged => - securityWarningLogged = true; - Message.warn("Not enough permissions to set the ErorrMessageAuthenticator. " + securityWarningLogged = true + Message.warn("Not enough permissions to set the ErrorMessageAuthenticator. " + "Helpful debug messages disabled!"); } // We will try to use the original authenticator as backup authenticator. @@ -94,7 +90,7 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato Message.error(s"Unable to find credentials for [${getRequestingPrompt} @ ${host}].") val configuredRealms = IvyCredentialsLookup.realmsForHost.getOrElse(host, Set.empty) if (configuredRealms.nonEmpty) { - Message.error(s" Is one of these realms mispelled for host [${host}]:") + Message.error(s" Is one of these realms misspelled for host [${host}]:") configuredRealms foreach { realm => Message.error(s" * ${realm}") } @@ -107,7 +103,7 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato // Grabs the authentication that would have been provided had we not been installed... def originalAuthentication: Option[PasswordAuthentication] = { - Authenticator.setDefault(original.getOrElse(null)) + Authenticator.setDefault(original.orNull) try Option(Authenticator.requestPasswordAuthentication( getRequestingHost, getRequestingSite, From 4abaec8622a9eabaa06d9122f3bc0c84369b9890 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 10 May 2016 00:34:40 -0400 Subject: [PATCH 0516/1030] Fix dependencies --- build.sbt | 28 ++++++++++++++++++++++------ project/doge.sbt | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 project/doge.sbt diff --git a/build.sbt b/build.sbt index a37e69249..390f51f9d 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ def baseVersion = "0.1.0" def internalPath = file("internal") def commonSettings: Seq[Setting[_]] = Seq( - scalaVersion := scala210, + scalaVersion := scala211, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), @@ -52,19 +52,35 @@ lazy val root = (project in file(".")). publishLocal := {}, publishArtifact in Compile := false, publishArtifact in Test := false, - publishArtifact := false + publishArtifact := false, + customCommands ) lazy val lm = (project in file("librarymanagement")). settings( commonSettings, libraryDependencies ++= Seq( - utilLogging, (utilLogging % Test).classifier("tests"), - sbtIO, (sbtIO % Test).classifier("tests"), + utilLogging.artifacts( + Artifact("util-logging", "jar", "jar", classifier = None, configurations = List(Compile), url = None), + Artifact("util-logging", "jar", "jar", classifier = Some("tests"), configurations = List(Test), url = None) + ), + sbtIO.artifacts( + Artifact("io", "jar", "jar", classifier = None, configurations = List(Compile), url = None), + Artifact("io", "jar", "jar", classifier = Some("tests"), configurations = List(Test), url = None) + ), utilTesting % Test, utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, name := "librarymanagement", - binaryIssueFilters ++= Seq( - ) + binaryIssueFilters ++= Seq() ) + +def customCommands: Seq[Setting[_]] = Seq( + commands += Command.command("release") { state => + // "clean" :: + "so compile" :: + "so publishSigned" :: + "reload" :: + state + } +) diff --git a/project/doge.sbt b/project/doge.sbt new file mode 100644 index 000000000..fedea9490 --- /dev/null +++ b/project/doge.sbt @@ -0,0 +1 @@ +addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") From 87b3ca04c0669233c9565f9f7e0a8852dbe27c04 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 11 May 2016 13:57:14 -0400 Subject: [PATCH 0517/1030] Don't depend on other projects' tests --- build.sbt | 15 ++++----------- .../src/test/scala/BaseIvySpecification.scala | 1 - .../src/test/scala/ComponentManagerTest.scala | 1 - .../src/test/scala/CustomPomParserTest.scala | 1 - .../test/scala/InconsistentDuplicateSpec.scala | 1 - .../src/test/scala/MakePomSpec.scala | 1 - .../RepositoriesParserSpecification.scala | 2 -- .../internal/librarymanagement/TestLogger.scala | 15 +++++++++++++++ .../sbt/internal/librarymanagement/UnitSpec.scala | 7 +++++++ project/Dependencies.scala | 4 ++-- 10 files changed, 28 insertions(+), 20 deletions(-) create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala diff --git a/build.sbt b/build.sbt index 390f51f9d..254bb647d 100644 --- a/build.sbt +++ b/build.sbt @@ -33,7 +33,7 @@ def commonSettings: Seq[Setting[_]] = Seq( "-Ywarn-value-discard"), previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, - publishArtifact in Test := true + publishArtifact in Test := false ) lazy val root = (project in file(".")). @@ -59,19 +59,12 @@ lazy val root = (project in file(".")). lazy val lm = (project in file("librarymanagement")). settings( commonSettings, + name := "librarymanagement", libraryDependencies ++= Seq( - utilLogging.artifacts( - Artifact("util-logging", "jar", "jar", classifier = None, configurations = List(Compile), url = None), - Artifact("util-logging", "jar", "jar", classifier = Some("tests"), configurations = List(Test), url = None) - ), - sbtIO.artifacts( - Artifact("io", "jar", "jar", classifier = None, configurations = List(Compile), url = None), - Artifact("io", "jar", "jar", classifier = Some("tests"), configurations = List(Test), url = None) - ), - utilTesting % Test, + utilLogging, sbtIO, utilTesting % Test, utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, - name := "librarymanagement", + publishArtifact in Test := false, binaryIssueFilters ++= Seq() ) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 4a1f4e6ab..aec1ad198 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -6,7 +6,6 @@ import java.io.File import cross.CrossVersionUtil import sbt.util.Logger import sbt.internal.util.ConsoleLogger -import sbt.internal.util.UnitSpec import sbt.librarymanagement._ import ivyint.SbtChainResolver import Configurations._ diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 00c76143f..8f6bec88f 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -8,7 +8,6 @@ import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider import sbt.util.Logger -import sbt.internal.util.{ UnitSpec, TestLogger } // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 833336dfe..16874c3d3 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -8,7 +8,6 @@ import sbt.librarymanagement._ import sbt.io.IO.withTemporaryDirectory import sbt.util.Logger import sbt.internal.util.ConsoleLogger -import sbt.internal.util.UnitSpec class CustomPomParserTest extends UnitSpec { "CustomPomParser" should "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index ab910609c..1e94e1196 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -1,6 +1,5 @@ package sbt.internal.librarymanagement -import sbt.internal.util.UnitSpec import sbt.librarymanagement._ // This is a specification to check the inconsistent duplicate warnings diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index d1dec575f..1a910ca91 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -3,7 +3,6 @@ package sbt.internal.librarymanagement import java.io.File import sbt.util.Logger import sbt.internal.util.ConsoleLogger -import sbt.internal.util.UnitSpec // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html // http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala index 7859c71ee..707bbcffa 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala @@ -2,8 +2,6 @@ package sbt package internal package librarymanagement -import sbt.internal.util.UnitSpec - import java.net.URL /** diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala new file mode 100644 index 000000000..4dace2131 --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala @@ -0,0 +1,15 @@ +package sbt +package internal +package librarymanagement + +import sbt.util._ +import sbt.internal.util._ + +object TestLogger { + def apply[T](f: Logger => T): T = + { + val log = new BufferedLogger(ConsoleLogger()) + log.setLevel(Level.Debug) + log.bufferQuietly(f(log)) + } +} diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala new file mode 100644 index 000000000..238e018e9 --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala @@ -0,0 +1,7 @@ +package sbt +package internal +package librarymanagement + +import org.scalatest._ + +abstract class UnitSpec extends FlatSpec with Matchers diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9d523d920..c06e52b1f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,8 +5,8 @@ object Dependencies { lazy val scala210 = "2.10.6" lazy val scala211 = "2.11.8" - val ioVersion = "1.0.0-M5" - val utilVersion = "0.1.0-M12" + val ioVersion = "1.0.0-M6" + val utilVersion = "0.1.0-M13" lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion From 92ca28e25af3383b5db9a79642fc57a2d9de5a90 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 14 Mar 2016 13:28:50 +0100 Subject: [PATCH 0518/1030] Use configuration of evicted nodes with cached resolution Consider a configuration where we have two projects, A and B. A has a library dependency on "a" % "b" % "1.0.0" % "compile->runtime" and "a" % "b" % "1.0.0" % "compile->runtime2" B depends on project A, and has a library dependency on "a" % "b" % "1.0.1" % "compile->runtime". Note that project B depends on a more recent version of "a" % "b" than project A, and that it depends ONLY on it's "runtime" configuration. However, when compiling project B, we expect to have on the classpath project A, and "a" % "b" % "1.0.1" % "compile->runtime" AND "a" % "b" % "1.0.1" % "compile->runtime2" because it is part of the compile configuration of project A. This commit changes the cached resolution engine so that it behaves like that, by first resolving dependencies on other project and then ensuring that the dependent project specifies dependencies on the same configurations. Mark test dependency-management/cached-resolution-configurations as passing. --- .../CachedResolutionResolveEngine.scala | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 6f4a69065..2e0a940b9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -331,12 +331,41 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { Left(new ResolveException(messages, failed, failedPaths)) } } - val results = mds map { + val (internal, external) = mds.partition { case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined } + val internalResults = internal map { case (md, changing, dd) => cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { doWork(md, dd) } } + val externalResults = external map { + case (md0, changing, dd) => + val configurationsInInternal = internalResults flatMap { + case Right(ur) => ur.allModules.flatMap { + case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } + case _ => Nil + } + + dd match { + case d: DefaultDependencyDescriptor => + configurationsInInternal foreach { c => + val configurations = c.split(";").map(_.split("->")) + configurations foreach { conf => d.addDependencyConfiguration(conf(0), conf(1)) } + } + + case _ => () + } + + // cache.getOrElseUpdateMiniGraph(md0, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + doWork(md0, dd) + // } + } + val results = internalResults ++ externalResults val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0) From ba274e05ac55e4ac5127b24a91fbf25f82c62512 Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Mon, 11 Apr 2016 10:06:13 +0200 Subject: [PATCH 0519/1030] Re-enable caching and updating minigraph in cached resolution --- .../ivyint/CachedResolutionResolveEngine.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 2e0a940b9..6a2856792 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -361,9 +361,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case _ => () } - // cache.getOrElseUpdateMiniGraph(md0, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { - doWork(md0, dd) - // } + cache.getOrElseUpdateMiniGraph(md0, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + doWork(md0, dd) + } } val results = internalResults ++ externalResults val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) From 1756d7372486338e86856a6bce00531d1b95746e Mon Sep 17 00:00:00 2001 From: Martin Duhem Date: Tue, 24 May 2016 10:25:24 +0200 Subject: [PATCH 0520/1030] Workaround for sbt/sbt#2620 --- .../ivyint/CachedResolutionResolveEngine.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 6a2856792..892d4b8e4 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -355,7 +355,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case d: DefaultDependencyDescriptor => configurationsInInternal foreach { c => val configurations = c.split(";").map(_.split("->")) - configurations foreach { conf => d.addDependencyConfiguration(conf(0), conf(1)) } + configurations foreach { conf => + try d.addDependencyConfiguration(conf(0), conf(1)) + catch { case _: Throwable => () } // An exception will be thrown if `conf(0)` doesn't exist. + } } case _ => () From 52867b8c9536b8b37bafe6c9a0ea360a9dd42bcf Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Thu, 2 Jun 2016 22:15:06 +0100 Subject: [PATCH 0521/1030] Override scala organization and version transitively at the Ivy level --- .../sbt/librarymanagement/IvyScala.scala | 43 +++++++++++++++---- .../src/test/scala/BaseIvySpecification.scala | 4 +- .../src/test/scala/EvictionWarningSpec.scala | 28 +++++++++--- .../src/test/scala/ScalaOverrideTest.scala | 42 ++++++++++++++++++ 4 files changed, 101 insertions(+), 16 deletions(-) create mode 100644 librarymanagement/src/test/scala/ScalaOverrideTest.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index d2df9b4cf..d01027769 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -9,6 +9,7 @@ import scala.collection.mutable.HashSet import org.apache.ivy.core.module.descriptor._ import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher +import org.apache.ivy.plugins.namespace.NamespaceTransformer import sbt.util.Logger object ScalaArtifacts { @@ -16,6 +17,8 @@ object ScalaArtifacts { val LibraryID = "scala-library" val CompilerID = "scala-compiler" val ReflectID = "scala-reflect" + val ActorsID = "scala-actors" + val ScalapID = "scalap" val DottyIDPrefix = "dotty" def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" @@ -47,17 +50,41 @@ private[sbt] object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) - checkDependencies(module, check.scalaBinaryVersion, check.configurations, log) + checkDependencies(module, check.scalaOrganization, check.scalaBinaryVersion, check.configurations, log) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaFullVersion) + overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion) } - def overrideScalaVersion(module: DefaultModuleDescriptor, version: String): Unit = { - overrideVersion(module, Organization, LibraryID, version) - overrideVersion(module, Organization, CompilerID, version) - overrideVersion(module, Organization, ReflectID, version) + + class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String) extends DependencyDescriptorMediator { + def mediate(dd: DependencyDescriptor): DependencyDescriptor = { + val transformer = + new NamespaceTransformer { + def transform(mrid: ModuleRevisionId): ModuleRevisionId = { + if (mrid == null) mrid + else + mrid.getName match { + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + ModuleRevisionId.newInstance(scalaOrganization, name, mrid.getBranch, scalaVersion, mrid.getQualifiedExtraAttributes) + case _ => mrid + } + } + + def isIdentity: Boolean = false + } + + DefaultDependencyDescriptor.transformInstance(dd, transformer, false) + } } + + def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String): Unit = { + val mediator = new OverrideScalaMediator(organization, version) + module.addDependencyDescriptorMediator(new ModuleId(Organization, "*"), ExactPatternMatcher.INSTANCE, mediator) + if (organization != Organization) + module.addDependencyDescriptorMediator(new ModuleId(organization, "*"), ExactPatternMatcher.INSTANCE, mediator) + } + def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String): Unit = { val id = new ModuleId(org, name) val over = new OverrideDependencyDescriptorMediator(null, version) @@ -68,13 +95,13 @@ private[sbt] object IvyScala { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { + private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) - def isScalaLangOrg = id.getOrganisation == Organization + def isScalaLangOrg = id.getOrganisation == scalaOrganization def isNotScalaActorsMigration = !(id.getName startsWith "scala-actors-migration") // Exception to the rule: sbt/sbt#1818 def isNotScalaPickling = !(id.getName startsWith "scala-pickling") // Exception to the rule: sbt/sbt#1899 def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index aec1ad198..7e561640d 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -20,7 +20,7 @@ trait BaseIvySpecification extends UnitSpec { def configurations = Seq(Compile, Test, Runtime) def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String], - uo: UpdateOptions = UpdateOptions()): IvySbt#Module = { + uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => new IvyScala( scalaFullVersion = fv, @@ -28,7 +28,7 @@ trait BaseIvySpecification extends UnitSpec { configurations = Nil, checkExplicit = true, filterImplicit = false, - overrideScalaVersion = false + overrideScalaVersion = overrideScalaVersion ) } diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 35b3e994b..c1a77bf31 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -5,12 +5,16 @@ import sbt.internal.librarymanagement.BaseIvySpecification class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - """Eviction of scala-library whose scalaVersion + """Eviction of non-overridden scala-library whose scalaVersion """ should "be detected" in scalaVersionWarn1() - it should "not be detected if it's diabled" in scalaVersionWarn2() + it should "not be detected if it's disabled" in scalaVersionWarn2() it should "print out message about the eviction" in scalaVersionWarn3() it should "print out message about the eviction with callers" in scalaVersionWarn4() + """Non-eviction of overridden scala-library whose scalaVersion + """ should "not be detected if it's enabled" in scalaVersionWarn5() + it should "not be detected if it's disabled" in scalaVersionWarn6() + """Including two (suspect) binary incompatible Java libraries to direct dependencies """ should "be detected as eviction" in javaLibWarn1() it should "not be detected if it's disabled" in javaLibWarn2() @@ -61,19 +65,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionDeps = Seq(scala2102, akkaActor230) def scalaVersionWarn1() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size (1) } def scalaVersionWarn2() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) } def scalaVersionWarn3() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( @@ -86,7 +90,7 @@ class EvictionWarningSpec extends BaseIvySpecification { } def scalaVersionWarn4() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe List( @@ -97,6 +101,18 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } + def scalaVersionWarn5() = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size (0) + } + + def scalaVersionWarn6() = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) + } + def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) def javaLibWarn1() = { diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala new file mode 100644 index 000000000..6fd2425c4 --- /dev/null +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -0,0 +1,42 @@ +package sbt.librarymanagement + +import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId } +import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor + +import sbt.internal.util.UnitSpec + +import IvyScala.OverrideScalaMediator +import ScalaArtifacts._ + +class ScalaOverrideTest extends UnitSpec { + val OtherOrgID = "other.org" + + def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { + val osm = new OverrideScalaMediator(org0, version0) + + val mrid = ModuleRevisionId.newInstance(org1, name1, version1) + val dd = new DefaultDependencyDescriptor(mrid, false) + + val res = osm.mediate(dd) + res.getDependencyRevisionId shouldBe ModuleRevisionId.newInstance(org0, name1, version0) + } + + """OverrideScalaMediator + """ should "Override compiler version" in check(Organization, "2.11.8")(Organization, CompilerID, "2.11.9") + it should "Override library version" in check(Organization, "2.11.8")(Organization, LibraryID, "2.11.8") + it should "Override reflect version" in check(Organization, "2.11.8")(Organization, ReflectID, "2.11.7") + it should "Override actors version" in check(Organization, "2.11.8")(Organization, ActorsID, "2.11.6") + it should "Override scalap version" in check(Organization, "2.11.8")(Organization, ScalapID, "2.11.5") + + it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")(Organization, CompilerID, "2.11.9") + it should "Override default library organization" in check(OtherOrgID, "2.11.8")(Organization, LibraryID, "2.11.8") + it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")(Organization, ReflectID, "2.11.7") + it should "Override default actors organization" in check(OtherOrgID, "2.11.8")(Organization, ActorsID, "2.11.6") + it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")(Organization, ScalapID, "2.11.5") + + it should "Override custom compiler organization" in check(Organization, "2.11.8")(OtherOrgID, CompilerID, "2.11.9") + it should "Override custom library organization" in check(Organization, "2.11.8")(OtherOrgID, LibraryID, "2.11.8") + it should "Override custom reflect organization" in check(Organization, "2.11.8")(OtherOrgID, ReflectID, "2.11.7") + it should "Override custom actors organization" in check(Organization, "2.11.8")(OtherOrgID, ActorsID, "2.11.6") + it should "Override custom scalap organization" in check(Organization, "2.11.8")(OtherOrgID, ScalapID, "2.11.5") +} From 76a1f12b1068b49d4ac50e6f77a1d6a617971511 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 17 Jun 2016 09:01:32 +0200 Subject: [PATCH 0522/1030] Remove scalacOptions that are already defined in sbt-houserules > show lm/scalacOptions [info] List(-encoding, utf8, -deprecation, -feature, -unchecked, -Xlint, -language:higherKinds, -language:implicitConversions, -Xfuture, -Yinline-warnings, -Yno-adapted-args, -Ywarn-dead-code, -Ywarn-numeric-widen, -Ywarn-value-discard, -encoding, utf8, -deprecation, -feature, -unchecked, -Xlint, -language:higherKinds, -language:implicitConversions, -Xfuture, -Yinline-warnings, -Xfatal-warnings, -Yno-adapted-args, -Ywarn-dead-code, -Ywarn-numeric-widen, -Ywarn-value-discard) [success] Total time: 0 s, completed 17-Jun-2016 09:00:40 > git diff [info] diff --git a/build.sbt b/build.sbt [info] index 254bb64..fed7303 100644 [info] --- a/build.sbt [info] +++ b/build.sbt [info] @@ -16,21 +16,7 @@ def commonSettings: Seq[Setting[_]] = Seq( [info] incOptions := incOptions.value.withNameHashing(true), [info] crossScalaVersions := Seq(scala210, scala211), [info] resolvers += Resolver.sonatypeRepo("public"), [info] - scalacOptions ++= Seq( [info] - "-encoding", "utf8", [info] - "-deprecation", [info] - "-feature", [info] - "-unchecked", [info] - "-Xlint", [info] - "-language:higherKinds", [info] - "-language:implicitConversions", [info] - "-Xfuture", [info] - "-Yinline-warnings", [info] - "-Xfatal-warnings", [info] - "-Yno-adapted-args", [info] - "-Ywarn-dead-code", [info] - "-Ywarn-numeric-widen", [info] - "-Ywarn-value-discard"), [info] + scalacOptions += "-Xfatal-warnings", [info] previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), [info] publishArtifact in Compile := true, [info] publishArtifact in Test := false RELOAD > reload [info] Loading global plugins from /Users/dnw/.dotfiles/.sbt/0.13/plugins [info] Loading project definition from /d/sbt-library-management/project [info] Set current project to LM Root (in build file:/d/sbt-library-management/) > show lm/scalacOptions [info] List(-encoding, utf8, -deprecation, -feature, -unchecked, -Xlint, -language:higherKinds, -language:implicitConversions, -Xfuture, -Yinline-warnings, -Yno-adapted-args, -Ywarn-dead-code, -Ywarn-numeric-widen, -Ywarn-value-discard, -Xfatal-warnings) --- build.sbt | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/build.sbt b/build.sbt index 254bb647d..fed730335 100644 --- a/build.sbt +++ b/build.sbt @@ -16,21 +16,7 @@ def commonSettings: Seq[Setting[_]] = Seq( incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala210, scala211), resolvers += Resolver.sonatypeRepo("public"), - scalacOptions ++= Seq( - "-encoding", "utf8", - "-deprecation", - "-feature", - "-unchecked", - "-Xlint", - "-language:higherKinds", - "-language:implicitConversions", - "-Xfuture", - "-Yinline-warnings", - "-Xfatal-warnings", - "-Yno-adapted-args", - "-Ywarn-dead-code", - "-Ywarn-numeric-widen", - "-Ywarn-value-discard"), + scalacOptions += "-Xfatal-warnings", previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false From 7db91141e1021579741b0bdd081b531b78b580cc Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 17 Jun 2016 09:03:23 +0200 Subject: [PATCH 0523/1030] Remove re-setting publishArtifact in Test, defined in commonSettings > show root/test:publishArtifact [info] lm/test:publishArtifact [info] false [info] root/test:publishArtifact [info] false > git diff [info] diff --git a/build.sbt b/build.sbt [info] index fed7303..6f1fb03 100644 [info] --- a/build.sbt [info] +++ b/build.sbt [info] @@ -37,7 +37,6 @@ lazy val root = (project in file(".")). [info] publish := {}, [info] publishLocal := {}, [info] publishArtifact in Compile := false, [info] - publishArtifact in Test := false, [info] publishArtifact := false, [info] customCommands [info] ) [info] @@ -50,7 +49,6 @@ lazy val lm = (project in file("librarymanagement")). [info] utilLogging, sbtIO, utilTesting % Test, [info] utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), [info] resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, [info] - publishArtifact in Test := false, [info] binaryIssueFilters ++= Seq() [info] ) [info] RELOAD > reload [info] Loading global plugins from /Users/dnw/.dotfiles/.sbt/0.13/plugins [info] Loading project definition from /d/sbt-library-management/project [info] Set current project to LM Root (in build file:/d/sbt-library-management/) > show root/test:publishArtifact [info] lm/test:publishArtifact [info] false [info] root/test:publishArtifact [info] false --- build.sbt | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.sbt b/build.sbt index fed730335..6f1fb0363 100644 --- a/build.sbt +++ b/build.sbt @@ -37,7 +37,6 @@ lazy val root = (project in file(".")). publish := {}, publishLocal := {}, publishArtifact in Compile := false, - publishArtifact in Test := false, publishArtifact := false, customCommands ) @@ -50,7 +49,6 @@ lazy val lm = (project in file("librarymanagement")). utilLogging, sbtIO, utilTesting % Test, utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, - publishArtifact in Test := false, binaryIssueFilters ++= Seq() ) From 9bf0da7bec90ab8496ddf2253d1052567fedc42f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 17 Jun 2016 09:04:49 +0200 Subject: [PATCH 0524/1030] Remove scripted test, forward-port fallout --- .../chainresolver/build.sbt | 36 ------------------- .../dependency-management/chainresolver/test | 3 -- 2 files changed, 39 deletions(-) delete mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/build.sbt delete mode 100644 sbt/src/sbt-test/dependency-management/chainresolver/test diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt b/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt deleted file mode 100644 index f9454c341..000000000 --- a/sbt/src/sbt-test/dependency-management/chainresolver/build.sbt +++ /dev/null @@ -1,36 +0,0 @@ -lazy val check = taskKey[Unit]("Runs the check") - -def commonSettings: Seq[Def.Setting[_]] = - Seq( - ivyPaths := new IvyPaths( (baseDirectory in ThisBuild).value, Some((target in LocalRootProject).value / "ivy-cache")), - scalaVersion in ThisBuild := "2.11.7", - organization in ThisBuild := "com.example", - version in ThisBuild := "0.1.0-SNAPSHOT", - autoScalaLibrary := false, - crossPaths := false - ) - -lazy val realCommonsIoClient = project. - settings( - commonSettings, - name := "a", - libraryDependencies := Seq( - "commons-io" % "commons-io" % "1.3" - ), - fullResolvers := fullResolvers.value.filterNot(_.name == "inter-project") - ) - -lazy val fakeCommonsIo = project. - settings( - commonSettings, - organization := "commons-io", - name := "commons-io", - version := "1.3" - ) - -lazy val fakeCommonsIoClient = project. - dependsOn(fakeCommonsIo % "test->test"). - settings( - commonSettings, - name := "c" - ) diff --git a/sbt/src/sbt-test/dependency-management/chainresolver/test b/sbt/src/sbt-test/dependency-management/chainresolver/test deleted file mode 100644 index c3786f997..000000000 --- a/sbt/src/sbt-test/dependency-management/chainresolver/test +++ /dev/null @@ -1,3 +0,0 @@ -> realCommonsIoClient/update - -> fakeCommonsIoClient/update From 9dd40145537fb1a85751dee79fcaa5ddaff86190 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 21 Jun 2016 14:06:27 +0100 Subject: [PATCH 0525/1030] Give IvyPaths a nicer toString --- .../scala/sbt/internal/librarymanagement/IvyConfigurations.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index d71f959ec..897b40b80 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -11,6 +11,7 @@ import sbt.librarymanagement._ final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) + override def toString = s"IvyPaths($baseDirectory, $ivyHome)" } sealed trait IvyConfiguration { type This <: IvyConfiguration From 931b7d7af59b068a3ba5756651d4be193917156d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 21 Jun 2016 16:06:40 +0100 Subject: [PATCH 0526/1030] Remove unused and unused imports Note that the pickler/sbt-serlization macros are bringing in unused imports.. --- build.sbt | 3 +- .../librarymanagement/ComponentManager.scala | 3 +- .../librarymanagement/ConvertResolver.scala | 3 +- .../librarymanagement/CustomPomParser.scala | 14 ------- .../librarymanagement/CustomXmlParser.scala | 1 - .../librarymanagement/FakeResolver.scala | 6 --- .../sbt/internal/librarymanagement/Ivy.scala | 41 ++++++------------- .../internal/librarymanagement/IvyCache.scala | 3 +- .../librarymanagement/IvyConfigurations.scala | 2 +- .../librarymanagement/IvyLogger.scala | 3 +- .../librarymanagement/IvyRetrieve.scala | 2 - .../internal/librarymanagement/JsonUtil.scala | 2 - .../internal/librarymanagement/MakePom.scala | 1 - .../librarymanagement/ProjectResolver.scala | 5 +-- .../librarymanagement/ResolutionCache.scala | 7 +--- .../librarymanagement/RichUpdateReport.scala | 1 - .../impl/DependencyBuilders.scala | 6 --- .../CachedResolutionResolveEngine.scala | 16 +++----- .../ivyint/MergeDescriptors.scala | 13 ++---- .../sbt/librarymanagement/Artifact.scala | 2 +- .../librarymanagement/ConflictWarning.scala | 2 - .../sbt/librarymanagement/IvyInterface.scala | 6 +-- .../sbt/librarymanagement/Resolver.scala | 2 +- .../sbt/librarymanagement/UpdateOptions.scala | 3 +- .../sbt/librarymanagement/UpdateReport.scala | 2 - 25 files changed, 35 insertions(+), 114 deletions(-) diff --git a/build.sbt b/build.sbt index 6f1fb0363..6222b2428 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,8 @@ def commonSettings: Seq[Setting[_]] = Seq( incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala210, scala211), resolvers += Resolver.sonatypeRepo("public"), - scalacOptions += "-Xfatal-warnings", + scalacOptions += "-Ywarn-unused", + scalacOptions += "-Ywarn-unused-import", previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 5b7034de0..480912e7a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -3,7 +3,7 @@ */ package sbt.internal.librarymanagement -import java.io.{ File, FileOutputStream } +import java.io.File import java.util.concurrent.Callable import sbt.util.Logger import sbt.librarymanagement._ @@ -57,7 +57,6 @@ class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentPr case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) } private def invalid(msg: String) = throw new InvalidComponent(msg) - private def invalid(e: NotInCache) = throw new InvalidComponent(e.getMessage, e) def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } /** Retrieve the file for component 'id' from the local repository. */ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 99b731f89..1d0a6a470 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -5,7 +5,6 @@ package sbt.internal.librarymanagement import java.net.URL import java.util.Collections -import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings @@ -245,7 +244,7 @@ private[sbt] object ConvertResolver { } fireTransferInitiated(resource, TransferEvent.REQUEST_PUT); try { - var totalLength = source.length + val totalLength = source.length if (totalLength > 0) { progress.setTotalLength(totalLength); } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 7cee3008c..fbcf53649 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -11,10 +11,8 @@ import org.apache.ivy.util.extendable.ExtendableItem import java.io.{ File, InputStream } import java.net.URL -import java.util.regex.Pattern import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } import sbt.io.Hash -import sbt.librarymanagement._ // @deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { @@ -99,12 +97,6 @@ object CustomPomParser { // parses the immediate text nodes of the property. val extraDepAttributes = getDependencyExtra(filtered) - // Fixes up the detected extension in some cases missed by Ivy. - val convertArtifacts = artifactExtIncorrect(md) - - // Merges artifact sections for duplicate dependency definitions - val mergeDuplicates = IvySbt.hasDuplicateDependencies(md.getDependencies) - val unqualify = toUnqualify(filtered) // Here we always add extra attributes. There's a scenario where parent-pom information corrupts child-poms with "e:" namespaced xml elements @@ -123,12 +115,8 @@ object CustomPomParser { private[sbt] def toUnqualify(propertyAttributes: Map[String, String]): Map[String, String] = (propertyAttributes - ExtraAttributesKey) map { case (k, v) => ("e:" + k, v) } - private[this] def artifactExtIncorrect(md: ModuleDescriptor): Boolean = - md.getConfigurations.exists(conf => md.getArtifacts(conf.getName).exists(art => JarPackagings(art.getExt))) private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) - private[this] def condAddExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = - if (properties.isEmpty) id else addExtra(properties, id) private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = { import collection.JavaConverters._ @@ -167,8 +155,6 @@ object CustomPomParser { } private[this] def transform(dep: DependencyDescriptor, f: ModuleRevisionId => ModuleRevisionId): DependencyDescriptor = DefaultDependencyDescriptor.transformInstance(dep, namespaceTransformer(dep.getDependencyRevisionId, f), false) - private[this] def extraTransformer(txId: ModuleRevisionId, extra: Map[String, String]): NamespaceTransformer = - namespaceTransformer(txId, revId => addExtra(extra, revId)) private[this] def namespaceTransformer(txId: ModuleRevisionId, f: ModuleRevisionId => ModuleRevisionId): NamespaceTransformer = new NamespaceTransformer { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index cad47b173..d8100ddcf 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -11,7 +11,6 @@ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.repository.url.URLResource -import sbt.librarymanagement._ /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 197922940..58ef9f63d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -14,7 +14,6 @@ import org.apache.ivy.core.resolve.{ DownloadOptions, ResolveData, ResolvedModul import org.apache.ivy.core.search.{ ModuleEntry, OrganisationEntry, RevisionEntry } import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.namespace.Namespace -import org.apache.ivy.plugins.repository.url.URLResource import org.apache.ivy.plugins.resolver.{ DependencyResolver, ResolverSettings } import org.apache.ivy.plugins.resolver.util.ResolvedResource @@ -77,7 +76,6 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val report = new DownloadReport artifacts foreach { art => - val artifactOrigin = locate(art) Option(locate(art)) foreach (o => report.addArtifactReport(download(o, options))) } @@ -177,10 +175,6 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module override def setSettings(settings: ResolverSettings): Unit = () - private class LocalURLResource(jar: File) extends URLResource(jar.toURI.toURL) { - override def isLocal(): Boolean = true - } - } private[sbt] object FakeResolver { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 4e908fb66..29e8b0b42 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -5,35 +5,25 @@ package sbt.internal.librarymanagement import java.io.File import java.net.URI -import java.text.ParseException import java.util.concurrent.Callable -import java.util.{ Collection, Collections => CS, Date } -import CS.singleton import org.apache.ivy.Ivy -import org.apache.ivy.core.report.ResolveReport -import org.apache.ivy.core.{ IvyPatternHelper, LogOptions, IvyContext } -import org.apache.ivy.core.cache.{ ResolutionCacheManager, CacheMetadataOptions, DefaultRepositoryCacheManager, ModuleDescriptorWriter } +import org.apache.ivy.core.IvyPatternHelper +import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator -import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } +import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId } import org.apache.ivy.core.resolve._ import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.sort.SortEngine -import org.apache.ivy.plugins.latest.{ LatestStrategy, LatestRevisionStrategy, ArtifactInfo } import org.apache.ivy.plugins.matcher.PatternMatcher -import org.apache.ivy.plugins.parser.m2.{ PomModuleDescriptorParser } -import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, BasicResolver } -import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } -import org.apache.ivy.plugins.version.ExactVersionMatcher -import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => IFileRepository } -import org.apache.ivy.plugins.repository.url.URLResource -import org.apache.ivy.util.{ Message, MessageLogger, StringUtils => IvyStringUtils } +import org.apache.ivy.plugins.resolver.DependencyResolver +import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.util.extendable.ExtendableItem -import scala.xml.{ NodeSeq, Text } +import scala.xml.NodeSeq import scala.collection.mutable import sbt.util.Logger @@ -44,12 +34,13 @@ import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, Sbt final class IvySbt(val configuration: IvyConfiguration) { import configuration.baseDirectory - /** + /* * ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. * These are lazy so that they are loaded within the right context. This is important so that no Ivy XML configuration needs to be loaded, * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). */ + private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = { def action() = @@ -119,7 +110,8 @@ final class IvySbt(val configuration: IvyConfiguration) { private lazy val ivy: Ivy = mkIvy // Must be the same file as is used in Update in the launcher private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") - /** ========== End Configuration/Setup ============*/ + + // ========== End Configuration/Setup ============ /** Uses the configured Ivy instance within a safe context.*/ def withIvy[T](log: Logger)(f: Ivy => T): T = @@ -269,7 +261,7 @@ private[sbt] object IvySbt { settings.addResolver(chain) chain } - val otherChain = makeChain("Other", "sbt-other", other) + makeChain("Other", "sbt-other", other) val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } @@ -461,15 +453,6 @@ private[sbt] object IvySbt { if (map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map) } - private object javaMap { - import java.util.{ HashMap, Map } - def apply[K, V](pairs: (K, V)*): Map[K, V] = - { - val map = new HashMap[K, V] - pairs.foreach { case (key, value) => map.put(key, value) } - map - } - } /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ private def wrapped(module: ModuleID, dependencies: NodeSeq) = { @@ -608,7 +591,7 @@ private[sbt] object IvySbt { parser.parseDepsConfs(confs, dependencyDescriptor) } for (artifact <- dependency.explicitArtifacts) { - import artifact.{ name, classifier, `type`, extension, url } + import artifact.{ name, `type`, extension, url } val extraMap = extra(artifact) val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.orNull, extraMap) copyConfigurations(artifact, ivyArtifact.addConfiguration) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index d7ce761c6..ba3d97912 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -4,7 +4,6 @@ package sbt.internal.librarymanagement import java.io.File -import java.net.URL import org.apache.ivy.core.cache.{ ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager } import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact } @@ -69,7 +68,7 @@ class IvyCache(val ivyHome: Option[File]) { /** Calls the given function with the default Ivy cache.*/ def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = { - val (ivy, local) = basicLocalIvy(lock, log) + val (ivy, _) = basicLocalIvy(lock, log) ivy.withIvy(log) { ivy => val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] cache.setUseOrigin(false) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index d71f959ec..101e48c41 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -4,7 +4,7 @@ package sbt.internal.librarymanagement import java.io.File -import java.net.{ URI, URL } +import java.net.URI import scala.xml.NodeSeq import sbt.util.Logger import sbt.librarymanagement._ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index b5d61fc06..028306694 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -5,7 +5,6 @@ package sbt.internal.librarymanagement import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } import sbt.util.Logger -import sbt.librarymanagement._ /** Interface to Ivy logging. */ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { @@ -52,4 +51,4 @@ private final class SbtMessageLoggerEngine extends MessageLoggerEngine { private object SbtIvyLogger { val UnknownResolver = "unknown resolver" def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) -} \ No newline at end of file +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 0432719d5..b9917e1ad 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -6,7 +6,6 @@ package sbt.internal.librarymanagement import java.io.File import java.{ util => ju } import collection.mutable -import java.net.URL import org.apache.ivy.core.{ module, report, resolve } import module.descriptor.{ Artifact => IvyArtifact, License => IvyLicense } import module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } @@ -52,7 +51,6 @@ object IvyRetrieve { // only the revolved modules. // Sometimes the entire module can be excluded via rules etc. private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Seq[OrganizationArtifactReport] = { - val dependencies = confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index b570c7cef..69a6fa282 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -1,11 +1,9 @@ package sbt.internal.librarymanagement import java.io.File -import java.net.URL import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor import sbt.serialization._ -import java.net.{ URLEncoder, URLDecoder } import sbt.util.Logger import sbt.librarymanagement._ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index e52bb165b..2103cc6f0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -369,7 +369,6 @@ class MakePom(val log: Logger) { def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = { - class MavenRepo(name: String, snapshots: Boolean, releases: Boolean) val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) val mavenRepositories = repositories.flatMap { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala index 760f63f52..caca5a9ed 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala @@ -7,15 +7,14 @@ import java.io.File import java.util.Date import org.apache.ivy.core.{ cache, module, report, resolve, search } -import cache.{ ArtifactOrigin, RepositoryCacheManager } +import cache.ArtifactOrigin import search.{ ModuleEntry, OrganisationEntry, RevisionEntry } import module.id.ModuleRevisionId import module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor } import org.apache.ivy.plugins.namespace.Namespace -import org.apache.ivy.plugins.resolver.{ DependencyResolver, ResolverSettings } +import org.apache.ivy.plugins.resolver.ResolverSettings import report.{ ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport } import resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } -import sbt.librarymanagement._ /** * A Resolver that uses a predefined mapping from module ids to in-memory descriptors. diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index a480c8ed3..25103ba89 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -1,13 +1,11 @@ package sbt.internal.librarymanagement import java.io.File -import java.io.FileInputStream -import java.util.Properties import org.apache.ivy.core import org.apache.ivy.plugins.parser import core.IvyPatternHelper import core.settings.IvySettings -import core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager, DefaultResolutionCacheManager, ResolutionCacheManager } +import core.cache.ResolutionCacheManager import core.module.id.ModuleRevisionId import core.module.descriptor.ModuleDescriptor import ResolutionCache.{ Name, ReportDirectory, ResolvedName, ResolvedPattern } @@ -78,9 +76,6 @@ private[sbt] object ResolutionCache { private val ReportDirectory = "reports" - // name of the file providing a dependency resolution report for a configuration - private val ReportFileName = "report.xml" - // base name (name except for extension) of resolution report file private val ResolvedName = "resolved.xml" diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala index e4005ef21..db283b6c7 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -3,7 +3,6 @@ package internal package librarymanagement import java.io.File -import java.net.URL import sbt.librarymanagement._ /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index 517ea1aa0..9ceac2da6 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -29,17 +29,11 @@ final class GroupID private[sbt] (private[sbt] val groupID: String) { def %(artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) - @deprecated(deprecationMessage, "0.12.0") - def %%(artifactID: String, crossVersion: String => String) = groupArtifact(artifactID, CrossVersion.binaryMapped(crossVersion)) - @deprecated(deprecationMessage, "0.12.0") - def %%(artifactID: String, alternatives: (String, String)*) = groupArtifact(artifactID, CrossVersion.binaryMapped(Map(alternatives: _*) orElse { case s => s })) - private def groupArtifact(artifactID: String, cross: CrossVersion) = { nonEmpty(artifactID, "Artifact ID") new GroupArtifactID(groupID, artifactID, cross) } - private[this] def deprecationMessage = """Use the cross method on the constructed ModuleID. For example: ("a" % "b" % "1").cross(...)""" } final class GroupArtifactID private[sbt] ( private[sbt] val groupID: String, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 892d4b8e4..ef9d20209 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -2,7 +2,6 @@ package sbt.internal.librarymanagement package ivyint import java.util.Date -import java.net.URL import java.io.File import java.text.SimpleDateFormat import collection.concurrent @@ -12,19 +11,18 @@ import org.apache.ivy.Ivy import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } -import core.report.{ ResolveReport, ConfigurationResolveReport, DownloadReport } +import core.report.ResolveReport import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } -import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } -import core.{ IvyPatternHelper, LogOptions } +import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor } +import core.IvyPatternHelper import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } import annotation.tailrec import scala.concurrent.duration._ -import sbt.io.{ DirectoryFilter, Hash, IO, Path } +import sbt.io.{ DirectoryFilter, Hash, IO } import sbt.util.Logger import sbt.librarymanagement._ -import Configurations.{ System => _, _ } import sbt.internal.librarymanagement.syntax._ private[sbt] object CachedResolutionResolveCache { @@ -254,8 +252,6 @@ private[sbt] trait ArtificialModuleDescriptor { self: DefaultModuleDescriptor => } private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { - import CachedResolutionResolveCache._ - private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache private[sbt] def projectResolver: Option[ProjectResolver] private[sbt] def makeInstance: Ivy @@ -313,7 +309,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { val options1 = new ResolveOptions(options0) - var rr = withIvy(log) { ivy => + val rr = withIvy(log) { ivy => ivy.resolve(md, options1) } if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) @@ -718,7 +714,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val (surviving, evicted) = cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } (surviving, evicted) } else { - val (surviving, evicted, mgr) = doResolveConflict + val (surviving, evicted, _) = doResolveConflict (surviving, evicted) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 475e6056f..b3c8c378c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -1,17 +1,10 @@ package sbt.internal.librarymanagement package ivyint -import java.io.File -import java.net.URI -import java.util.{ Collection, Collections => CS } -import CS.singleton - -import org.apache.ivy.{ core, plugins, util, Ivy } +import org.apache.ivy.core import core.module.descriptor.{ DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } -import core.module.descriptor.{ DefaultDependencyDescriptor => DDD, DependencyDescriptor } -import core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } -import plugins.namespace.Namespace -import util.extendable.ExtendableItem +import core.module.descriptor.DependencyDescriptor +import core.module.id.{ ArtifactId, ModuleRevisionId } private[sbt] object MergeDescriptors { def mergeable(a: DependencyDescriptor, b: DependencyDescriptor): Boolean = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 8bf97bc05..fd9e33bef 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -11,7 +11,7 @@ final case class Artifact(name: String, `type`: String, extension: String, class def extra(attributes: (String, String)*) = copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) } -import Configurations.{ config, Optional, Pom, Test } +import Configurations.{ Optional, Pom, Test } object Artifact { def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index ab98c67af..98d9fe46a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -1,6 +1,5 @@ package sbt.librarymanagement -import sbt.internal.librarymanagement.DependencyFilter._ import sbt.util.{ Logger, Level } /** @@ -13,7 +12,6 @@ final case class ConflictWarning(label: String, level: Level.Value, failOnConfli object ConflictWarning { def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) - private def org = (_: ModuleID).organization private[this] def idString(org: String, name: String) = s"$org:$name" def default(label: String): ConflictWarning = ConflictWarning(label, Level.Error, true) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 964fe7447..54531bae4 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -3,11 +3,7 @@ */ package sbt.librarymanagement -import java.io.File -import java.net.{ URI, URL } -import scala.xml.NodeSeq -import org.apache.ivy.plugins.resolver.{ DependencyResolver, IBiblioResolver } -import org.apache.ivy.util.url.CredentialsStore +import java.net.URL import org.apache.ivy.core.module.descriptor import org.apache.ivy.util.filter.{ Filter => IvyFilter } import sbt.serialization._ diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 37224ccca..f0f3da55e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -5,7 +5,7 @@ package sbt.librarymanagement import java.io.{ IOException, File } import java.net.URL -import scala.xml.{ Text, NodeSeq, Elem, XML } +import scala.xml.XML import org.apache.ivy.plugins.resolver.DependencyResolver import org.xml.sax.SAXParseException diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index ed63b4c48..626d31371 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -1,6 +1,5 @@ package sbt.librarymanagement -import java.io.File import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings import sbt.util.Logger @@ -23,7 +22,7 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, // If set to true, use cached resolution. val cachedResolution: Boolean, - // Extention point for an alternative resolver converter. + // Extension point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter ) { def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 88603454d..06974aa90 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -4,10 +4,8 @@ package sbt.librarymanagement import java.io.File -import java.net.URL import java.{ util => ju } import sbt.serialization._ -import sbt.internal.librarymanagement.{ DependencyFilter, ConfigurationFilter, ModuleFilter, ArtifactFilter } /** * Provides information about resolution of a single configuration. From 9706577c67d9c63fe08e2a1edad2b3fc91c9dfde Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 21 Jun 2016 17:51:16 +0100 Subject: [PATCH 0527/1030] Drop Scala 2.10, add openjdk7 --- .travis.yml | 8 ++++---- build.sbt | 2 +- project/Dependencies.scala | 1 - 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb23581e8..44dc5a257 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: scala scala: - - 2.10.6 - - 2.11.7 + - 2.11.8 jdk: - - oraclejdk8 - - oraclejdk7 + - openjdk7 + - oraclejdk7 + - oraclejdk8 diff --git a/build.sbt b/build.sbt index 6222b2428..ab16fd295 100644 --- a/build.sbt +++ b/build.sbt @@ -14,7 +14,7 @@ def commonSettings: Seq[Setting[_]] = Seq( testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), incOptions := incOptions.value.withNameHashing(true), - crossScalaVersions := Seq(scala210, scala211), + crossScalaVersions := Seq(scala211), resolvers += Resolver.sonatypeRepo("public"), scalacOptions += "-Ywarn-unused", scalacOptions += "-Ywarn-unused-import", diff --git a/project/Dependencies.scala b/project/Dependencies.scala index c06e52b1f..8bd5bf78c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,7 +2,6 @@ import sbt._ import Keys._ object Dependencies { - lazy val scala210 = "2.10.6" lazy val scala211 = "2.11.8" val ioVersion = "1.0.0-M6" From ffcad3cdad77e8439cce9c4d01c3923ab2e4cbee Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 1 Jul 2016 23:03:03 +0100 Subject: [PATCH 0528/1030] Make CrossVersion & ModuleId more commonly equal Two instance of functions defined in the same way don't equal themselves, but the same instance of a function does. So by using a val idStringFun for full and binary, and making Binary and Full case classes there are much better chances that ModuleId's defined in the same way will be equal. --- .../sbt/librarymanagement/CrossVersion.scala | 15 +++++++++++++-- .../src/test/scala/CrossVersionTest.scala | 9 +++++++++ .../src/test/scala/ModuleIdTest.scala | 17 +++++++++++++++++ 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 librarymanagement/src/test/scala/ModuleIdTest.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index d3cf58d6a..d9869e030 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -26,6 +26,11 @@ object CrossVersion { */ final class Binary(val remapVersion: String => String) extends CrossVersion { override def toString = "Binary" + override def hashCode = remapVersion.## + override def equals(that: Any) = that match { + case that: Binary => this.remapVersion == that.remapVersion + case _ => false + } } /** @@ -35,6 +40,11 @@ object CrossVersion { */ final class Full(val remapVersion: String => String) extends CrossVersion { override def toString = "Full" + override def hashCode = remapVersion.## + override def equals(that: Any) = that match { + case that: Full => this.remapVersion == that.remapVersion + case _ => false + } } private val disabledTag = implicitly[FastTypeTag[Disabled.type]] @@ -75,7 +85,7 @@ object CrossVersion { } /** Cross-versions a module with the full version (typically the full Scala version). */ - def full: CrossVersion = new Full(idFun) + def full: CrossVersion = new Full(idStringFun) /** * Cross-versions a module with the result of applying `remapVersion` to the full version @@ -84,7 +94,7 @@ object CrossVersion { def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) /** Cross-versions a module with the binary version (typically the binary Scala version). */ - def binary: CrossVersion = new Binary(idFun) + def binary: CrossVersion = new Binary(idStringFun) /** * Cross-versions a module with the result of applying `remapVersion` to the binary version @@ -93,6 +103,7 @@ object CrossVersion { def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) private[this] def idFun[T]: T => T = x => x + private[this] val idStringFun = idFun[String] private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s)) diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 3f8a608ea..f70343e73 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -115,4 +115,13 @@ class CrossVersionTest extends UnitSpec { it should "return binary Scala version for 2.10.1 as 2.10" in { CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" } + it should "return disabled cross version as equal to a copy" in { + CrossVersion.Disabled shouldBe CrossVersion.Disabled + } + it should "return full cross version as equal to a copy" in { + CrossVersion.full shouldBe CrossVersion.full + } + it should "return binary cross version as equal to a copy" in { + CrossVersion.binary shouldBe CrossVersion.binary + } } diff --git a/librarymanagement/src/test/scala/ModuleIdTest.scala b/librarymanagement/src/test/scala/ModuleIdTest.scala new file mode 100644 index 000000000..8b1d7d7b7 --- /dev/null +++ b/librarymanagement/src/test/scala/ModuleIdTest.scala @@ -0,0 +1,17 @@ +package sbt.librarymanagement + +import sbt.internal.util.UnitSpec + +class ModuleIdTest extends UnitSpec { + "Module Id" should "return cross-disabled module id as equal to a copy" in { + ModuleID("com.acme", "foo", "1") shouldBe ModuleID("com.acme", "foo", "1") + } + it should "return cross-full module id as equal to a copy" in { + (ModuleID("com.acme", "foo", "1") cross CrossVersion.full) shouldBe + (ModuleID("com.acme", "foo", "1") cross CrossVersion.full) + } + it should "return cross-binary module id as equal to a copy" in { + (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) shouldBe + (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) + } +} From 138787f55e5fbcbeac751196b000855ff6ba1625 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 15 Jul 2016 07:57:04 +0100 Subject: [PATCH 0529/1030] Add Resolver.sbtIvyRepo (#49) .. deprecate & rename SbtPluginRepositoryRoot to SbtRepositoryRoot. --- .../src/main/scala/sbt/librarymanagement/Resolver.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index f0f3da55e..7f2c8779e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -174,7 +174,9 @@ object Resolver { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) - val SbtPluginRepositoryRoot = sbtPluginRepositoryRoot(useSecureResolvers) + val SbtRepositoryRoot = sbtRepositoryRoot(useSecureResolvers) + @deprecated("Renamed to SbtRepositoryRoot.", "1.0.0") + val SbtPluginRepositoryRoot = SbtRepositoryRoot val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = javanet2RepositoryRoot(useSecureResolvers) @@ -190,7 +192,7 @@ object Resolver { // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def typesafeRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. - private[sbt] def sbtPluginRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" + private[sbt] def sbtRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" @@ -202,7 +204,8 @@ object Resolver { def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) - def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtPluginRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) + def sbtIvyRepo(status: String) = url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) + def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) def bintrayRepo(owner: String, repo: String) = new MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))(Resolver.ivyStylePatterns) From cee81e3bb020b975ea21d568d31e6b2126ac46b4 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Mon, 22 Aug 2016 10:51:33 +0100 Subject: [PATCH 0530/1030] Configurable explicit list of artifacts for Scala binary version check --- .../main/scala/sbt/librarymanagement/IvyScala.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index d01027769..8b004ef9d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -19,6 +19,7 @@ object ScalaArtifacts { val ReflectID = "scala-reflect" val ActorsID = "scala-actors" val ScalapID = "scalap" + val Artifacts = Seq(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) val DottyIDPrefix = "dotty" def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" @@ -44,13 +45,13 @@ object SbtArtifacts { import ScalaArtifacts._ -final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization) +final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization, scalaArtifacts: Seq[String] = ScalaArtifacts.Artifacts) private[sbt] object IvyScala { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) - checkDependencies(module, check.scalaOrganization, check.scalaBinaryVersion, check.configurations, log) + checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, check.configurations, log) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) @@ -95,18 +96,17 @@ private[sbt] object IvyScala { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { + private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Seq[String], scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) def isScalaLangOrg = id.getOrganisation == scalaOrganization - def isNotScalaActorsMigration = !(id.getName startsWith "scala-actors-migration") // Exception to the rule: sbt/sbt#1818 - def isNotScalaPickling = !(id.getName startsWith "scala-pickling") // Exception to the rule: sbt/sbt#1899 + def isScalaArtifact = scalaArtifacts.contains(id.getName) def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion def matchesOneOfTheConfigs = dep.getModuleConfigurations.exists(configSet) - val mismatched = isScalaLangOrg && isNotScalaActorsMigration && isNotScalaPickling && hasBinVerMismatch && matchesOneOfTheConfigs + val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some("Binary version (" + depBinaryVersion + ") for dependency " + id + "\n\tin " + module.getModuleRevisionId + From a1f9b5ed64b4c71da47c11adc0b6df2fd7ee3bdc Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 22 Sep 2016 23:47:05 +0200 Subject: [PATCH 0531/1030] Change bintray repo, see sbt #1696 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index ab16fd295..b46e2d6ac 100644 --- a/build.sbt +++ b/build.sbt @@ -9,7 +9,7 @@ def commonSettings: Seq[Setting[_]] = Seq( // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), - resolvers += Resolver.bintrayRepo("sbt", "maven-releases"), + resolvers += "bintray-typesafe-maven-releases" at "https://dl.bintray.com/typesafe/maven-releases/", // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), From 3cb3d8d221791b7b2cf0baac9027c5f5318e2399 Mon Sep 17 00:00:00 2001 From: James Roper Date: Thu, 29 Sep 2016 19:38:22 +1000 Subject: [PATCH 0532/1030] Log resolving messages at debug level For great justice. --- .../internal/librarymanagement/ivyint/SbtChainResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index df397f354..afc5bda12 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -72,7 +72,7 @@ private[sbt] case class SbtChainResolver( override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { if (data.getOptions.getLog != LogOptions.LOG_QUIET) - Message.info("Resolving " + dd.getDependencyRevisionId + " ...") + Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") val gd = doGetDependency(dd, data) val mod = IvySbt.resetArtifactResolver(gd) mod From bc7ed0d784d8cf1624b132ac8591cdde1808e254 Mon Sep 17 00:00:00 2001 From: cunei Date: Fri, 7 Oct 2016 13:36:32 -0500 Subject: [PATCH 0533/1030] Fix to bintray repo (#53) --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index b46e2d6ac..ce55ca467 100644 --- a/build.sbt +++ b/build.sbt @@ -9,7 +9,7 @@ def commonSettings: Seq[Setting[_]] = Seq( // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), - resolvers += "bintray-typesafe-maven-releases" at "https://dl.bintray.com/typesafe/maven-releases/", + resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), From 8c4a969c9a17a219cacc9da75e2d9e6bebd0e55c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 27 Oct 2016 13:35:29 +0100 Subject: [PATCH 0534/1030] Add props to define source dependencies on io & util Use either -Dsbtio.path / -Dsbtutil.path on the command line or sbtio.path= / sbtutil.path= in project/local.properties --- build.sbt | 6 +++--- project/Dependencies.scala | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index ce55ca467..0f38b6bde 100644 --- a/build.sbt +++ b/build.sbt @@ -47,11 +47,11 @@ lazy val lm = (project in file("librarymanagement")). commonSettings, name := "librarymanagement", libraryDependencies ++= Seq( - utilLogging, sbtIO, utilTesting % Test, - utilCollection, utilCompletion, ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), + ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, binaryIssueFilters ++= Seq() - ) + ). + configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8bd5bf78c..8232a3c7e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,11 +6,39 @@ object Dependencies { val ioVersion = "1.0.0-M6" val utilVersion = "0.1.0-M13" - lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion - lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion - lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion - lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion + + private lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion + + private lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion + private lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion + private lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion + private lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion + private lazy val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion + + def getSbtModulePath(key: String, name: String) = { + val localProps = new java.util.Properties() + IO.load(localProps, file("project/local.properties")) + val path = Option(localProps getProperty key) orElse (sys.props get key) + path foreach (f => println(s"Using $name from $f")) + path + } + + lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io") + lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util") + + def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID, c: Option[Configuration] = None) = + path match { + case Some(f) => p dependsOn c.fold[ClasspathDependency](ProjectRef(file(f), projectName))(ProjectRef(file(f), projectName) % _) + case None => p settings (libraryDependencies += c.fold(m)(m % _)) + } + + def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) + + def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) + def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) + def addSbtUtilTesting(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) + def addSbtUtilCompletion(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) + def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" From f2efa10af1ead99b830edc01caf3b9b1be7e0d15 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 2 Nov 2016 15:22:55 +0000 Subject: [PATCH 0535/1030] Switch to sbt-datatype, sjson-new & Vectors --- build.sbt | 12 +- .../src/main/datatype/librarymanagement.json | 780 ++++++++++++++++++ .../librarymanagement/ConvertResolver.scala | 16 +- .../sbt/internal/librarymanagement/Ivy.scala | 29 +- .../librarymanagement/IvyActions.scala | 80 +- .../internal/librarymanagement/IvyCache.scala | 44 +- .../librarymanagement/IvyConfigurations.scala | 199 +---- .../librarymanagement/IvyRetrieve.scala | 22 +- .../internal/librarymanagement/JsonUtil.scala | 26 +- .../librarymanagement/RichUpdateReport.scala | 21 +- .../librarymanagement/SbtExclusionRule.scala | 52 -- .../formats/DateFormat.scala | 11 + .../formats/DependencyResolverFormat.scala | 12 + .../formats/Function1Format.scala | 8 + .../formats/GlobalLockFormat.scala | 9 + .../formats/LoggerFormat.scala | 9 + .../formats/MyCrazyReferences.scala | 15 + .../formats/NodeSeqFormat.scala | 9 + .../formats/UpdateOptionsFormat.scala | 27 + .../impl/DependencyBuilders.scala | 4 +- .../CachedResolutionResolveEngine.scala | 35 +- .../sbt/librarymanagement/Artifact.scala | 113 +-- .../sbt/librarymanagement/Configuration.scala | 20 +- .../sbt/librarymanagement/CrossVersion.scala | 90 +- .../librarymanagement/EvictionWarning.scala | 4 +- .../sbt/librarymanagement/IvyInterface.scala | 58 +- .../sbt/librarymanagement/IvyScala.scala | 12 +- .../sbt/librarymanagement/ModuleID.scala | 48 +- .../sbt/librarymanagement/Resolver.scala | 160 +--- .../sbt/librarymanagement/UpdateReport.scala | 254 ++---- .../scala/sbt/librarymanagement/package.scala | 2 +- .../src/test/scala/BaseIvySpecification.scala | 40 +- .../src/test/scala/CachedResolutionSpec.scala | 22 +- .../src/test/scala/CrossVersionTest.scala | 2 +- .../src/test/scala/CustomPomParserTest.scala | 4 +- .../src/test/scala/DMSerializationSpec.scala | 26 +- .../src/test/scala/EvictionWarningSpec.scala | 46 +- .../scala/InconsistentDuplicateSpec.scala | 6 +- .../src/test/scala/ResolverTest.scala | 4 +- .../FakeResolverSpecification.scala | 14 +- .../librarymanagement/IvyRepoSpec.scala | 14 +- project/DatatypeConfig.scala | 61 ++ project/Dependencies.scala | 14 +- project/build.properties | 2 +- project/sbt-datatype.sbt | 1 + 45 files changed, 1372 insertions(+), 1065 deletions(-) create mode 100644 librarymanagement/src/main/datatype/librarymanagement.json delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala create mode 100644 project/DatatypeConfig.scala create mode 100644 project/sbt-datatype.sbt diff --git a/build.sbt b/build.sbt index 0f38b6bde..9f0c79fb4 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,6 @@ def commonSettings: Seq[Setting[_]] = Seq( crossScalaVersions := Seq(scala211), resolvers += Resolver.sonatypeRepo("public"), scalacOptions += "-Ywarn-unused", - scalacOptions += "-Ywarn-unused-import", previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false @@ -47,11 +46,14 @@ lazy val lm = (project in file("librarymanagement")). commonSettings, name := "librarymanagement", libraryDependencies ++= Seq( - ivy, jsch, sbtSerialization, scalaReflect.value, launcherInterface), - resourceGenerators in Compile <+= (version, resourceManaged, streams, compile in Compile) map Util.generateVersionFile, - binaryIssueFilters ++= Seq() + ivy, jsch, scalaReflect.value, launcherInterface, sjsonnewScalaJson % Optional), + libraryDependencies ++= scalaXml.value, + resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue, + binaryIssueFilters ++= Seq(), + datatypeFormatsForType in generateDatatypes in Compile := DatatypeConfig.getFormats ). - configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion) + configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache). + enablePlugins(DatatypePlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json new file mode 100644 index 000000000..102b22748 --- /dev/null +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -0,0 +1,780 @@ +{ + "codecNamespace": "sbt.librarymanagement", + "fullCodec": "LibraryManagementCodec", + "types": [ + { + "name": "Caller", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "caller", "type": "sbt.librarymanagement.ModuleID" }, + { "name": "callerConfigurations", "type": "String*" }, + { "name": "callerExtraAttributes", "type": "Map[String, String]" }, + { "name": "isForceDependency", "type": "boolean" }, + { "name": "isChangingDependency", "type": "boolean" }, + { "name": "isTransitiveDependency", "type": "boolean" }, + { "name": "isDirectlyForceDependency", "type": "boolean" } + ], + "toString": "s\"$caller\"" + }, + { + "name": "ModuleReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Provides information about the resolution of a module.", + "This information is in the context of a specific configuration." + ], + "parents": "sbt.librarymanagement.ModuleReportParent", + "fields": [ + { "name": "module", "type": "sbt.librarymanagement.ModuleID" }, + { "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*" }, + { "name": "missingArtifacts", "type": "sbt.librarymanagement.Artifact*" }, + { "name": "status", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "publicationDate", "type": "java.util.Date?", "default": "None", "since": "0.0.1" }, + { "name": "resolver", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "artifactResolver", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "evicted", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "evictedData", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "evictedReason", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "problem", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "homepage", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, + { "name": "isDefault", "type": "boolean?", "default": "None", "since": "0.0.1" }, + { "name": "branch", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, Option[String]]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "callers", "type": "sbt.librarymanagement.Caller*", "default": "Vector.empty", "since": "0.0.1" } + ], + "toString": [ + "s\"\\t\\t$module: \" +", + "(if (arts.size <= 1) \"\" else \"\\n\\t\\t\\t\") + arts.mkString(\"\\n\\t\\t\\t\") + \"\\n\"" + ] + }, + { + "name": "OrganizationArtifactReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.", + "In sbt's terminology, \"module\" consists of organization, name, and version.", + "In Ivy's, \"module\" means just organization and name, and the one including version numbers", + "are called revisions.", + "", + "A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.", + "(Note old evicted was just a seq of ModuleIDs).", + "OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,", + "which can be used to calculate detailed eviction warning etc." + ], + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" } + ] + }, + { + "name": "UpdateStats", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "resolveTime", "type": "long" }, + { "name": "downloadTime", "type": "long" }, + { "name": "downloadSize", "type": "long" }, + { "name": "cached", "type": "boolean" } + ], + "toString": "Seq(\"Resolve time: \" + resolveTime + \" ms\", \"Download time: \" + downloadTime + \" ms\", \"Download size: \" + downloadSize + \" bytes\").mkString(\", \")" + }, + { + "name": "UpdateLogging", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "enumeration", + "doc": [ + "Configures logging during an 'update'. `level` determines the amount of other information logged.", + "`Full` is the default and logs the most.", + "`DownloadOnly` only logs what is downloaded.", + "`Quiet` only displays errors.", + "`Default` uses the current log level of `update` task." + ], + "symbols": [ "Full", "DownloadOnly", "Quiet", "Default" ] + }, + { + "name": "RetrieveConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "retrieveDirectory", "type": "java.io.File" }, + { "name": "outputPattern", "type": "String" }, + { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "configurationsToRetrieve", "type": "Set[sbt.librarymanagement.Configuration]?", "default": "None", "since": "0.0.1" } + ] + }, + { + "name": "UpdateConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" }, + { "name": "missingOk", "type": "boolean" }, + { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, + { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" } + ] + }, + { + "name": "ScmInfo", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Basic SCM information for a project module", + "fields": [ + { "name": "browseUrl", "type": "java.net.URL" }, + { "name": "connection", "type": "String" }, + { "name": "devConnection", "type": "String?" } + ] + }, + { + "name": "Developer", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "id", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "email", "type": "String" }, + { "name": "url", "type": "java.net.URL" } + ] + }, + { + "name": "SbtExclusionRule", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "artifact", "type": "String" }, + { "name": "configurations", "type": "String*" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" } + ] + }, + { + "name": "ModuleInfo", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Additional information about a project module", + "fields": [ + { "name": "nameFormal", "type": "String" }, + { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "homepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "startYear", "type": "int?", "default": "None", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "scmInfo", "type": "sbt.librarymanagement.ScmInfo?", "default": "None", "since": "0.0.1" }, + { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } + ] + }, + { + "name": "ConflictManager", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "module", "type": "String", "default": "\"*\"", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.ConflictManagerCompanion" + }, + { + "name": "IvyScala", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "scalaFullVersion", "type": "String" }, + { "name": "scalaBinaryVersion", "type": "String" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, + { "name": "checkExplicit", "type": "boolean" }, + { "name": "filterImplicit", "type": "boolean" }, + { "name": "overrideScalaVersion", "type": "boolean" }, + { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, + { "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.IvyScalaCompanion" + }, + { + "name": "ModuleSettings", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "fields": [ + { "name": "validate", "type": "boolean" }, + { "name": "ivyScala", "type": "sbt.librarymanagement.IvyScala?" } + ], + "types": [ + { + "name": "IvyFileConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "file", "type": "java.io.File" }, + { "name": "autoScalaTools", "type": "boolean" } + ] + }, + { + "name": "PomConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "file", "type": "java.io.File" }, + { "name": "autoScalaTools", "type": "boolean" } + ] + }, + { + "name": "InlineConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "module", "type": "sbt.librarymanagement.ModuleID" }, + { "name": "moduleInfo", "type": "sbt.librarymanagement.ModuleInfo" }, + { "name": "dependencies", "type": "sbt.librarymanagement.ModuleID*" }, + { "name": "overrides", "type": "Set[sbt.librarymanagement.ModuleID]", "default": "Set.empty", "since": "0.0.1" }, + { "name": "excludes", "type": "sbt.internal.librarymanagement.SbtExclusionRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "defaultConfiguration", "type": "sbt.librarymanagement.Configuration?", "default": "None", "since": "0.0.1" }, + { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationCompanion" + } + ] + }, + { + "name": "IvyPaths", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "baseDirectory", "type": "java.io.File" }, + { "name": "ivyHome", "type": "java.io.File?" } + ] + }, + { + "name": "InclExclRule", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Rule to either:", + "
    ", + "
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • ", + "
  • include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
  • ", + "
", + "Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases." + ], + "fields": [ + { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.InclExclRuleCompanion" + }, + { + "name": "CrossVersion", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "doc": "Configures how a module will be cross-versioned.", + "types": [ + { + "name": "Disabled", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": "Disables cross versioning for a module.", + "type": "record" + }, + { + "name": "Binary", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": [ + "Cross-versions a module using the result of applying `remapVersion` to the binary version.", + "For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",", + "the module is cross-versioned with \"2.10\"." + ], + "type": "record", + "fields": [ + { "name": "remapVersion", "type": "Function1[String, String]" } + ] + }, + { + "name": "Full", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Cross-versions a module with the result of applying `remapVersion` to the full version.", + "For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",", + "the module is cross-versioned with \"2.10\"." + ], + "fields": [ + { "name": "remapVersion", "type": "Function1[String, String]" } + ] + } + ], + "parentsCompanion": "sbt.librarymanagement.CrossVersionCompanion" + }, + { + "name": "Configuration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Represents an Ivy configuration.", + "parents": "sbt.librarymanagement.ConfigurationParent", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" } + ], + "toString": "name" + }, + { + "name": "Artifact", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "parents": "sbt.librarymanagement.ArtifactParent", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, + { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, + { "name": "classifier", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.ArtifactCompanion" + }, + { + "name": "SshAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "types": [ + { + "name": "PasswordAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "user", "type": "String" }, + { "name": "password", "type": "String?" } + ] + }, + { + "name": "KeyFileAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "user", "type": "String" }, + { "name": "keyfile", "type": "java.io.File" }, + { "name": "password", "type": "String?" } + ] + } + ] + }, + { + "name": "SshConnection", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "authentication", "type": "sbt.librarymanagement.SshAuthentication?" }, + { "name": "hostname", "type": "String?" }, + { "name": "port", "type": "int?" } + ] + }, + { + "name": "FileConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Configuration specific to an Ivy filesystem resolver.", + "fields": [ + { "name": "isLocal", "type": "boolean" }, + { "name": "isTransactional", "type": "boolean?" } + ] + }, + { + "name": "Patterns", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "ivyPatterns", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "artifactPatterns", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "isMavenCompatible", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "descriptorOptional", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "skipConsistencyCheck", "type": "boolean", "default": "false", "since": "0.0.1" } + ], + "toString": [ + "\"Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)\".format(", + " ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck)" + ], + "parentsCompanion": "sbt.librarymanagement.PatternsCompanion" + }, + { + "name": "Resolver", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "fields": [ + { "name": "name", "type": "String" } + ], + "types": [ + { + "name": "ChainedResolver", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" } + ] + }, + { + "name": "IMavenRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "doc": "An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts.", + "fields": [ + { "name": "root", "type": "String" }, + { "name": "localIfFile", "type": "boolean", "default": "true", "since": "0.0.1" } + ], + "types": [ + { + "name": "MavenRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "toString": "s\"$name: $root\"" + }, + { + "name": "MavenCache", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because", + "the metadata is different (see Aether ML discussion)." + ], + "fields": [ + { "name": "rootFile", "type": "java.io.File" } + ], + "extra": "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)", + "toString": "s\"cache:$name: ${rootFile.getAbsolutePath}\"", + "extraCompanion": "def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile)" + } + ] + }, + { + "name": "PatternsBasedRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "fields": [ + { "name": "patterns", "type": "sbt.librarymanagement.Patterns" } + ], + "doc": "sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.", + "types": [ + { + "name": "FileRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file.", + "fields": [ + { "name": "configuration", "type": "sbt.librarymanagement.FileConfiguration" } + ], + "extra": [ + "def this(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = ", + " this(name, patterns, configuration)" + ], + "extraCompanion": [ + "def apply(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = ", + " new FileRepository(name, patterns, configuration)" + ] + }, + { + "name": "URLRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record" + }, + { + "name": "SshBasedRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "doc": "sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library..", + "fields": [ + { "name": "connection", "type": "sbt.librarymanagement.SshConnection" } + ], + "types": [ + { + "name": "SshRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh.", + "fields": [ + { "name": "publishPermissions", "type": "String?" } + ], + "extra": [ + "def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = ", + " this(name, patterns, connection, publishPermissions)" + ], + "extraCompanion": [ + "def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = ", + " new SshRepository(name, patterns, connection, publishPermissions)" + ] + }, + { + "name": "SftpRepository", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp.", + "extra": [ + "def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = ", + " this(name, patterns, connection)" + ], + "extraCompanion": [ + "def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = ", + " new SftpRepository(name, patterns, connection)" + ] + } + ] + } + ] + } + ], + "parentsCompanion": "sbt.librarymanagement.ResolverCompanion" + }, + { + "name": "ModuleConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "revision", "type": "String" }, + { "name": "resolver", "type": "sbt.librarymanagement.Resolver" } + ], + "extraCompanion": [ + "def apply(org: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = apply(org, \"*\", \"*\", resolver)", + "def apply(org: String, name: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = ModuleConfiguration(org, name, \"*\", resolver)" + ] + }, + { + "name": "IvyConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "interface", + "fields": [ + { "name": "lock", "type": "xsbti.GlobalLock?" }, + { "name": "baseDirectory", "type": "java.io.File" }, + { "name": "log", "type": "xsbti.Logger" }, + { "name": "updateOptions", "type": "sbt.librarymanagement.UpdateOptions" } + ], + "types": [ + { + "name": "InlineIvyConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "paths", "type": "sbt.internal.librarymanagement.IvyPaths" }, + { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" }, + { "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" }, + { "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" }, + { "name": "localOnly", "type": "boolean" }, + { "name": "checksums", "type": "String*" }, + { "name": "resolutionCacheDir", "type": "java.io.File?" } + ], + "extra": [ + "def this(", + " paths: sbt.internal.librarymanagement.IvyPaths,", + " resolvers: Vector[sbt.librarymanagement.Resolver],", + " otherResolvers: Vector[sbt.librarymanagement.Resolver],", + " moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],", + " localOnly: Boolean,", + " lock: Option[xsbti.GlobalLock],", + " checksums: Vector[String],", + " resolutionCacheDir: Option[java.io.File],", + " updateOptions: sbt.librarymanagement.UpdateOptions,", + " log: xsbti.Logger", + ") =", + " this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,", + " moduleConfigurations, localOnly, checksums, resolutionCacheDir)" + ] + }, + { + "name": "ExternalIvyConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "uri", "type": "java.net.URI" }, + { "name": "extraResolvers", "type": "sbt.librarymanagement.Resolver*" } + ] + } + ] + }, + { + "name": "UpdateReportLite", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "configurations", "type": "sbt.internal.librarymanagement.ConfigurationReportLite*" } + ] + }, + { + "name": "ConfigurationReportLite", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "configuration", "type": "String" }, + { "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" } + ] + }, + { + "name": "ModuleID", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "parents": "sbt.librarymanagement.ModuleIDParent", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "revision", "type": "String" }, + { "name": "configurations", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, + { "name": "branchName", "type": "String?", "default": "None", "since": "0.0.1" } + ], + "toString": [ + "organization + \":\" + name + \":\" + revision +", + " (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +", + " (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)" + ], + "parentsCompanion": "sbt.librarymanagement.ModuleIDCompanion" + }, + { + "name": "ArtifactTypeFilter", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)", + "parents": "sbt.librarymanagement.ArtifactTypeFilterParent", + "fields": [ + { + "name": "types", + "doc": [ + "Represents the artifact types that we should try to resolve for (as in the allowed values of", + "`artifact[type]` from a dependency `` section). One can use this to filter", + "source / doc artifacts." + ], + "type": "Set[String]" + }, + { + "name": "inverted", + "doc": [ "Whether to invert the types filter (i.e. allow only types NOT in the set)" ], + "type": "boolean" + } + ], + "parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterCompanion" + }, + { + "name": "UpdateReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Provides information about dependency resolution.", + "It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.", + "This means that for a given configuration, there should only be one revision for a given organization and module name." + ], + "parents": "sbt.librarymanagement.UpdateReportParent", + "fields": [ + { + "name": "cachedDescriptor", + "type": "java.io.File", + "doc": [ "the location of the resolved module descriptor in the cache" ] + }, + { + "name": "configurations", + "type": "sbt.librarymanagement.ConfigurationReport*", + "doc": [ "a sequence containing one report for each configuration resolved." ] + }, + { + "name": "stats", + "type": "sbt.librarymanagement.UpdateStats", + "doc": [ "stats information about the update that produced this report" ] + }, + { "name": "stamps", "type": "Map[java.io.File, Long]" } + ], + "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" + }, + { + "name": "ConfigurationReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Provides information about resolution of a single configuration." + ], + "parents": "sbt.librarymanagement.ConfigurationReportParent", + "fields": [ + { "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] }, + { + "name": "modules", + "type": "sbt.librarymanagement.ModuleReport*", + "doc": [ + "a sequence containing one report for each module resolved for this configuration." + ] + }, + { + "name": "details", + "type": "sbt.librarymanagement.OrganizationArtifactReport*", + "doc": [ "a sequence containing one report for each org/name, which may or may not be part of the final resolution." ] + } + ] + } + ] +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 1d0a6a470..a1d67b99c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -195,20 +195,20 @@ private[sbt] object ConvertResolver { initializePatterns(resolver, repo.patterns, settings) initializeConnection(resolver, repo.connection) } - private def initializeConnection(resolver: AbstractSshBasedResolver, connection: RepositoryHelpers.SshConnection): Unit = { + private def initializeConnection(resolver: AbstractSshBasedResolver, connection: SshConnection): Unit = { import resolver._ import connection._ hostname.foreach(setHost) port.foreach(setPort) authentication foreach { - case RepositoryHelpers.PasswordAuthentication(user, password) => - setUser(user) - password.foreach(setUserPassword) - case RepositoryHelpers.KeyFileAuthentication(user, file, password) => - setKeyFile(file) - password.foreach(setKeyFilePassword) - setUser(user) + case pa: PasswordAuthentication => + setUser(pa.user) + pa.password.foreach(setUserPassword) + case kfa: KeyFileAuthentication => + setKeyFile(kfa.keyfile) + kfa.password.foreach(setKeyFilePassword) + setUser(kfa.user) } } private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings): Unit = { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 29e8b0b42..320f549a0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -30,8 +30,9 @@ import sbt.util.Logger import sbt.librarymanagement._ import Resolver.PluginPattern import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } +import sbt.internal.util.CacheStore -final class IvySbt(val configuration: IvyConfiguration) { +final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => CacheStore) { self => import configuration.baseDirectory /* @@ -92,7 +93,8 @@ final class IvySbt(val configuration: IvyConfiguration) { setEventManager(new EventManager()) if (configuration.updateOptions.cachedResolution) { setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine { - val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache + override private[sbt] val fileToStore: File => CacheStore = self.fileToStore + val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache(fileToStore) val projectResolver = prOpt def makeInstance = mkIvy }) @@ -139,7 +141,7 @@ final class IvySbt(val configuration: IvyConfiguration) { withIvy(log) { i => val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } if (configuration.updateOptions.cachedResolution) { - IvySbt.cachedResolutionResolveCache.clean(md, prOpt) + IvySbt.cachedResolutionResolveCache(fileToStore).clean(md, prOpt) } } @@ -236,8 +238,8 @@ private[sbt] object IvySbt { val DefaultIvyConfigFilename = "ivysettings.xml" val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" - val DefaultChecksums = Seq("sha1", "md5") - private[sbt] val cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache() + val DefaultChecksums = Vector("sha1", "md5") + private[sbt] def cachedResolutionResolveCache(fileToStore: File => CacheStore): CachedResolutionResolveCache = new CachedResolutionResolveCache(fileToStore) def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) @@ -305,8 +307,8 @@ private[sbt] object IvySbt { */ def hasImplicitClassifier(artifact: IArtifact): Boolean = { - import collection.JavaConversions._ - artifact.getQualifiedExtraAttributes.keys.exists(_.asInstanceOf[String] startsWith "m:") + import scala.collection.JavaConverters._ + artifact.getQualifiedExtraAttributes.asScala.keys.exists(_.asInstanceOf[String] startsWith "m:") } private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger): Unit = { val existing = settings.getResolverNames @@ -426,7 +428,7 @@ private[sbt] object IvySbt { { val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { - case ic: InlineConfiguration => ic.copy(module = sub(ic.module), dependencies = ic.dependencies map sub, overrides = ic.overrides map sub) + case ic: InlineConfiguration => ic.withModule(sub(ic.module)).withDependencies(ic.dependencies map sub).withOverrides(ic.overrides map sub) case _ => m } } @@ -439,7 +441,7 @@ private[sbt] object IvySbt { } def getExtraAttributes(revID: ExtendableItem): Map[String, String] = { - import collection.JavaConverters._ + import scala.collection.JavaConverters._ revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = @@ -449,8 +451,9 @@ private[sbt] object IvySbt { } private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { + import scala.collection.JavaConverters._ val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m - if (map.isEmpty) null else scala.collection.JavaConversions.mapAsJavaMap(map) + if (map.isEmpty) null else map.asJava } /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ @@ -514,7 +517,7 @@ private[sbt] object IvySbt { val dds = moduleID.getDependencies val deps = dds flatMap { dd => val module = toModuleID(dd.getDependencyRevisionId) - dd.getModuleConfigurations map (c => module.copy(configurations = Some(c))) + dd.getModuleConfigurations map (c => module.withConfigurations(Some(c))) } inconsistentDuplicateWarning(deps) } @@ -571,7 +574,7 @@ private[sbt] object IvySbt { deps.put(id, updated) } - import collection.JavaConverters._ + import scala.collection.JavaConverters._ deps.values.asScala.toSeq.flatMap { dds => val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _) if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds @@ -652,7 +655,7 @@ private[sbt] object IvySbt { val overridden = overrides.map(id => (key(id), id.revision)).toMap dependencies map { dep => overridden get key(dep) match { - case Some(rev) => dep.copy(revision = rev) + case Some(rev) => dep.withRevision(rev) case None => dep } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index d87001653..13a5d040b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -21,36 +21,19 @@ import sbt.util.Logger import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } import sbt.librarymanagement._ import sbt.internal.librarymanagement.syntax._ +import sbt.internal.librarymanagement._ -final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Seq[Configuration]], val logging: UpdateLogging.Value) -final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Seq[String], val logging: UpdateLogging.Value, +final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Vector[Configuration]], val logging: UpdateLogging) +final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Vector[String], val logging: UpdateLogging, val overwrite: Boolean) { - def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Seq[String], logging: UpdateLogging.Value) = + def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Vector[String], logging: UpdateLogging) = this(ivyFile, resolverName, artifacts, checksums, logging, false) } -final class UpdateConfiguration(val retrieve: Option[RetrieveConfiguration], val missingOk: Boolean, val logging: UpdateLogging.Value, val artifactFilter: ArtifactTypeFilter) { - @deprecated("You should use the constructor that provides an artifactFilter", "1.0.x") - def this(retrieve: Option[RetrieveConfiguration], missingOk: Boolean, logging: UpdateLogging.Value) { - this(retrieve, missingOk, logging, ArtifactTypeFilter.forbid(Set("src", "doc"))) // allow everything but "src", "doc" by default - } - - private[sbt] def copy( - retrieve: Option[RetrieveConfiguration] = this.retrieve, - missingOk: Boolean = this.missingOk, - logging: UpdateLogging.Value = this.logging, - artifactFilter: ArtifactTypeFilter = this.artifactFilter - ): UpdateConfiguration = - new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter) -} -final class RetrieveConfiguration(val retrieveDirectory: File, val outputPattern: String, val sync: Boolean, val configurationsToRetrieve: Option[Set[Configuration]]) { - def this(retrieveDirectory: File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) - def this(retrieveDirectory: File, outputPattern: String, sync: Boolean) = this(retrieveDirectory, outputPattern, sync, None) -} -final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Seq[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) +final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Vector[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) /** @param exclude is a map from ModuleID to classifiers that were previously tried and failed, so should now be excluded */ final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], sourceArtifactTypes: Set[String], docArtifactTypes: Set[String]) -final case class GetClassifiersModule(id: ModuleID, modules: Seq[ModuleID], configurations: Seq[Configuration], classifiers: Seq[String]) +final case class GetClassifiersModule(id: ModuleID, modules: Vector[ModuleID], configurations: Vector[Configuration], classifiers: Vector[String]) final class UnresolvedWarningConfiguration private[sbt] ( val modulePositions: Map[ModuleID, SourcePosition] @@ -61,17 +44,6 @@ object UnresolvedWarningConfiguration { new UnresolvedWarningConfiguration(modulePositions) } -/** - * Configures logging during an 'update'. `level` determines the amount of other information logged. - * `Full` is the default and logs the most. - * `DownloadOnly` only logs what is downloaded. - * `Quiet` only displays errors. - * `Default` uses the current log level of `update` task. - */ -object UpdateLogging extends Enumeration { - val Full, DownloadOnly, Quiet, Default = Value -} - object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { @@ -133,13 +105,13 @@ object IvyActions { if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toSeq + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } } } - private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Seq[String])(act: => T): T = + private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])(act: => T): T = resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act } - private[this] def withChecksums[T](resolver: BasicResolver, checksums: Seq[String])(act: => T): T = + private[this] def withChecksums[T](resolver: BasicResolver, checksums: Vector[String])(act: => T): T = { val previous = resolver.getChecksumAlgorithms resolver.setChecksums(checksums mkString ",") @@ -151,9 +123,9 @@ object IvyActions { case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) case _ => None } - def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Seq[(IArtifact, File)] = + def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Vector[(IArtifact, File)] = { - val rawa = artifacts.keys.toSeq + val rawa = artifacts.keys.toVector val seqa = CrossVersion.substituteCross(rawa, cross) val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } @@ -235,8 +207,8 @@ object IvyActions { { import config.{ configuration => c, ivyScala, module => mod } import mod.{ id, modules => deps } - val base = restrictedCopy(id, true).copy(name = id.name + "$" + label) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala)) + val base = restrictedCopy(id, true).withName(id.name + "$" + label) + val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps)) val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { case Right(r) => r case Left(w) => @@ -270,10 +242,10 @@ object IvyActions { val baseModules = modules map { m => restrictedCopy(m, true) } // Adding list of explicit artifacts here. val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) - val base = restrictedCopy(id, true).copy(name = id.name + classifiers.mkString("$", "_", "")) - val module = new ivySbt.Module(InlineConfiguration(base, ModuleInfo(base.name), deps).copy(ivyScala = ivyScala, configurations = confs)) + val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", "")) + val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps).withConfigurations(confs)) // c.copy ensures c.types is preserved too - val upConf = c.copy(missingOk = true) + val upConf = c.withMissingOk(true) updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { case Right(r) => // The artifacts that came from Ivy don't have their classifier set, let's set it according to @@ -285,7 +257,7 @@ object IvyActions { artFileSeq map { case (art, f) => // Deduce the classifier from the type if no classifier is present already - art.copy(classifier = art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f } } case Left(w) => @@ -294,7 +266,7 @@ object IvyActions { } // This version adds explicit artifact private[sbt] def classifiedArtifacts( - classifiers: Seq[String], + classifiers: Vector[String], exclude: Map[ModuleID, Set[String]], artifacts: Vector[(String, ModuleID, Artifact, File)] )(m: ModuleID): Option[ModuleID] = { @@ -308,7 +280,7 @@ object IvyActions { def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) explicitArtifacts orElse hardcodedArtifacts } - private def classifiedArtifacts(classifiers: Seq[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = + private def classifiedArtifacts(classifiers: Vector[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = { val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) val included = classifiers filterNot excluded @@ -330,12 +302,12 @@ object IvyActions { * }}} * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. */ - private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Seq[Artifact]): ModuleID = - module.copy(isTransitive = false, explicitArtifacts = arts, inclusions = InclExclRule.everything :: Nil) + private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Vector[Artifact]): ModuleID = + module.withIsTransitive(false).withExplicitArtifacts(arts).withInclusions(Vector(InclExclRule.everything)) - def addExcluded(report: UpdateReport, classifiers: Seq[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = + def addExcluded(report: UpdateReport, classifiers: Vector[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } - def classifiedArtifacts(name: String, classifiers: Seq[String]): Seq[Artifact] = + def classifiedArtifacts(name: String, classifiers: Vector[String]): Vector[Artifact] = classifiers map { c => Artifact.classified(name, c) } private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) @@ -344,10 +316,10 @@ object IvyActions { report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision, crossVersion = m.crossVersion, extraAttributes = m.extraAttributes, configurations = if (confs) m.configurations else None) + ModuleID(m.organization, m.name, m.revision).withCrossVersion(m.crossVersion).withExtraAttributes(m.extraAttributes).withConfigurations(if (confs) m.configurations else None) .branch(m.branchName) - private[this] def resolve(logging: UpdateLogging.Value)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) = + private[this] def resolve(logging: UpdateLogging)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) = { val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(module) @@ -420,7 +392,7 @@ object IvyActions { import UpdateLogging.{ Quiet, Full, DownloadOnly, Default } import LogOptions.{ LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY } - private def ivyLogLevel(level: UpdateLogging.Value) = + private def ivyLogLevel(level: UpdateLogging) = level match { case Quiet => LOG_QUIET case DownloadOnly => LOG_DOWNLOAD_ONLY diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index ba3d97912..0c1c1f969 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -15,6 +15,14 @@ import sbt.io.Path import sbt.util.Logger import sbt.librarymanagement._ +import sbt.internal.util.{ CacheStore, FileBasedStore } + +import scala.json.ast.unsafe._ +import scala.collection.mutable +import jawn.{ SupportParser, MutableFacade } +import sjsonnew.IsoString +import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } + class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { def this(id: ModuleID) = this(id, null) @@ -27,7 +35,9 @@ private object NotInCache { } } /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ -class IvyCache(val ivyHome: Option[File]) { +class IvyCache(val ivyHome: Option[File], fileToStore: File => CacheStore) { + def this(ivyHome: Option[File]) = this(ivyHome, DefaultFileToStore) + def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { @@ -81,8 +91,8 @@ class IvyCache(val ivyHome: Option[File]) { { val local = Resolver.defaultLocal val paths = new IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) - (new IvySbt(conf), local) + val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) + (new IvySbt(conf, fileToStore), local) } /** Creates a default jar artifact based on the given ID.*/ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = @@ -98,3 +108,31 @@ private class FileDownloader extends ResourceDownloader { sys.error("Could not move temporary file " + part + " to final location " + dest) } } + +object FixedParser extends SupportParser[JValue] { + implicit val facade: MutableFacade[JValue] = + new MutableFacade[JValue] { + def jnull() = JNull + def jfalse() = JFalse + def jtrue() = JTrue + def jnum(s: String) = JNumber(s) + def jint(s: String) = JNumber(s) + def jstring(s: String) = JString(s) + def jarray(vs: mutable.ArrayBuffer[JValue]) = JArray(vs.toArray) + def jobject(vs: mutable.Map[String, JValue]) = { + val array = new Array[JField](vs.size) + var i = 0 + vs.foreach { + case (key, value) => + array(i) = JField(key, value) + i += 1 + } + JObject(array) + } + } +} + +object DefaultFileToStore extends (File => CacheStore) { + private implicit lazy val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply _, FixedParser.parseUnsafe _) + override def apply(f: File): CacheStore = new FileBasedStore(f, Converter) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 7602f0de9..96cdf1585 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -3,206 +3,9 @@ */ package sbt.internal.librarymanagement -import java.io.File -import java.net.URI -import scala.xml.NodeSeq -import sbt.util.Logger import sbt.librarymanagement._ -final class IvyPaths(val baseDirectory: File, val ivyHome: Option[File]) { - def withBase(newBaseDirectory: File) = new IvyPaths(newBaseDirectory, ivyHome) - override def toString = s"IvyPaths($baseDirectory, $ivyHome)" -} -sealed trait IvyConfiguration { - type This <: IvyConfiguration - def lock: Option[xsbti.GlobalLock] - def baseDirectory: File - def log: Logger - def withBase(newBaseDirectory: File): This - def updateOptions: UpdateOptions -} -final class InlineIvyConfiguration(val paths: IvyPaths, val resolvers: Seq[Resolver], val otherResolvers: Seq[Resolver], - val moduleConfigurations: Seq[ModuleConfiguration], val localOnly: Boolean, val lock: Option[xsbti.GlobalLock], - val checksums: Seq[String], val resolutionCacheDir: Option[File], val updateOptions: UpdateOptions, - val log: Logger) extends IvyConfiguration { - @deprecated("Use the variant that accepts resolutionCacheDir and updateOptions.", "0.13.0") - def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], - moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], - checksums: Seq[String], log: Logger) = - this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, None, UpdateOptions(), log) - - @deprecated("Use the variant that accepts updateOptions.", "0.13.6") - def this(paths: IvyPaths, resolvers: Seq[Resolver], otherResolvers: Seq[Resolver], - moduleConfigurations: Seq[ModuleConfiguration], localOnly: Boolean, lock: Option[xsbti.GlobalLock], - checksums: Seq[String], resolutionCacheDir: Option[File], log: Logger) = - this(paths, resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, resolutionCacheDir, UpdateOptions(), log) - - override def toString: String = s"InlineIvyConfiguration($paths, $resolvers, $otherResolvers, " + - s"$moduleConfigurations, $localOnly, $checksums, $resolutionCacheDir, $updateOptions)" - - type This = InlineIvyConfiguration - def baseDirectory = paths.baseDirectory - def withBase(newBase: File) = new InlineIvyConfiguration(paths.withBase(newBase), resolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, - resolutionCacheDir, updateOptions, log) - def changeResolvers(newResolvers: Seq[Resolver]) = new InlineIvyConfiguration(paths, newResolvers, otherResolvers, moduleConfigurations, localOnly, lock, checksums, - resolutionCacheDir, updateOptions, log) - - override def equals(o: Any): Boolean = o match { - case o: InlineIvyConfiguration => - this.paths == o.paths && - this.resolvers == o.resolvers && - this.otherResolvers == o.otherResolvers && - this.moduleConfigurations == o.moduleConfigurations && - this.localOnly == o.localOnly && - this.checksums == o.checksums && - this.resolutionCacheDir == o.resolutionCacheDir && - this.updateOptions == o.updateOptions - case _ => false - } - - override def hashCode: Int = - { - var hash = 1 - hash = hash * 31 + this.paths.## - hash = hash * 31 + this.resolvers.## - hash = hash * 31 + this.otherResolvers.## - hash = hash * 31 + this.moduleConfigurations.## - hash = hash * 31 + this.localOnly.## - hash = hash * 31 + this.checksums.## - hash = hash * 31 + this.resolutionCacheDir.## - hash = hash * 31 + this.updateOptions.## - hash - } -} -final class ExternalIvyConfiguration(val baseDirectory: File, val uri: URI, val lock: Option[xsbti.GlobalLock], - val extraResolvers: Seq[Resolver], val updateOptions: UpdateOptions, val log: Logger) extends IvyConfiguration { - @deprecated("Use the variant that accepts updateOptions.", "0.13.6") - def this(baseDirectory: File, uri: URI, lock: Option[xsbti.GlobalLock], extraResolvers: Seq[Resolver], log: Logger) = - this(baseDirectory, uri, lock, extraResolvers, UpdateOptions(), log) - - type This = ExternalIvyConfiguration - def withBase(newBase: File) = new ExternalIvyConfiguration(newBase, uri, lock, extraResolvers, UpdateOptions(), log) -} -object ExternalIvyConfiguration { - def apply(baseDirectory: File, file: File, lock: Option[xsbti.GlobalLock], log: Logger) = new ExternalIvyConfiguration(baseDirectory, file.toURI, lock, Nil, UpdateOptions(), log) -} - -object IvyConfiguration { - /** - * Called to configure Ivy when inline resolvers are not specified. - * This will configure Ivy with an 'ivy-settings.xml' file if there is one or else use default resolvers. - */ - @deprecated("Explicitly use either external or inline configuration.", "0.12.0") - def apply(paths: IvyPaths, lock: Option[xsbti.GlobalLock], localOnly: Boolean, checksums: Seq[String], log: Logger): IvyConfiguration = - { - log.debug("Autodetecting configuration.") - val defaultIvyConfigFile = IvySbt.defaultIvyConfiguration(paths.baseDirectory) - if (defaultIvyConfigFile.canRead) - ExternalIvyConfiguration(paths.baseDirectory, defaultIvyConfigFile, lock, log) - else - new InlineIvyConfiguration(paths, Resolver.withDefaultResolvers(Nil), Nil, Nil, localOnly, lock, checksums, None, log) - } -} - -sealed trait ModuleSettings { - def validate: Boolean - def ivyScala: Option[IvyScala] - def noScala: ModuleSettings -} -final case class IvyFileConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { - def noScala = copy(ivyScala = None) -} -final case class PomConfiguration(file: File, ivyScala: Option[IvyScala], validate: Boolean, autoScalaTools: Boolean = true) extends ModuleSettings { - def noScala = copy(ivyScala = None) -} - -final class InlineConfiguration private[sbt] ( - val module: ModuleID, - val moduleInfo: ModuleInfo, - val dependencies: Seq[ModuleID], - val overrides: Set[ModuleID], - val excludes: Seq[SbtExclusionRule], - val ivyXML: NodeSeq, - val configurations: Seq[Configuration], - val defaultConfiguration: Option[Configuration], - val ivyScala: Option[IvyScala], - val validate: Boolean, - val conflictManager: ConflictManager -) extends ModuleSettings { - def withConfigurations(configurations: Seq[Configuration]) = copy(configurations = configurations) - def noScala = copy(ivyScala = None) - def withOverrides(overrides: Set[ModuleID]): ModuleSettings = - copy(overrides = overrides) - - private[sbt] def copy( - module: ModuleID = this.module, - moduleInfo: ModuleInfo = this.moduleInfo, - dependencies: Seq[ModuleID] = this.dependencies, - overrides: Set[ModuleID] = this.overrides, - excludes: Seq[SbtExclusionRule] = this.excludes, - ivyXML: NodeSeq = this.ivyXML, - configurations: Seq[Configuration] = this.configurations, - defaultConfiguration: Option[Configuration] = this.defaultConfiguration, - ivyScala: Option[IvyScala] = this.ivyScala, - validate: Boolean = this.validate, - conflictManager: ConflictManager = this.conflictManager - ): InlineConfiguration = - InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML, - configurations, defaultConfiguration, ivyScala, validate, conflictManager) - - override def toString: String = - s"InlineConfiguration($module, $moduleInfo, $dependencies, $overrides, $excludes, " + - s"$ivyXML, $configurations, $defaultConfiguration, $ivyScala, $validate, $conflictManager)" - - override def equals(o: Any): Boolean = o match { - case o: InlineConfiguration => - this.module == o.module && - this.moduleInfo == o.moduleInfo && - this.dependencies == o.dependencies && - this.overrides == o.overrides && - this.excludes == o.excludes && - this.ivyXML == o.ivyXML && - this.configurations == o.configurations && - this.defaultConfiguration == o.defaultConfiguration && - this.ivyScala == o.ivyScala && - this.validate == o.validate && - this.conflictManager == o.conflictManager - case _ => false - } - - override def hashCode: Int = - { - var hash = 1 - hash = hash * 31 + this.module.## - hash = hash * 31 + this.dependencies.## - hash = hash * 31 + this.overrides.## - hash = hash * 31 + this.excludes.## - hash = hash * 31 + this.ivyXML.## - hash = hash * 31 + this.configurations.## - hash = hash * 31 + this.defaultConfiguration.## - hash = hash * 31 + this.ivyScala.## - hash = hash * 31 + this.validate.## - hash = hash * 31 + this.conflictManager.## - hash - } -} -object InlineConfiguration { - def apply( - module: ModuleID, - moduleInfo: ModuleInfo, - dependencies: Seq[ModuleID], - overrides: Set[ModuleID] = Set.empty, - excludes: Seq[SbtExclusionRule] = Nil, - ivyXML: NodeSeq = NodeSeq.Empty, - configurations: Seq[Configuration] = Nil, - defaultConfiguration: Option[Configuration] = None, - ivyScala: Option[IvyScala] = None, - validate: Boolean = false, - conflictManager: ConflictManager = ConflictManager.default - ): InlineConfiguration = - new InlineConfiguration(module, moduleInfo, dependencies, overrides, excludes, ivyXML, - configurations, defaultConfiguration, ivyScala, validate, conflictManager) - +abstract class InlineConfigurationCompanion { def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if (explicitConfigurations.isEmpty) { defaultConfiguration match { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index b9917e1ad..6f0a7d42e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -17,10 +17,10 @@ import sbt.librarymanagement._ import sbt.internal.librarymanagement.syntax._ object IvyRetrieve { - def reports(report: ResolveReport): Seq[ConfigurationResolveReport] = - report.getConfigurations map report.getConfigurationReport + def reports(report: ResolveReport): Vector[ConfigurationResolveReport] = + report.getConfigurations.toVector map report.getConfigurationReport - def moduleReports(confReport: ConfigurationResolveReport): Seq[ModuleReport] = + def moduleReports(confReport: ConfigurationResolveReport): Vector[ModuleReport] = for { revId <- confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } } yield moduleRevisionDetail(confReport, confReport.getDependency(revId)) @@ -32,7 +32,7 @@ object IvyRetrieve { ModuleReport(mid, resolved, missing) } - private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Seq[(Artifact, File)], Seq[Artifact]) = + private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Vector[(Artifact, File)], Vector[Artifact]) = { val missing = new mutable.ListBuffer[Artifact] val resolved = new mutable.ListBuffer[(Artifact, File)] @@ -44,13 +44,13 @@ object IvyRetrieve { case None => missing += art } } - (resolved.toSeq, missing.toSeq) + (resolved.toVector, missing.toVector) } // We need this because current module report used as part of UpdateReport/ConfigurationReport contains // only the revolved modules. // Sometimes the entire module can be excluded via rules etc. - private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Seq[OrganizationArtifactReport] = { + private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Vector[OrganizationArtifactReport] = { val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } @@ -130,14 +130,14 @@ object IvyRetrieve { case _ => dep.getResolvedId.getExtraAttributes }) val isDefault = Option(dep.getDescriptor) map { _.isDefault } - val configurations = dep.getConfigurations(confReport.getConfiguration).toList - val licenses: Seq[(String, Option[String])] = mdOpt match { + val configurations = dep.getConfigurations(confReport.getConfiguration).toVector + val licenses: Vector[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toVector collect { case lic: IvyLicense if Option(lic.getName).isDefined => val temporaryURL = "http://localhost" (lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) }) } - case _ => Nil + case _ => Vector.empty } val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) @@ -151,13 +151,13 @@ object IvyRetrieve { confReport.getEvictedNodes.map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = - ModuleID(revID.getOrganisation, revID.getName, revID.getRevision, extraAttributes = IvySbt.getExtraAttributes(revID)) + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision).withExtraAttributes(IvySbt.getExtraAttributes(revID)) .branch(nonEmptyString(revID.getBranch)) def toArtifact(art: IvyArtifact): Artifact = { import art._ - Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations map Configurations.config, Option(getUrl)) + Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations.toVector map Configurations.config, Option(getUrl)) } def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 69a6fa282..7be87317a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -3,18 +3,22 @@ package sbt.internal.librarymanagement import java.io.File import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor -import sbt.serialization._ import sbt.util.Logger +import sbt.internal.util.CacheStore import sbt.librarymanagement._ +import sbt.librarymanagement.LibraryManagementCodec._ +import JsonUtil._ private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" def fakeCallerOrganization = "org.scala-sbt.temp-callers" +} +private[sbt] class JsonUtil(fileToStore: File => CacheStore) { def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { try { - val lite = fromJsonFile[UpdateReportLite](path).get + val lite = fileToStore(path).read[UpdateReportLite] fromLite(lite, cachedDescriptor) } catch { case e: Throwable => @@ -25,7 +29,7 @@ private[sbt] object JsonUtil { def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { sbt.io.IO.createDirectory(graphPath.getParentFile) - toJsonFile(toLite(ur), graphPath) + fileToStore(graphPath).write(toLite(ur)) } def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => @@ -44,7 +48,7 @@ private[sbt] object JsonUtil { }) // #1763/#2030. Caller takes up 97% of space, so we need to shrink it down, // but there are semantics associated with some of them. - def filterOutArtificialCallers(callers: Seq[Caller]): Seq[Caller] = + def filterOutArtificialCallers(callers: Vector[Caller]): Vector[Caller] = if (callers.isEmpty) callers else { val nonArtificial = callers filter { c => @@ -53,8 +57,8 @@ private[sbt] object JsonUtil { } val interProj = (callers find { c => c.caller.organization == sbtOrgTemp - }).toList - interProj ::: nonArtificial.toList + }).toVector + interProj ++ nonArtificial } def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = @@ -72,13 +76,3 @@ private[sbt] object JsonUtil { new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } } - -private[sbt] case class UpdateReportLite(configurations: Seq[ConfigurationReportLite]) -private[sbt] object UpdateReportLite { - implicit val pickler: Pickler[UpdateReportLite] with Unpickler[UpdateReportLite] = PicklerUnpickler.generate[UpdateReportLite] -} - -private[sbt] case class ConfigurationReportLite(configuration: String, details: Seq[OrganizationArtifactReport]) -private[sbt] object ConfigurationReportLite { - implicit val pickler: Pickler[ConfigurationReportLite] with Unpickler[ConfigurationReportLite] = PicklerUnpickler.generate[ConfigurationReportLite] -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala index db283b6c7..8b9f82922 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -35,18 +35,16 @@ final class RichUpdateReport(report: UpdateReport) { /** Constructs a new report that only contains files matching the specified filter.*/ private[sbt] def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => - modReport.copy( - artifacts = modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }, - missingArtifacts = modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } - ) + modReport + .withArtifacts(modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }) + .withMissingArtifacts(modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }) } - def substitute(f: (String, ModuleID, Seq[(Artifact, File)]) => Seq[(Artifact, File)]): UpdateReport = + def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) - modReport.copy( - artifacts = newArtifacts, - missingArtifacts = modReport.missingArtifacts - ) + modReport + .withArtifacts(newArtifacts) + .withMissingArtifacts(modReport.missingArtifacts) } def toSeq: Seq[(String, ModuleID, Artifact, File)] = @@ -57,9 +55,8 @@ final class RichUpdateReport(report: UpdateReport) { def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => - modReport.copy( - missingArtifacts = (modReport.missingArtifacts ++ f(modReport.module)).distinct - ) + modReport + .withMissingArtifacts((modReport.missingArtifacts ++ f(modReport.module)).distinct) } def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala deleted file mode 100644 index 76e74dcd4..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRule.scala +++ /dev/null @@ -1,52 +0,0 @@ -package sbt.internal.librarymanagement - -import impl.{ GroupID, GroupArtifactID } -import sbt.librarymanagement._ - -final class SbtExclusionRule( - val organization: String, - val name: String, - val artifact: String, - val configurations: Seq[String], - val crossVersion: CrossVersion -) { - - def copy( - organization: String = this.organization, - name: String = this.name, - artifact: String = this.artifact, - configurations: Seq[String] = this.configurations, - crossVersion: CrossVersion = this.crossVersion - ): SbtExclusionRule = - SbtExclusionRule( - organization = organization, - name = name, - artifact = artifact, - configurations = configurations, - crossVersion = crossVersion - ) -} - -object SbtExclusionRule { - def apply(organization: String): SbtExclusionRule = - new SbtExclusionRule(organization, "*", "*", Nil, CrossVersion.Disabled) - - def apply(organization: String, name: String): SbtExclusionRule = - new SbtExclusionRule(organization, name, "*", Nil, CrossVersion.Disabled) - - def apply( - organization: String, - name: String, - artifact: String, - configurations: Seq[String], - crossVersion: CrossVersion - ): SbtExclusionRule = - new SbtExclusionRule(organization, name, artifact, configurations, crossVersion) - - implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = - SbtExclusionRule(organization.groupID) - implicit def stringToExclusionRule(organization: String): SbtExclusionRule = - SbtExclusionRule(organization) - implicit def groupArtifactIDToExcludsionRule(gaid: GroupArtifactID): SbtExclusionRule = - SbtExclusionRule(gaid.groupID, gaid.artifactID, "*", Nil, gaid.crossVersion) -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala new file mode 100644 index 000000000..337ff3bd8 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala @@ -0,0 +1,11 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ +import java.util._ +import java.text._ + +trait DateFormat { self: BasicJsonProtocol => + private val format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy") + + implicit lazy val DateFormat: JsonFormat[Date] = project(_.toString, format.parse _) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala new file mode 100644 index 000000000..3a8920373 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala @@ -0,0 +1,12 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ +import org.apache.ivy.plugins.resolver.DependencyResolver + +trait DependencyResolverFormat { self: BasicJsonProtocol => + implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] = + project( + MyCrazyReferences.referenced _, + (ref: String) => MyCrazyReferences(ref, classOf[DependencyResolver]) + ) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala new file mode 100644 index 000000000..12f4f2f94 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala @@ -0,0 +1,8 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ + +trait Function1Format { self: BasicJsonProtocol => + implicit def Function1Format[T, U]: JsonFormat[T => U] = + project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[T => U])) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala new file mode 100644 index 000000000..fda66ae6b --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala @@ -0,0 +1,9 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ +import xsbti._ + +trait GlobalLockFormat { self: BasicJsonProtocol => + implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = + project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[GlobalLock])) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala new file mode 100644 index 000000000..5b84703d9 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala @@ -0,0 +1,9 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ +import xsbti._ + +trait LoggerFormat { self: BasicJsonProtocol => + implicit lazy val LoggerFormat: JsonFormat[Logger] = + project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[Logger])) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala new file mode 100644 index 000000000..7051e327e --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala @@ -0,0 +1,15 @@ +package sbt.internal.librarymanagement.formats + +import scala.collection.mutable + +object MyCrazyReferences { + private val references: mutable.Map[String, Any] = mutable.Map.empty + + def apply[T](key: String, clazz: Class[T]): T = synchronized(clazz.cast(references(key))) + + def referenced[T](value: T): String = synchronized { + val key = java.util.UUID.randomUUID.toString + references(key) = value + key + } +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala new file mode 100644 index 000000000..df862fb61 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala @@ -0,0 +1,9 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ +import scala.xml._ + +trait NodeSeqFormat { self: BasicJsonProtocol => + implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = + project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[NodeSeq])) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala new file mode 100644 index 000000000..e5e8b6e63 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -0,0 +1,27 @@ +package sbt.internal.librarymanagement +package formats + +import sjsonnew._ +import sbt.librarymanagement._ + +trait UpdateOptionsFormat { self: BasicJsonProtocol => + + implicit lazy val UpdateOptionsFormat: JsonFormat[UpdateOptions] = + project( + (uo: UpdateOptions) => ( + uo.circularDependencyLevel.name, + uo.interProjectFirst, + uo.latestSnapshots, + uo.consolidatedResolution, + uo.cachedResolution + ), + (xs: (String, Boolean, Boolean, Boolean, Boolean)) => + new UpdateOptions(levels(xs._1), xs._2, xs._3, xs._4, xs._5, ConvertResolver.defaultConvert) + ) + + private val levels: Map[String, CircularDependencyLevel] = Map( + "warn" -> CircularDependencyLevel.Warn, + "ignore" -> CircularDependencyLevel.Ignore, + "error" -> CircularDependencyLevel.Error + ) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index 9ceac2da6..6260f5ad6 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -26,7 +26,7 @@ trait DependencyBuilders { } final class GroupID private[sbt] (private[sbt] val groupID: String) { - def %(artifactID: String) = groupArtifact(artifactID, CrossVersion.Disabled) + def %(artifactID: String) = groupArtifact(artifactID, Disabled()) def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) private def groupArtifact(artifactID: String, cross: CrossVersion) = @@ -53,7 +53,7 @@ final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { { nonEmpty(configurations, "Configurations") val c = configurations - moduleID.copy(configurations = Some(c)) + moduleID.withConfigurations(configurations = Some(c)) } } final class RepositoryName private[sbt] (name: String) { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index ef9d20209..8c94be6f6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -24,6 +24,7 @@ import sbt.io.{ DirectoryFilter, Hash, IO } import sbt.util.Logger import sbt.librarymanagement._ import sbt.internal.librarymanagement.syntax._ +import sbt.internal.util.CacheStore private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -38,8 +39,9 @@ private[sbt] object CachedResolutionResolveCache { lazy val yyyymmdd: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") } -private[sbt] class CachedResolutionResolveCache() { +private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) { import CachedResolutionResolveCache._ + val jsonUtil = new JsonUtil(fileToStore) val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() // Used for subproject val projectReportCache: concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap() @@ -164,7 +166,7 @@ private[sbt] class CachedResolutionResolveCache() { else None) match { case Some(path) => log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) + val ur = jsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) if (ur.allFiles forall { _.exists }) { updateReportCache(md.getModuleRevisionId) = Right(ur) Some(Right(ur)) @@ -198,7 +200,7 @@ private[sbt] class CachedResolutionResolveCache() { if (changing) { cleanDynamicGraph() } - JsonUtil.writeUpdateReport(ur, gp) + jsonUtil.writeUpdateReport(ur, gp) // limit the update cache size if (updateReportCache.size > maxUpdateReportCacheSize) { updateReportCache.remove(updateReportCache.head._1) @@ -221,7 +223,7 @@ private[sbt] class CachedResolutionResolveCache() { { def reconstructReports(surviving: Vector[ModuleID], evicted: Vector[ModuleID], mgr: String): (Vector[ModuleReport], Vector[ModuleReport]) = { val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) - (surviving map moduleIdMap, evicted map moduleIdMap map { _.copy(evicted = true, evictedReason = Some(mgr.toString)) }) + (surviving map moduleIdMap, evicted map moduleIdMap map { _.withEvicted(true).withEvictedReason(Some(mgr.toString)) }) } (conflictCache get ((cf0, cf1))) match { case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) @@ -257,6 +259,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def makeInstance: Ivy private[sbt] val ignoreTransitiveForce: Boolean = true + private[sbt] val fileToStore: File => CacheStore + private val jsonUtil = new JsonUtil(fileToStore) + def withIvy[A](log: Logger)(f: Ivy => A): A = withIvy(new IvyLoggerInterface(log))(f) def withIvy[A](log: MessageLogger)(f: Ivy => A): A = @@ -428,7 +433,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { if (mr.evicted || mr.problem.nonEmpty) None else // https://github.com/sbt/sbt/issues/1763 - Some(mr.copy(callers = JsonUtil.filterOutArtificialCallers(mr.callers))) + Some(mr.withCallers(jsonUtil.filterOutArtificialCallers(mr.callers))) } match { case Vector() => None case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms)) @@ -504,7 +509,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { if (callers.size == callers0.size) mr else { log.debug(s":: $rootModuleConf: removing caller $moduleWithMostCallers -> $next for sorting") - mr.copy(callers = callers) + mr.withCallers(callers) } } OrganizationArtifactReport(oar.organization, oar.name, mrs) @@ -591,18 +596,18 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). */ - def mergeModuleReports(rootModuleConf: String, modules: Seq[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = + def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = { if (modules.nonEmpty) { log.debug(s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}") } - def mergeModuleReports(org: String, name: String, version: String, xs: Seq[ModuleReport]): ModuleReport = { + def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. - val distinctByModuleId = allCallers.groupBy({ _.caller }).toList map { case (k, xs) => xs.head } + val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (k, xs) => xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct - xs.head.copy(artifacts = allArtifacts, evicted = completelyEvicted, callers = distinctByModuleId) + xs.head.withArtifacts(allArtifacts).withEvicted(completelyEvicted).withCallers(distinctByModuleId) } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { case ((org, name, version), xs) => @@ -637,7 +642,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } x } - val newlyEvicted = affected map { _.copy(evicted = true, evictedReason = Some("transitive-evict")) } + val newlyEvicted = affected map { _.withEvicted(true).withEvictedReason(Some("transitive-evict")) } if (affected.isEmpty) oar else new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) } @@ -669,7 +674,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }) match { case Some(m) => log.debug(s"- directly forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("direct-force")) }, "direct-force") + (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("direct-force")) }, "direct-force") case None => (conflicts find { m => m.callers.exists { _.isForceDependency } @@ -677,13 +682,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. case Some(m) if !ignoreTransitiveForce => log.debug(s"- transitively forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("transitive-force")) }, "transitive-force") + (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("transitive-force")) }, "transitive-force") case _ => val strategy = lcm.getStrategy val infos = conflicts map { ModuleReportArtifactInfo(_) } Option(strategy.findLatest(infos.toArray, None.orNull)) match { case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some(lcm.toString)) }, lcm.toString) + (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some(lcm.toString)) }, lcm.toString) case _ => (conflicts, Vector(), lcm.toString) } } @@ -696,7 +701,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { mr.module.revision == ovrVersion } match { case Some(m) => - (Vector(m), conflicts filterNot { _ == m } map { _.copy(evicted = true, evictedReason = Some("override")) }, "override") + (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("override")) }, "override") case None => sys.error(s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { _.module }).mkString("(", ", ", ")")) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index fd9e33bef..7b843546a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -5,22 +5,39 @@ package sbt.librarymanagement import java.io.File import java.net.URL -import sbt.serialization._ -final case class Artifact(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL], extraAttributes: Map[String, String]) { +abstract class ArtifactParent { + def name: String + def `type`: String + def extension: String + def classifier: Option[String] + def configurations: Vector[Configuration] + def url: Option[URL] + def extraAttributes: Map[String, String] + + protected[this] def copy( + name: String = name, + `type`: String = `type`, + extension: String = extension, + classifier: Option[String] = classifier, + configurations: Vector[Configuration] = configurations, + url: Option[URL] = url, + extraAttributes: Map[String, String] = extraAttributes + ): Artifact + def extra(attributes: (String, String)*) = copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) } import Configurations.{ Optional, Pom, Test } -object Artifact { - def apply(name: String): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None) - def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Nil, None, extra) - def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Nil, None) - def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Nil, None) - def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Nil, None) - def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Nil, Some(url)) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Iterable[Configuration], url: Option[URL]): Artifact = +abstract class ArtifactCompanion { + def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra) + def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None) + def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Vector.empty, None) + def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) + def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, Some(url)) + + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[Configuration], url: Option[URL]): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) val DefaultExtension = "jar" @@ -28,7 +45,7 @@ object Artifact { def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Pom :: Nil, None) + def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None) // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs val DefaultSourceTypes = Set("src", "source", "sources") @@ -62,7 +79,7 @@ object Artifact { val name = file.getName val i = name.lastIndexOf('.') val base = if (i >= 0) name.substring(0, i) else name - Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Nil, Some(file.toURI.toURL)) + Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Vector.empty, Some(file.toURI.toURL)) } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { @@ -88,75 +105,5 @@ object Artifact { * The artifact is created under the default configuration. */ def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Nil, None) - - private val optStringPickler = implicitly[Pickler[Option[String]]] - private val optStringUnpickler = implicitly[Unpickler[Option[String]]] - private val vectorConfigurationPickler = implicitly[Pickler[Vector[Configuration]]] - private val vectorConfigurationUnpickler = implicitly[Unpickler[Vector[Configuration]]] - private val stringStringMapPickler = implicitly[Pickler[Map[String, String]]] - private val stringStringMapUnpickler = implicitly[Unpickler[Map[String, String]]] - - implicit val pickler: Pickler[Artifact] = new Pickler[Artifact] { - val tag = implicitly[FastTypeTag[Artifact]] - val stringTag = implicitly[FastTypeTag[String]] - val optionStringTag = implicitly[FastTypeTag[Option[String]]] - val vectorConfigurationTag = implicitly[FastTypeTag[Vector[Configuration]]] - val stringStringMapTag = implicitly[FastTypeTag[Map[String, String]]] - def pickle(a: Artifact, builder: PBuilder): Unit = { - builder.pushHints() - builder.hintTag(tag) - builder.beginEntry(a) - builder.putField("name", { b => - b.hintTag(stringTag) - stringPickler.pickle(a.name, b) - }) - builder.putField("type", { b => - b.hintTag(stringTag) - stringPickler.pickle(a.`type`, b) - }) - builder.putField("extension", { b => - b.hintTag(stringTag) - stringPickler.pickle(a.extension, b) - }) - builder.putField("classifier", { b => - b.hintTag(optionStringTag) - optStringPickler.pickle(a.classifier, b) - }) - builder.putField("configurations", { b => - b.hintTag(vectorConfigurationTag) - vectorConfigurationPickler.pickle(a.configurations.toVector, b) - }) - builder.putField("url", { b => - b.hintTag(optionStringTag) - optStringPickler.pickle(a.url map { _.toString }, b) - }) - builder.putField("extraAttributes", { b => - b.hintTag(stringStringMapTag) - stringStringMapPickler.pickle(a.extraAttributes, b) - }) - builder.endEntry() - builder.popHints() - () - } - } - implicit val unpickler: Unpickler[Artifact] = new Unpickler[Artifact] { - val tag = implicitly[FastTypeTag[Artifact]] - def unpickle(tpe: String, reader: PReader): Any = { - reader.pushHints() - // reader.hintTag(tag) - reader.beginEntry() - val name = stringPickler.unpickleEntry(reader.readField("name")).asInstanceOf[String] - val tp = stringPickler.unpickleEntry(reader.readField("type")).asInstanceOf[String] - val extension = stringPickler.unpickleEntry(reader.readField("extension")).asInstanceOf[String] - val classifier = optStringUnpickler.unpickleEntry(reader.readField("classifier")).asInstanceOf[Option[String]] - val configurations = vectorConfigurationUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[Configuration]] - val u = optStringUnpickler.unpickleEntry(reader.readField("url")).asInstanceOf[Option[String]] map { new URL(_) } - val extraAttributes = stringStringMapUnpickler.unpickleEntry(reader.readField("extraAttributes")).asInstanceOf[Map[String, String]] - val result = Artifact(name, tp, extension, classifier, configurations, u, extraAttributes) - reader.endEntry() - reader.popHints() - result - } - } + Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Vector.empty, None) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index f860d4abc..ad064f550 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -3,8 +3,6 @@ */ package sbt.librarymanagement -import sbt.serialization._ - object Configurations { def config(name: String) = new Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations @@ -50,18 +48,20 @@ object Configurations { private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } -/** Represents an Ivy configuration. */ -final case class Configuration(name: String, description: String, isPublic: Boolean, extendsConfigs: List[Configuration], transitive: Boolean) { + +abstract class ConfigurationParent { + def name: String + def description: String + def isPublic: Boolean + def extendsConfigs: Vector[Configuration] + def transitive: Boolean + require(name != null && !name.isEmpty) require(description != null) - def this(name: String) = this(name, "", true, Nil, true) + def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) - def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toList ::: extendsConfigs, transitive) + def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) def notTransitive = intransitive def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) def hide = Configuration(name, description, false, extendsConfigs, transitive) - override def toString = name -} -object Configuration { - implicit val pickler: Pickler[Configuration] with Unpickler[Configuration] = PicklerUnpickler.generate[Configuration] } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index d9869e030..88b15cf6a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -1,89 +1,17 @@ package sbt.librarymanagement -import sbt.serialization._ import sbt.internal.librarymanagement.SbtExclusionRule import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) -/** Configures how a module will be cross-versioned. */ -sealed trait CrossVersion - -object CrossVersion { +abstract class CrossVersionCompanion { /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion /** The first `major.minor` sbt version that the sbt binary version should be used for cross-versioning instead of the full version. */ val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion - /** Disables cross versioning for a module.*/ - object Disabled extends CrossVersion { override def toString = "disabled" } - - /** - * Cross-versions a module using the result of applying `remapVersion` to the binary version. - * For example, if `remapVersion = v => "2.10"` and the binary version is "2.9.2" or "2.10", - * the module is cross-versioned with "2.10". - */ - final class Binary(val remapVersion: String => String) extends CrossVersion { - override def toString = "Binary" - override def hashCode = remapVersion.## - override def equals(that: Any) = that match { - case that: Binary => this.remapVersion == that.remapVersion - case _ => false - } - } - - /** - * Cross-versions a module with the result of applying `remapVersion` to the full version. - * For example, if `remapVersion = v => "2.10"` and the full version is "2.9.2" or "2.10.3", - * the module is cross-versioned with "2.10". - */ - final class Full(val remapVersion: String => String) extends CrossVersion { - override def toString = "Full" - override def hashCode = remapVersion.## - override def equals(that: Any) = that match { - case that: Full => this.remapVersion == that.remapVersion - case _ => false - } - } - - private val disabledTag = implicitly[FastTypeTag[Disabled.type]] - private val binaryTag = implicitly[FastTypeTag[Binary]] - private val fullTag = implicitly[FastTypeTag[Full]] - implicit val pickler: Pickler[CrossVersion] = new Pickler[CrossVersion] { - val tag = implicitly[FastTypeTag[CrossVersion]] - def pickle(a: CrossVersion, builder: PBuilder): Unit = { - builder.pushHints() - builder.hintTag(a match { - case Disabled => disabledTag - case x: Binary => binaryTag - case x: Full => fullTag - }) - builder.beginEntry(a) - builder.endEntry() - builder.popHints() - () - } - } - implicit val unpickler: Unpickler[CrossVersion] = new Unpickler[CrossVersion] { - val tag = implicitly[FastTypeTag[CrossVersion]] - def unpickle(tpe: String, reader: PReader): Any = { - reader.pushHints() - reader.hintTag(tag) - val tpeStr = reader.beginEntry() - val tpe = scala.pickling.FastTypeTag(tpeStr) - // sys.error(tpe.toString) - val result = tpe match { - case t if t == disabledTag => Disabled - case t if t == binaryTag => binary - case t if t == fullTag => full - } - reader.endEntry() - reader.popHints() - result - } - } - /** Cross-versions a module with the full version (typically the full Scala version). */ def full: CrossVersion = new Full(idStringFun) @@ -114,9 +42,9 @@ object CrossVersion { */ def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { - case Disabled => None - case b: Binary => append(b.remapVersion(binaryVersion)) - case f: Full => append(f.remapVersion(fullVersion)) + case _: Disabled => None + case b: Binary => append(b.remapVersion(binaryVersion)) + case f: Full => append(f.remapVersion(fullVersion)) } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ @@ -128,7 +56,7 @@ object CrossVersion { is flatMap { i => apply(module, i) } /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ - def substituteCross(artifacts: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + def substituteCross(artifacts: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] = cross match { case None => artifacts case Some(is) => substituteCrossA(artifacts, cross) @@ -147,14 +75,14 @@ object CrossVersion { private[sbt] def substituteCross(exclude: SbtExclusionRule, is: Option[IvyScala]): SbtExclusionRule = { val fopt: Option[String => String] = is flatMap { i => CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) } - exclude.copy(name = applyCross(exclude.name, fopt)) + exclude.withName(applyCross(exclude.name, fopt)) } /** Cross-versions `a` according to cross-version function `cross`. */ def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = - a.copy(name = applyCross(a.name, cross)) + a.withName(applyCross(a.name, cross)) - private[sbt] def substituteCrossA(as: Seq[Artifact], cross: Option[String => String]): Seq[Artifact] = + private[sbt] def substituteCrossA(as: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] = as.map(art => substituteCross(art, cross)) /** @@ -166,7 +94,7 @@ object CrossVersion { { val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) if (cross.isDefined) - m.copy(name = applyCross(m.name, cross), explicitArtifacts = substituteCrossA(m.explicitArtifacts, cross)) + m.withName(applyCross(m.name, cross)).withExplicitArtifacts(substituteCrossA(m.explicitArtifacts, cross)) else m } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 2c93719ec..dde946c1f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -88,7 +88,7 @@ final class EvictionPair private[sbt] ( val organization: String, val name: String, val winner: Option[ModuleReport], - val evicteds: Seq[ModuleReport], + val evicteds: Vector[ModuleReport], val includesDirect: Boolean, val showCallers: Boolean ) { @@ -168,7 +168,7 @@ object EvictionWarning { private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { val directDependencies = module.moduleSettings match { case x: InlineConfiguration => x.dependencies - case _ => Seq() + case _ => Vector.empty } val pairs = reports map { detail => val evicteds = detail.modules filter { _.evicted } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 54531bae4..275856dcd 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -3,54 +3,24 @@ */ package sbt.librarymanagement -import java.net.URL import org.apache.ivy.core.module.descriptor import org.apache.ivy.util.filter.{ Filter => IvyFilter } -import sbt.serialization._ -/** Additional information about a project module */ -final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) { - def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) = - this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq()) - def formally(name: String) = copy(nameFormal = name) - def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home) - def licensed(lics: (String, URL)*) = copy(licenses = lics) - def organization(name: String, home: Option[URL]) = copy(organizationName = name, organizationHomepage = home) +abstract class InclExclRuleCompanion { + def everything = new InclExclRule("*", "*", "*", Vector.empty) } -/** Basic SCM information for a project module */ -final case class ScmInfo(browseUrl: URL, connection: String, devConnection: Option[String] = None) +abstract class ArtifactTypeFilterParent { + def types: Set[String] + def inverted: Boolean -final case class Developer(id: String, name: String, email: String, url: URL) + protected[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter -/** - * Rule to either: - *
    - *
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • - *
  • include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
  • - *
- * Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases. - */ -final case class InclExclRule(organization: String = "*", name: String = "*", artifact: String = "*", configurations: Seq[String] = Nil) -object InclExclRule { - def everything = InclExclRule("*", "*", "*", Nil) - - implicit val pickler: Pickler[InclExclRule] with Unpickler[InclExclRule] = PicklerUnpickler.generate[InclExclRule] -} - -/** - * Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) - * @param types represents the artifact types that we should try to resolve for (as in the allowed values of - * `artifact[type]` from a dependency `` section). One can use this to filter - * source / doc artifacts. - * @param inverted whether to invert the types filter (i.e. allow only types NOT in the set) - */ -case class ArtifactTypeFilter(types: Set[String], inverted: Boolean) { def invert = copy(inverted = !inverted) def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted } -object ArtifactTypeFilter { +abstract class ArtifactTypeFilterCompanion { def allow(types: Set[String]) = ArtifactTypeFilter(types, false) def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) @@ -59,16 +29,12 @@ object ArtifactTypeFilter { } } -final case class ModuleConfiguration(organization: String, name: String, revision: String, resolver: Resolver) -object ModuleConfiguration { - def apply(org: String, resolver: Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) - def apply(org: String, name: String, resolver: Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) -} +abstract class ConflictManagerCompanion { + // To avoid NPE (or making the val's below lazy) + // For case classes refchecks rewrites apply calls to constructor calls, we have to do it manually + def apply(name: String, organization: String = "*", module: String = "*"): ConflictManager + def ConflictManager(name: String) = apply(name) -final case class ConflictManager(name: String, organization: String = "*", module: String = "*") - -/** See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.*/ -object ConflictManager { val all = ConflictManager("all") val latestTime = ConflictManager("latest-time") val latestRevision = ConflictManager("latest-revision") diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index 8b004ef9d..c45b84799 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -19,7 +19,7 @@ object ScalaArtifacts { val ReflectID = "scala-reflect" val ActorsID = "scala-actors" val ScalapID = "scalap" - val Artifacts = Seq(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) + val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) val DottyIDPrefix = "dotty" def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" @@ -28,8 +28,8 @@ object ScalaArtifacts { private[sbt] def toolDependencies(org: String, version: String, isDotty: Boolean = false): Seq[ModuleID] = if (isDotty) - Seq(ModuleID(org, DottyIDPrefix, version, Some(Configurations.ScalaTool.name + "->compile"), - crossVersion = CrossVersion.binary)) + Seq(ModuleID(org, DottyIDPrefix, version).withConfigurations(Some(Configurations.ScalaTool.name + "->compile")) + .withCrossVersion(CrossVersion.binary)) else Seq( scalaToolDependency(org, ScalaArtifacts.CompilerID, version), @@ -37,7 +37,7 @@ object ScalaArtifacts { ) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = - ModuleID(org, id, version, Some(Configurations.ScalaTool.name + "->default,optional(default)")) + ModuleID(org, id, version).withConfigurations(Some(Configurations.ScalaTool.name + "->default,optional(default)")) } object SbtArtifacts { val Organization = "org.scala-sbt" @@ -45,9 +45,7 @@ object SbtArtifacts { import ScalaArtifacts._ -final case class IvyScala(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Iterable[Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String = ScalaArtifacts.Organization, scalaArtifacts: Seq[String] = ScalaArtifacts.Artifacts) - -private[sbt] object IvyScala { +private[sbt] abstract class IvyScalaCompanion { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 2cbf37138..3716ac790 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -6,13 +6,37 @@ package sbt.librarymanagement import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties -import sbt.serialization._ -final case class ModuleID(organization: String, name: String, revision: String, configurations: Option[String] = None, isChanging: Boolean = false, isTransitive: Boolean = true, isForce: Boolean = false, explicitArtifacts: Seq[Artifact] = Nil, inclusions: Seq[InclusionRule] = Nil, exclusions: Seq[ExclusionRule] = Nil, extraAttributes: Map[String, String] = Map.empty, crossVersion: CrossVersion = CrossVersion.Disabled, branchName: Option[String] = None) { - override def toString: String = - organization + ":" + name + ":" + revision + - (configurations match { case Some(s) => ":" + s; case None => "" }) + - (if (extraAttributes.isEmpty) "" else " " + extraString) +abstract class ModuleIDParent { + def organization: String + def name: String + def revision: String + def configurations: Option[String] + def isChanging: Boolean + def isTransitive: Boolean + def isForce: Boolean + def explicitArtifacts: Vector[Artifact] + def inclusions: Vector[InclusionRule] + def exclusions: Vector[ExclusionRule] + def extraAttributes: Map[String, String] + def crossVersion: CrossVersion + def branchName: Option[String] + + protected[this] def copy( + organization: String = organization, + name: String = name, + revision: String = revision, + configurations: Option[String] = configurations, + isChanging: Boolean = isChanging, + isTransitive: Boolean = isTransitive, + isForce: Boolean = isForce, + explicitArtifacts: Vector[Artifact] = explicitArtifacts, + inclusions: Vector[InclusionRule] = inclusions, + exclusions: Vector[ExclusionRule] = exclusions, + extraAttributes: Map[String, String] = extraAttributes, + crossVersion: CrossVersion = crossVersion, + branchName: Option[String] = branchName + ): ModuleID /** String representation of the extra attributes, excluding any information only attributes. */ def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") @@ -21,10 +45,10 @@ final case class ModuleID(organization: String, name: String, revision: String, def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)) @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else CrossVersion.Disabled) + def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled()) @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else CrossVersion.Disabled) + def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else Disabled()) /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) @@ -64,7 +88,7 @@ final case class ModuleID(organization: String, name: String, revision: String, * Declares the explicit artifacts for this module. If this ModuleID represents a dependency, * these artifact definitions override the information in the dependency's published metadata. */ - def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts ++ this.explicitArtifacts) + def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts.toVector ++ explicitArtifacts) /** * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify @@ -73,7 +97,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def excludeAll(rules: InclExclRule*) = copy(exclusions = this.exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = excludeAll(InclExclRule(org, name)) + def exclude(org: String, name: String) = excludeAll(InclExclRule().withOrganization(org).withName(name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. @@ -127,9 +151,7 @@ final case class ModuleID(organization: String, name: String, revision: String, def branch(branchName: Option[String]) = copy(branchName = branchName) } -object ModuleID { - implicit val pickler: Pickler[ModuleID] with Unpickler[ModuleID] = PicklerUnpickler.generate[ModuleID] - +abstract class ModuleIDCompanion { /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 7f2c8779e..12a4c03f6 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -9,11 +9,7 @@ import scala.xml.XML import org.apache.ivy.plugins.resolver.DependencyResolver import org.xml.sax.SAXParseException -sealed trait Resolver { - def name: String -} -final class RawRepository(val resolver: DependencyResolver) extends Resolver { - def name = resolver.getName +final class RawRepository(val resolver: DependencyResolver) extends Resolver(resolver.getName) { override def toString = "Raw(" + resolver.toString + ")" override def equals(o: Any): Boolean = o match { @@ -29,148 +25,30 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver { hash } } -sealed case class ChainedResolver(name: String, resolvers: Seq[Resolver]) extends Resolver -/** An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts. */ -sealed case class MavenRepository(name: String, root: String, localIfFile: Boolean = true) extends Resolver { - override def toString = s"$name: $root" - def isCache: Boolean = false - def withLocalIfFile(value: Boolean) = MavenRepository(name, root, value) -} - -/** - * An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because - * the metadata is different (see Aether ML discussion). - */ -final class MavenCache(name: String, val rootFile: File) extends MavenRepository(name, rootFile.toURI.toURL.toString) { - override val toString = s"cache:$name: ${rootFile.getAbsolutePath}" - override def isCache: Boolean = true -} -object MavenCache { - def apply(name: String, rootFile: File): MavenCache = new MavenCache(name, rootFile) -} - -final class Patterns(val ivyPatterns: Seq[String], val artifactPatterns: Seq[String], val isMavenCompatible: Boolean, val descriptorOptional: Boolean, val skipConsistencyCheck: Boolean) { - private[sbt] def mavenStyle(): Patterns = Patterns(ivyPatterns, artifactPatterns, true) - private[sbt] def withDescriptorOptional(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, true, skipConsistencyCheck) - private[sbt] def withoutConsistencyCheck(): Patterns = Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, true) - private[sbt] def withIvys(patterns: Seq[String]): Patterns = Patterns(patterns ++ ivyPatterns, artifactPatterns, isMavenCompatible) - private[sbt] def withArtifacts(patterns: Seq[String]): Patterns = Patterns(ivyPatterns, patterns ++ artifactPatterns, isMavenCompatible) - override def toString = "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) - override def equals(obj: Any): Boolean = { - obj match { - case other: Patterns => - ivyPatterns == other.ivyPatterns && artifactPatterns == other.artifactPatterns && isMavenCompatible == other.isMavenCompatible && descriptorOptional == other.descriptorOptional && skipConsistencyCheck == other.skipConsistencyCheck - case _ => false - } - } - override def hashCode: Int = (ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck).hashCode -} -object Patterns { +abstract class PatternsCompanion { implicit def defaultPatterns: Patterns = Resolver.defaultPatterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*) - def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = Patterns(artifactPatterns, artifactPatterns, isMavenCompatible) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean): Patterns = apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, false, false) - def apply(ivyPatterns: Seq[String], artifactPatterns: Seq[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) -} -object RepositoryHelpers { - final case class SshConnection(authentication: Option[SshAuthentication], hostname: Option[String], port: Option[Int]) { - def copy(authentication: Option[SshAuthentication]) = SshConnection(authentication, hostname, port) + def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = { + val patterns = artifactPatterns.toVector + Patterns().withIvyPatterns(patterns).withArtifactPatterns(patterns).withIsMavenCompatible(isMavenCompatible) } - /** Configuration specific to an Ivy filesystem resolver. */ - final case class FileConfiguration(isLocal: Boolean, isTransactional: Option[Boolean]) { - def transactional() = FileConfiguration(isLocal, Some(true)) - def nontransactional() = FileConfiguration(isLocal, Some(false)) - def nonlocal() = FileConfiguration(false, isTransactional) - } - sealed trait SshAuthentication - final case class PasswordAuthentication(user: String, password: Option[String]) extends SshAuthentication - final case class KeyFileAuthentication(user: String, keyfile: File, password: Option[String]) extends SshAuthentication } -import RepositoryHelpers.{ SshConnection, FileConfiguration } -import RepositoryHelpers.{ KeyFileAuthentication, PasswordAuthentication, SshAuthentication } -/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories.*/ -sealed abstract class PatternsBasedRepository extends Resolver { - type RepositoryType <: PatternsBasedRepository - /** Should be implemented to create a new copy of this repository but with `patterns` as given.*/ - protected def copy(patterns: Patterns): RepositoryType - - /** The object representing the configured patterns for this repository. */ - def patterns: Patterns - - /** Enables maven 2 compatibility for this repository. */ - def mavenStyle() = copy(patterns.mavenStyle()) - - /** Makes descriptor metadata optional for this repository. */ - def descriptorOptional() = copy(patterns.withDescriptorOptional()) - - /** Disables consistency checking for this repository. */ - def skipConsistencyCheck() = copy(patterns.withoutConsistencyCheck()) - - /** Adds the given patterns for resolving/publishing Ivy files.*/ - def ivys(ivyPatterns: String*): RepositoryType = copy(patterns.withIvys(ivyPatterns)) - /** Adds the given patterns for resolving/publishing artifacts.*/ - def artifacts(artifactPatterns: String*): RepositoryType = copy(patterns.withArtifacts(artifactPatterns)) -} -/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ -final case class FileRepository(name: String, configuration: FileConfiguration, patterns: Patterns) extends PatternsBasedRepository { - type RepositoryType = FileRepository - protected def copy(patterns: Patterns): FileRepository = FileRepository(name, configuration, patterns) - private def copy(configuration: FileConfiguration) = FileRepository(name, configuration, patterns) - def transactional() = copy(configuration.transactional()) - def nonlocal() = copy(configuration.nonlocal()) -} -final case class URLRepository(name: String, patterns: Patterns) extends PatternsBasedRepository { - type RepositoryType = URLRepository - protected def copy(patterns: Patterns): URLRepository = URLRepository(name, patterns) -} -/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ -sealed abstract class SshBasedRepository extends PatternsBasedRepository { - type RepositoryType <: SshBasedRepository - protected def copy(connection: SshConnection): RepositoryType - private def copy(authentication: SshAuthentication): RepositoryType = copy(connection.copy(Some(authentication))) - - /** The object representing the configured ssh connection for this repository. */ - def connection: SshConnection - - /** Configures this to use the specified user name and password when connecting to the remote repository. */ - def as(user: String, password: String): RepositoryType = as(user, Some(password)) - def as(user: String): RepositoryType = as(user, None) - def as(user: String, password: Option[String]) = copy(new PasswordAuthentication(user, password)) - /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ - def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) - def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) - def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(new KeyFileAuthentication(user, keyfile, password)) -} -/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ -final case class SshRepository(name: String, connection: SshConnection, patterns: Patterns, publishPermissions: Option[String]) extends SshBasedRepository { - type RepositoryType = SshRepository - protected def copy(patterns: Patterns): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - protected def copy(connection: SshConnection): SshRepository = SshRepository(name, connection, patterns, publishPermissions) - /** Defines the permissions to set when publishing to this repository. */ - def withPermissions(publishPermissions: String): SshRepository = withPermissions(Some(publishPermissions)) - def withPermissions(publishPermissions: Option[String]): SshRepository = SshRepository(name, connection, patterns, publishPermissions) -} -/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ -final case class SftpRepository(name: String, connection: SshConnection, patterns: Patterns) extends SshBasedRepository { - type RepositoryType = SftpRepository - protected def copy(patterns: Patterns): SftpRepository = SftpRepository(name, connection, patterns) - protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) -} /** A repository that conforms to sbt launcher's interface */ private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Repository { def rawRepository = new RawRepository(resolver) } -import Resolver._ +trait ResolversSyntax { + import Resolver._ + val DefaultMavenRepository = new MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) + val JavaNet2Repository = new MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) + val JCenterRepository = new MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) +} -object DefaultMavenRepository extends MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) -object JavaNet2Repository extends MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) -object JCenterRepository extends MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) - -object Resolver { +abstract class ResolverCompanion { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) @@ -342,7 +220,7 @@ object Resolver { /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = { - def resolveAll(patterns: Seq[String]) = patterns.map(p => resolvePattern(base, p)) + def resolveAll(patterns: Vector[String]) = patterns.map(p => resolvePattern(base, p)) Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible, basePatterns.descriptorOptional, basePatterns.skipConsistencyCheck) } private[sbt] def resolvePattern(base: String, pattern: String): String = @@ -351,7 +229,7 @@ object Resolver { if (normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern } def defaultFileConfiguration = FileConfiguration(true, None) - def mavenStylePatterns = Patterns(Nil, mavenStyleBasePattern :: Nil, true) + def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern)) def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns @@ -381,17 +259,17 @@ object Resolver { } // TODO - should this just be the *exact* same as mavenLocal? probably... def publishMavenLocal: MavenCache = new MavenCache("publish-m2-local", mavenLocalDir) - def mavenLocal: MavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) + def mavenLocal: IMavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = { - val pList = s"$${ivy.home}/$id/$localBasePattern" :: Nil - FileRepository(id, defaultFileConfiguration, Patterns(pList, pList, false)) + val pList = Vector(s"$${ivy.home}/$id/$localBasePattern") + FileRepository(id, defaultFileConfiguration, Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false)) } def defaultIvyPatterns = { - val pList = List(localBasePattern) - Patterns(pList, pList, false) + val pList = Vector(localBasePattern) + Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index 06974aa90..fb0b0a87b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -5,21 +5,13 @@ package sbt.librarymanagement import java.io.File import java.{ util => ju } -import sbt.serialization._ -/** - * Provides information about resolution of a single configuration. - * @param configuration the configuration this report is for. - * @param modules a sequence containing one report for each module resolved for this configuration. - * @param details a sequence containing one report for each org/name, which may or may not be part of the final resolution. - * @param evicted a sequence of evicted modules - */ -final class ConfigurationReport( - val configuration: String, - val modules: Seq[ModuleReport], - val details: Seq[OrganizationArtifactReport] -) { +abstract class ConfigurationReportParent { + def configuration: String + def modules: Vector[ModuleReport] + def details: Vector[OrganizationArtifactReport] + /** a sequence of evicted modules */ def evicted: Seq[ModuleID] = details flatMap (_.modules) filter (_.evicted) map (_.module) @@ -36,78 +28,36 @@ final class ConfigurationReport( val module = mr.module if (module.configurations.isEmpty) { val conf = mr.configurations map (c => s"$configuration->$c") mkString ";" - module.copy(configurations = Some(conf)) + module.withConfigurations(Some(conf)) } else module } def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) } -object ConfigurationReport { - implicit val pickler: Pickler[ConfigurationReport] with Unpickler[ConfigurationReport] = PicklerUnpickler.generate[ConfigurationReport] -} -/** - * OrganizationArtifactReport represents an organization+name entry in Ivy resolution report. - * In sbt's terminology, "module" consists of organization, name, and version. - * In Ivy's, "module" means just organization and name, and the one including version numbers - * are called revisions. - * - * A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted. - * (Note old evicted was just a seq of ModuleIDs). - * OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name, - * which can be used to calculate detailed evction warning etc. - */ -final class OrganizationArtifactReport private[sbt] ( - val organization: String, - val name: String, - val modules: Seq[ModuleReport] -) { - override def toString: String = { - val details = modules map { _.detailReport } - s"\t$organization:$name\n${details.mkString}\n" - } -} -object OrganizationArtifactReport { - implicit val pickler: Pickler[OrganizationArtifactReport] with Unpickler[OrganizationArtifactReport] = PicklerUnpickler.generate[OrganizationArtifactReport] +abstract class ModuleReportParent { + def module: ModuleID + def artifacts: Vector[(Artifact, File)] + def missingArtifacts: Vector[Artifact] + def status: Option[String] + def publicationDate: Option[ju.Date] + def resolver: Option[String] + def artifactResolver: Option[String] + def evicted: Boolean + def evictedData: Option[String] + def evictedReason: Option[String] + def problem: Option[String] + def homepage: Option[String] + def extraAttributes: Map[String, String] + def isDefault: Option[Boolean] + def branch: Option[String] + def configurations: Vector[String] + def licenses: Vector[(String, Option[String])] + def callers: Vector[Caller] - def apply(organization: String, name: String, modules: Seq[ModuleReport]): OrganizationArtifactReport = - new OrganizationArtifactReport(organization, name, modules) -} + protected[this] def arts: Vector[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) -/** - * Provides information about the resolution of a module. - * This information is in the context of a specific configuration. - * @param module the `ModuleID` this report is for. - * @param artifacts the resolved artifacts for this module, paired with the File the artifact was retrieved to. - * @param missingArtifacts the missing artifacts for this module. - */ -final class ModuleReport( - val module: ModuleID, - val artifacts: Seq[(Artifact, File)], - val missingArtifacts: Seq[Artifact], - val status: Option[String], - val publicationDate: Option[ju.Date], - val resolver: Option[String], - val artifactResolver: Option[String], - val evicted: Boolean, - val evictedData: Option[String], - val evictedReason: Option[String], - val problem: Option[String], - val homepage: Option[String], - val extraAttributes: Map[String, String], - val isDefault: Option[Boolean], - val branch: Option[String], - val configurations: Seq[String], - val licenses: Seq[(String, Option[String])], - val callers: Seq[Caller] -) { - - private[this] lazy val arts: Seq[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) - override def toString: String = { - s"\t\t$module: " + - (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" - } def detailReport: String = s"\t\t- ${module.revision}\n" + (if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) + @@ -148,10 +98,10 @@ final class ModuleReport( def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) - private[sbt] def copy( + protected[this] def copy( module: ModuleID = module, - artifacts: Seq[(Artifact, File)] = artifacts, - missingArtifacts: Seq[Artifact] = missingArtifacts, + artifacts: Vector[(Artifact, File)] = artifacts, + missingArtifacts: Vector[Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[ju.Date] = publicationDate, resolver: Option[String] = resolver, @@ -164,66 +114,31 @@ final class ModuleReport( extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, - configurations: Seq[String] = configurations, - licenses: Seq[(String, Option[String])] = licenses, - callers: Seq[Caller] = callers - ): ModuleReport = - new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, - evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) + configurations: Vector[String] = configurations, + licenses: Vector[(String, Option[String])] = licenses, + callers: Vector[Caller] = callers + ): ModuleReport } -object ModuleReport { - def apply(module: ModuleID, artifacts: Seq[(Artifact, File)], missingArtifacts: Seq[Artifact]): ModuleReport = - new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, - false, None, None, None, None, Map(), None, None, Nil, Nil, Nil) - implicit val pickler: Pickler[ModuleReport] with Unpickler[ModuleReport] = PicklerUnpickler.generate[ModuleReport] -} - -final class Caller( - val caller: ModuleID, - val callerConfigurations: Seq[String], - val callerExtraAttributes: Map[String, String], - val isForceDependency: Boolean, - val isChangingDependency: Boolean, - val isTransitiveDependency: Boolean, - val isDirectlyForceDependency: Boolean -) { - override def toString: String = - s"$caller" -} -object Caller { - implicit val pickler: Pickler[Caller] with Unpickler[Caller] = PicklerUnpickler.generate[Caller] -} - -/** - * Provides information about dependency resolution. - * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. - * This means that for a given configuration, there should only be one revision for a given organization and module name. - * @param cachedDescriptor the location of the resolved module descriptor in the cache - * @param configurations a sequence containing one report for each configuration resolved. - * @param stats information about the update that produced this report - * @see sbt.RichUpdateReport - */ -final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[ConfigurationReport], val stats: UpdateStats, private[sbt] val stamps: Map[File, Long]) { - @deprecated("Use the variant that provides timestamps of files.", "0.13.0") - def this(cachedDescriptor: File, configurations: Seq[ConfigurationReport], stats: UpdateStats) = - this(cachedDescriptor, configurations, stats, Map.empty) - - override def toString = "Update report:\n\t" + stats + "\n" + configurations.mkString +abstract class UpdateReportParent { + def cachedDescriptor: File + def configurations: Vector[ConfigurationReport] + def stats: UpdateStats + private[sbt] def stamps: Map[File, Long] /** All resolved modules in all configurations. */ - def allModules: Seq[ModuleID] = + def allModules: Vector[ModuleID] = { val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toSeq map { + configurations.flatMap(_.allModules).groupBy(key).toVector map { case (k, v) => v reduceLeft { (agg, x) => - agg.copy( - configurations = (agg.configurations, x.configurations) match { - case (None, _) => x.configurations - case (Some(ac), None) => Some(ac) - case (Some(ac), Some(xc)) => Some(s"$ac;$xc") - } + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } ) } } @@ -237,81 +152,4 @@ final class UpdateReport(val cachedDescriptor: File, val configurations: Seq[Con /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ def allConfigurations: Seq[String] = configurations.map(_.configuration) - - private[sbt] def withStats(us: UpdateStats): UpdateReport = - new UpdateReport( - this.cachedDescriptor, - this.configurations, - us, - this.stamps - ) -} - -object UpdateReport { - private val vectorConfigurationReportPickler = implicitly[Pickler[Vector[ConfigurationReport]]] - private val vectorConfigurationReportUnpickler = implicitly[Unpickler[Vector[ConfigurationReport]]] - private val updateStatsPickler = implicitly[Pickler[UpdateStats]] - private val updateStatsUnpickler = implicitly[Unpickler[UpdateStats]] - private val flMapPickler = implicitly[Pickler[Map[File, Long]]] - private val flMapUnpickler = implicitly[Unpickler[Map[File, Long]]] - - implicit val pickler: Pickler[UpdateReport] with Unpickler[UpdateReport] = new Pickler[UpdateReport] with Unpickler[UpdateReport] { - val tag = implicitly[FastTypeTag[UpdateReport]] - val fileTag = implicitly[FastTypeTag[File]] - val vectorConfigurationReportTag = implicitly[FastTypeTag[Vector[ConfigurationReport]]] - val updateStatsTag = implicitly[FastTypeTag[UpdateStats]] - val flMapTag = implicitly[FastTypeTag[Map[File, Long]]] - def pickle(a: UpdateReport, builder: PBuilder): Unit = { - builder.pushHints() - builder.hintTag(tag) - builder.beginEntry(a) - builder.putField("cachedDescriptor", { b => - b.hintTag(fileTag) - filePickler.pickle(a.cachedDescriptor, b) - }) - builder.putField("configurations", { b => - b.hintTag(vectorConfigurationReportTag) - vectorConfigurationReportPickler.pickle(a.configurations.toVector, b) - }) - builder.putField("stats", { b => - b.hintTag(updateStatsTag) - updateStatsPickler.pickle(a.stats, b) - }) - builder.putField("stamps", { b => - b.hintTag(flMapTag) - flMapPickler.pickle(a.stamps, b) - }) - builder.endEntry() - builder.popHints() - () - } - - def unpickle(tpe: String, reader: PReader): Any = { - reader.pushHints() - reader.hintTag(tag) - reader.beginEntry() - val cachedDescriptor = filePickler.unpickleEntry(reader.readField("cachedDescriptor")).asInstanceOf[File] - val configurations = vectorConfigurationReportUnpickler.unpickleEntry(reader.readField("configurations")).asInstanceOf[Vector[ConfigurationReport]] - val stats = updateStatsUnpickler.unpickleEntry(reader.readField("stats")).asInstanceOf[UpdateStats] - val stamps = flMapUnpickler.unpickleEntry(reader.readField("stamps")).asInstanceOf[Map[File, Long]] - val result = new UpdateReport(cachedDescriptor, configurations, stats, stamps) - reader.endEntry() - reader.popHints() - result - } - } -} - -final class UpdateStats(val resolveTime: Long, val downloadTime: Long, val downloadSize: Long, val cached: Boolean) { - override def toString = Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") - private[sbt] def withCached(c: Boolean): UpdateStats = - new UpdateStats( - resolveTime = this.resolveTime, - downloadTime = this.downloadTime, - downloadSize = this.downloadSize, - cached = c - ) -} -object UpdateStats { - implicit val pickler: Pickler[UpdateStats] with Unpickler[UpdateStats] = PicklerUnpickler.generate[UpdateStats] } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala index 24e6eee19..a1892b2f0 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala @@ -1,6 +1,6 @@ package sbt -package object librarymanagement { +package object librarymanagement extends ResolversSyntax { type ExclusionRule = InclExclRule val ExclusionRule = InclExclRule diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 7e561640d..a0f4bdfc0 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -10,22 +10,32 @@ import sbt.librarymanagement._ import ivyint.SbtChainResolver import Configurations._ +import sbt.internal.util.FileBasedStore + +import sjsonnew.IsoString +import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } + +import scala.json.ast.unsafe.JValue + trait BaseIvySpecification extends UnitSpec { def currentBase: File = new File(".") def currentTarget: File = currentBase / "target" / "ivyhome" def currentManaged: File = currentBase / "target" / "lib_managed" def currentDependency: File = currentBase / "target" / "dependency" - def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) + def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) + + implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) + val fileToStore = (f: File) => new FileBasedStore(f, Converter) lazy val log = ConsoleLogger() - def configurations = Seq(Compile, Test, Runtime) - def module(moduleId: ModuleID, deps: Seq[ModuleID], scalaFullVersion: Option[String], + def configurations = Vector(Compile, Test, Runtime) + def module(moduleId: ModuleID, deps: Vector[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => new IvyScala( scalaFullVersion = fv, scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), - configurations = Nil, + configurations = Vector.empty, checkExplicit = true, filterImplicit = false, overrideScalaVersion = overrideScalaVersion @@ -33,32 +43,32 @@ trait BaseIvySpecification extends UnitSpec { } val moduleSetting: ModuleSettings = InlineConfiguration( + false, + ivyScala, module = moduleId, moduleInfo = ModuleInfo("foo"), - dependencies = deps, - configurations = configurations, - ivyScala = ivyScala - ) - val ivySbt = new IvySbt(mkIvyConfiguration(uo)) + dependencies = deps + ).withConfigurations(configurations) + val ivySbt = new IvySbt(mkIvyConfiguration(uo), fileToStore) new ivySbt.Module(moduleSetting) } - def resolvers: Seq[Resolver] = Seq(DefaultMavenRepository) + def resolvers: Vector[Resolver] = Vector(DefaultMavenRepository) def chainResolver = ChainedResolver("sbt-chain", resolvers) def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = new IvyPaths(currentBase, Some(currentTarget)) - val other = Nil - val moduleConfs = Seq(ModuleConfiguration("*", chainResolver)) + val other = Vector.empty + val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val off = false - val check = Nil + val check = Vector.empty val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) } def makeUpdateConfiguration: UpdateConfiguration = { - val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern, false) + val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) } @@ -84,7 +94,7 @@ trait BaseIvySpecification extends UnitSpec { ivyFile = None, resolverName = resolver.name, artifacts = artifacts, - checksums = Seq(), + checksums = Vector.empty, logging = UpdateLogging.Full, overwrite = true ) diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 4fc6faa3e..85796bd20 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -9,8 +9,8 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving the same module twice" should "work" in { cleanIvyCache() val m = module( - ModuleID("com.example", "foo", "0.1.0", Some("compile")), - Seq(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), + Vector(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true) ) val report = ivyUpdate(m) cleanCachedResolutionCache(m) @@ -25,8 +25,8 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving the unsolvable module should" should "not work" in { // log.setLevel(Level.Debug) val m = module( - ModuleID("com.example", "foo", "0.2.0", Some("compile")), - Seq(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + ModuleID("com.example", "foo", "0.2.0").withConfigurations(Some("compile")), + Vector(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true) ) ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed") @@ -52,8 +52,8 @@ class CachedResolutionSpec extends BaseIvySpecification { // log.setLevel(Level.Debug) cleanIvyCache() val m = module( - ModuleID("com.example", "foo", "0.3.0", Some("compile")), - Seq(avro177, dataAvro1940, netty320), + ModuleID("com.example", "foo", "0.3.0").withConfigurations(Some("compile")), + Vector(avro177, dataAvro1940, netty320), Some("2.10.2"), UpdateOptions().withCachedResolution(true) ) // first resolution creates the minigraph @@ -66,11 +66,11 @@ class CachedResolutionSpec extends BaseIvySpecification { assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final""" })) } - def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) - def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2", Some("compile")) - def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7", Some("compile")) - def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40", Some("compile")) - def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final", Some("compile")) + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) + def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations(Some("compile")) + def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7").withConfigurations(Some("compile")) + def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile")) + def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile")) def defaultOptions = EvictionWarningOptions.default } diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index f70343e73..921ee1b18 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -116,7 +116,7 @@ class CrossVersionTest extends UnitSpec { CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" } it should "return disabled cross version as equal to a copy" in { - CrossVersion.Disabled shouldBe CrossVersion.Disabled + Disabled() shouldBe Disabled() } it should "return full cross version as equal to a copy" in { CrossVersion.full shouldBe CrossVersion.full diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 16874c3d3..e90b0ba20 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -16,8 +16,8 @@ class CustomPomParserTest extends UnitSpec { val repoUrl = getClass.getResource("/test-maven-repo") val local = MavenRepository("Test Repo", repoUrl.toExternalForm) val paths = new IvyPaths(new File("."), Some(cacheDir)) - val conf = new InlineIvyConfiguration(paths, Seq(local), Nil, Nil, false, None, Seq("sha1", "md5"), None, UpdateOptions(), log) - val ivySbt = new IvySbt(conf) + val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, None, Vector("sha1", "md5"), None, UpdateOptions(), log) + val ivySbt = new IvySbt(conf, DefaultFileToStore) val resolveOpts = new ResolveOptions().setConfs(Array("default")) val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index ab4d9f78c..ab1bb457b 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -2,8 +2,12 @@ package sbt.librarymanagement import java.net.URL import java.io.File -import sbt.serialization._ -import sbt.internal.util.UnitSpec + +import sbt.internal._, librarymanagement._, util.UnitSpec +import scala.json.ast.unsafe._ +import sjsonnew._, support.scalajson.unsafe._ + +import LibraryManagementCodec._ class DMSerializationSpec extends UnitSpec { "CrossVersion.full" should "roundtrip" in { @@ -13,7 +17,7 @@ class DMSerializationSpec extends UnitSpec { roundtripStr(CrossVersion.binary: CrossVersion) } "CrossVersion.Disabled" should "roundtrip" in { - roundtrip(CrossVersion.Disabled: CrossVersion) + roundtrip(Disabled(): CrossVersion) } """Artifact("foo")""" should "roundtrip" in { roundtrip(Artifact("foo")) @@ -34,7 +38,7 @@ class DMSerializationSpec extends UnitSpec { roundtrip(ModuleID("org", "name", "1.0")) } """ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)""" should "roundtrip" in { - roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)) + roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty)) } "Organization artifact report" should "roundtrip" in { roundtripStr(organizationArtifactReportExample) @@ -55,17 +59,19 @@ class DMSerializationSpec extends UnitSpec { lazy val organizationArtifactReportExample = new OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) lazy val moduleReportExample = - ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) + ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) - def roundtrip[A: Pickler: Unpickler](a: A): Unit = + def roundtrip[A: JsonReader: JsonWriter](a: A): Unit = roundtripBuilder(a) { _ shouldBe _ } - def roundtripStr[A: Pickler: Unpickler](a: A): Unit = + def roundtripStr[A: JsonReader: JsonWriter](a: A): Unit = roundtripBuilder(a) { _.toString shouldBe _.toString } - def roundtripBuilder[A: Pickler: Unpickler](a: A)(f: (A, A) => Unit): Unit = + def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit = { - val json = toJsonString(a) + val json = isoString to (Converter toJsonUnsafe a) println(json) - val obj = fromJsonString[A](json).get + val obj = Converter fromJsonUnsafe[A] (isoString from json) f(a, obj) } + + implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) } diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index c1a77bf31..21d59b10a 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -44,25 +44,25 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "be detected if it's enabled" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() - def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary - def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary - def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4", Some("compile")) cross CrossVersion.binary - def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2", Some("compile")) - def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3", Some("compile")) - def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4", Some("compile")) - def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3", Some("compile")) - def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4", Some("compile")) - def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4", Some("compile")) - def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0", Some("compile")) // uses commons-io 2.4 - def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0", Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 - def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 - def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4", Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) + def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3").withConfigurations(Some("compile")) + def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) + def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile")) + def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile")) + def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 + def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 def defaultOptions = EvictionWarningOptions.default import sbt.internal.util.ShowLines._ - def scalaVersionDeps = Seq(scala2102, akkaActor230) + def scalaVersionDeps = Vector(scala2102, akkaActor230) def scalaVersionWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) @@ -113,7 +113,7 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) } - def javaLibDirectDeps = Seq(commonsIo14, commonsIo24) + def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) def javaLibWarn1() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) @@ -151,20 +151,20 @@ class EvictionWarningSpec extends BaseIvySpecification { } def javaLibNoWarn1() = { - val deps = Seq(commonsIo14, commonsIo13) + val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } def javaLibNoWarn2() = { - val deps = Seq(commonsIo14, commonsIo13) + val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil } - def javaLibTransitiveDeps = Seq(unfilteredUploads080, bnfparser10) + def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) def javaLibTransitiveWarn1() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) @@ -190,14 +190,14 @@ class EvictionWarningSpec extends BaseIvySpecification { } def scalaLibWarn1() = { - val deps = Seq(scala2104, akkaActor214, akkaActor234) + val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } def scalaLibWarn2() = { - val deps = Seq(scala2104, akkaActor214, akkaActor234) + val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe @@ -210,20 +210,20 @@ class EvictionWarningSpec extends BaseIvySpecification { } def scalaLibNoWarn1() = { - val deps = Seq(scala2104, akkaActor230, akkaActor234) + val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) } def scalaLibNoWarn2() = { - val deps = Seq(scala2104, akkaActor230, akkaActor234) + val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil } - def scalaLibTransitiveDeps = Seq(scala2104, bananaSesame04, akkaRemote234) + def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) def scalaLibTransitiveWarn1() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index 1e94e1196..4e0866d6c 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -20,7 +20,7 @@ class InconsistentDuplicateSpec extends UnitSpec { IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil } - def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4", Some("compile")) cross CrossVersion.binary - def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("compile")) cross CrossVersion.binary - def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0", Some("test")) cross CrossVersion.binary + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary } diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index 499e86db4..b2625304e 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -8,8 +8,8 @@ import sbt.internal.util.UnitSpec object ResolverTest extends UnitSpec { "Resolver url" should "propagate pattern descriptorOptional and skipConsistencyCheck." in { - val pats = Seq("[orgPath]") - val patsExpected = Seq("http://foo.com/test/[orgPath]") + val pats = Vector("[orgPath]") + val patsExpected = Vector("http://foo.com/test/[orgPath]") val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns patterns.ivyPatterns shouldBe patsExpected diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index 60e9f2dd7..27936225f 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -9,10 +9,10 @@ import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport } class FakeResolverSpecification extends BaseIvySpecification { import FakeResolver._ - val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT", Some("compile")) - val example = ModuleID("com.example", "example", "1.0.0", Some("compile")) - val anotherExample = ModuleID("com.example", "another-example", "1.0.0", Some("compile")) - val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3", Some("compile")) + val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT").withConfigurations(Some("compile")) + val example = ModuleID("com.example", "example", "1.0.0").withConfigurations(Some("compile")) + val anotherExample = ModuleID("com.example", "another-example", "1.0.0").withConfigurations(Some("compile")) + val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile")) "The FakeResolver" should "find modules with only one artifact" in { val m = getModule(myModule) @@ -66,8 +66,8 @@ class FakeResolverSpecification extends BaseIvySpecification { ) private def fakeResolver = new FakeResolver("FakeResolver", new File("tmp"), modules) - override def resolvers: Seq[Resolver] = Seq(new RawRepository(fakeResolver)) - private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Seq(myModule), None) + override def resolvers: Vector[Resolver] = Vector(new RawRepository(fakeResolver)) + private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Vector(myModule), None) private def getAllFiles(report: UpdateReport) = for { conf <- report.configurations @@ -75,4 +75,4 @@ class FakeResolverSpecification extends BaseIvySpecification { (_, f) <- m.artifacts } yield f -} \ No newline at end of file +} diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 9e15fbc01..fd7896c5b 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -6,7 +6,7 @@ import sbt.librarymanagement._ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { - val ourModuleID = ModuleID("com.example", "foo", "0.1.0", Some("compile")) + val ourModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) def makeModuleForDepWithSources = { // By default a module seems to only have [compile, test, runtime], yet deps automatically map to @@ -15,7 +15,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { module( ourModuleID, - Seq(dep), None //, UpdateOptions().withCachedResolution(true) + Vector(dep), None //, UpdateOptions().withCachedResolution(true) ) } @@ -50,7 +50,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val docTypes = Set("javadoc") // These will be the default classifiers that SBT should try, in case a dependency is Maven. // In this case though, they will be tried and should fail gracefully - only the - val attemptedClassifiers = Seq("sources", "javadoc") + val attemptedClassifiers = Vector("sources", "javadoc") // The dep that we want to get the "classifiers" (i.e. sources / docs) for. // We know it has only one source artifact in the "compile" configuration. @@ -59,12 +59,12 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val clMod = { import language.implicitConversions implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision) - val externalModules = Seq(dep) + val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) - GetClassifiersModule(ourModuleID, externalModules, Seq(Configurations.Compile), attemptedClassifiers) + GetClassifiersModule(ourModuleID, externalModules, Vector(Configurations.Compile), attemptedClassifiers) } - val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.copy(artifactFilter = c.artifactFilter.invert), ivyScala, srcTypes, docTypes) + val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.withArtifactFilter(c.artifactFilter.invert), ivyScala, srcTypes, docTypes) val report2 = IvyActions.updateClassifiers(m.owner, gcm, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) @@ -80,7 +80,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { } } - override lazy val resolvers: Seq[Resolver] = Seq(testIvy) + override lazy val resolvers: Vector[Resolver] = Vector(testIvy) lazy val testIvy = { val repoUrl = getClass.getResource("/test-ivy-repo") diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala new file mode 100644 index 000000000..a83fb618a --- /dev/null +++ b/project/DatatypeConfig.scala @@ -0,0 +1,61 @@ +import sbt.datatype.{ CodecCodeGen, TpeRef } + +object DatatypeConfig { + + /** Extract the only type parameter from a TpeRef */ + def oneArg(tpe: TpeRef): TpeRef = { + val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?)[>\\]]""".r + val pat(arg0) = tpe.name + TpeRef(arg0, false, false, false) + } + + /** Extract the two type parameters from a TpeRef */ + def twoArgs(tpe: TpeRef): List[TpeRef] = { + val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?), (.+?)[>\\]]""".r + val pat(arg0, arg1) = tpe.name + TpeRef(arg0, false, false, false) :: TpeRef(arg1, false, false, false) :: Nil + } + + /** Codecs that were manually written. */ + val myCodecs: PartialFunction[String, TpeRef => List[String]] = { + case "java.util.Date" => { _ => "sbt.internal.librarymanagement.formats.DateFormat" :: Nil } + + case "Function1" => + { tpe => "sbt.internal.librarymanagement.formats.Function1Format" :: twoArgs(tpe).flatMap(getFormats) } + + case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil } + + case "org.apache.ivy.plugins.resolver.DependencyResolver" => + { _ => "sbt.internal.librarymanagement.formats.DependencyResolverFormat" :: Nil } + + case "xsbti.GlobalLock" => { _ => "sbt.internal.librarymanagement.formats.GlobalLockFormat" :: Nil } + case "xsbti.Logger" => { _ => "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil } + + case "sbt.librarymanagement.UpdateOptions" => + { _ => "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil } + + // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo + case "Option" | "Set" => { tpe => getFormats(oneArg(tpe)) } + case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) } + case "Int" | "Long" => { _ => Nil } + } + + /** Types for which we don't include the format -- they're just aliases to InclExclRule */ + val excluded = Set( + "sbt.librarymanagement.InclusionRule", + "sbt.librarymanagement.ExclusionRule") + + /** Returns the list of formats required to encode the given `TpeRef`. */ + val getFormats: TpeRef => List[String] = + CodecCodeGen.extensibleFormatsForType { + case TpeRef("sbt.internal.librarymanagement.RetrieveConfiguration", false, false, false) => + "sbt.librarymanagement.RetrieveConfigurationFormats" :: Nil + case tpe @ TpeRef(name, _, _, _) if myCodecs isDefinedAt CodecCodeGen.removeTypeParameters(name) => + myCodecs(CodecCodeGen.removeTypeParameters(name))(tpe) + case TpeRef(name, _, _, _) if excluded contains CodecCodeGen.removeTypeParameters(name) => + Nil + case other => + CodecCodeGen.formatsForType(other) + } + +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8232a3c7e..250adc2e2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ object Dependencies { lazy val scala211 = "2.11.8" val ioVersion = "1.0.0-M6" - val utilVersion = "0.1.0-M13" + val utilVersion = "0.1.0-M15" private lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -43,6 +43,16 @@ object Dependencies { lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () - lazy val sbtSerialization = "org.scala-sbt" %% "serialization" % "0.1.2" lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } + lazy val scalaXml = scala211Module("scala-xml", "1.0.5") + lazy val sjsonnewVersion = "0.4.1" + lazy val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion + + private def scala211Module(name: String, moduleVersion: String) = + Def.setting { + scalaVersion.value match { + case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil + case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil + } + } } diff --git a/project/build.properties b/project/build.properties index 817bc38df..27e88aa11 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.9 +sbt.version=0.13.13 diff --git a/project/sbt-datatype.sbt b/project/sbt-datatype.sbt new file mode 100644 index 000000000..c13a23ad7 --- /dev/null +++ b/project/sbt-datatype.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scala-sbt" % "sbt-datatype" % "0.2.8") From 5475a3c01ca0e375be1e943fe4942560c889f6d4 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 01:41:47 +0000 Subject: [PATCH 0536/1030] Switch to FooExtra naming convention for contraband parents --- .../src/main/datatype/librarymanagement.json | 14 +++++++------- .../scala/sbt/librarymanagement/Artifact.scala | 2 +- .../sbt/librarymanagement/Configuration.scala | 2 +- .../scala/sbt/librarymanagement/IvyInterface.scala | 2 +- .../scala/sbt/librarymanagement/ModuleID.scala | 2 +- .../scala/sbt/librarymanagement/UpdateReport.scala | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index 102b22748..46fbbe0b5 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -27,7 +27,7 @@ "Provides information about the resolution of a module.", "This information is in the context of a specific configuration." ], - "parents": "sbt.librarymanagement.ModuleReportParent", + "parents": "sbt.librarymanagement.ModuleReportExtra", "fields": [ { "name": "module", "type": "sbt.librarymanagement.ModuleID" }, { "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*" }, @@ -343,7 +343,7 @@ "target": "Scala", "type": "record", "doc": "Represents an Ivy configuration.", - "parents": "sbt.librarymanagement.ConfigurationParent", + "parents": "sbt.librarymanagement.ConfigurationExtra", "fields": [ { "name": "name", "type": "String" }, { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, @@ -358,7 +358,7 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", - "parents": "sbt.librarymanagement.ArtifactParent", + "parents": "sbt.librarymanagement.ArtifactExtra", "fields": [ { "name": "name", "type": "String" }, { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, @@ -672,7 +672,7 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", - "parents": "sbt.librarymanagement.ModuleIDParent", + "parents": "sbt.librarymanagement.ModuleIDExtra", "fields": [ { "name": "organization", "type": "String" }, { "name": "name", "type": "String" }, @@ -701,7 +701,7 @@ "target": "Scala", "type": "record", "doc": "Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)", - "parents": "sbt.librarymanagement.ArtifactTypeFilterParent", + "parents": "sbt.librarymanagement.ArtifactTypeFilterExtra", "fields": [ { "name": "types", @@ -730,7 +730,7 @@ "It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.", "This means that for a given configuration, there should only be one revision for a given organization and module name." ], - "parents": "sbt.librarymanagement.UpdateReportParent", + "parents": "sbt.librarymanagement.UpdateReportExtra", "fields": [ { "name": "cachedDescriptor", @@ -759,7 +759,7 @@ "doc": [ "Provides information about resolution of a single configuration." ], - "parents": "sbt.librarymanagement.ConfigurationReportParent", + "parents": "sbt.librarymanagement.ConfigurationReportExtra", "fields": [ { "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] }, { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 7b843546a..590d686c8 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement import java.io.File import java.net.URL -abstract class ArtifactParent { +abstract class ArtifactExtra { def name: String def `type`: String def extension: String diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index ad064f550..f0d0fff7f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -49,7 +49,7 @@ object Configurations { private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) } -abstract class ConfigurationParent { +abstract class ConfigurationExtra { def name: String def description: String def isPublic: Boolean diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 275856dcd..538dd0b80 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -10,7 +10,7 @@ abstract class InclExclRuleCompanion { def everything = new InclExclRule("*", "*", "*", Vector.empty) } -abstract class ArtifactTypeFilterParent { +abstract class ArtifactTypeFilterExtra { def types: Set[String] def inverted: Boolean diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 3716ac790..2f802017e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -7,7 +7,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties -abstract class ModuleIDParent { +abstract class ModuleIDExtra { def organization: String def name: String def revision: String diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala index fb0b0a87b..ecc81493b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement import java.io.File import java.{ util => ju } -abstract class ConfigurationReportParent { +abstract class ConfigurationReportExtra { def configuration: String def modules: Vector[ModuleReport] def details: Vector[OrganizationArtifactReport] @@ -36,7 +36,7 @@ abstract class ConfigurationReportParent { new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) } -abstract class ModuleReportParent { +abstract class ModuleReportExtra { def module: ModuleID def artifacts: Vector[(Artifact, File)] def missingArtifacts: Vector[Artifact] @@ -120,7 +120,7 @@ abstract class ModuleReportParent { ): ModuleReport } -abstract class UpdateReportParent { +abstract class UpdateReportExtra { def cachedDescriptor: File def configurations: Vector[ConfigurationReport] def stats: UpdateStats From e7ba7fa9a442f5e6467ef18fd702db5803f02906 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 09:55:43 +0000 Subject: [PATCH 0537/1030] Switch to FooFunctions naming convention for contraband companion parents --- .../src/main/datatype/librarymanagement.json | 20 +++++++++---------- .../librarymanagement/IvyConfigurations.scala | 2 +- .../sbt/librarymanagement/Artifact.scala | 2 +- .../sbt/librarymanagement/CrossVersion.scala | 2 +- .../sbt/librarymanagement/IvyInterface.scala | 6 +++--- .../sbt/librarymanagement/IvyScala.scala | 2 +- .../sbt/librarymanagement/ModuleID.scala | 2 +- .../sbt/librarymanagement/Resolver.scala | 4 ++-- 8 files changed, 20 insertions(+), 20 deletions(-) diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index 46fbbe0b5..7e01e4424 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -192,7 +192,7 @@ { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "module", "type": "String", "default": "\"*\"", "since": "0.0.1" } ], - "parentsCompanion": "sbt.librarymanagement.ConflictManagerCompanion" + "parentsCompanion": "sbt.librarymanagement.ConflictManagerFunctions" }, { "name": "IvyScala", @@ -209,7 +209,7 @@ { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, { "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } ], - "parentsCompanion": "sbt.librarymanagement.IvyScalaCompanion" + "parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions" }, { "name": "ModuleSettings", @@ -257,7 +257,7 @@ { "name": "defaultConfiguration", "type": "sbt.librarymanagement.Configuration?", "default": "None", "since": "0.0.1" }, { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } ], - "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationCompanion" + "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationFunctions" } ] }, @@ -290,7 +290,7 @@ { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" } ], - "parentsCompanion": "sbt.librarymanagement.InclExclRuleCompanion" + "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" }, { "name": "CrossVersion", @@ -335,7 +335,7 @@ ] } ], - "parentsCompanion": "sbt.librarymanagement.CrossVersionCompanion" + "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" }, { "name": "Configuration", @@ -368,7 +368,7 @@ { "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } ], - "parentsCompanion": "sbt.librarymanagement.ArtifactCompanion" + "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" }, { "name": "SshAuthentication", @@ -437,7 +437,7 @@ "\"Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)\".format(", " ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck)" ], - "parentsCompanion": "sbt.librarymanagement.PatternsCompanion" + "parentsCompanion": "sbt.librarymanagement.PatternsFunctions" }, { "name": "Resolver", @@ -575,7 +575,7 @@ ] } ], - "parentsCompanion": "sbt.librarymanagement.ResolverCompanion" + "parentsCompanion": "sbt.librarymanagement.ResolverFunctions" }, { "name": "ModuleConfiguration", @@ -693,7 +693,7 @@ " (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +", " (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)" ], - "parentsCompanion": "sbt.librarymanagement.ModuleIDCompanion" + "parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions" }, { "name": "ArtifactTypeFilter", @@ -718,7 +718,7 @@ "type": "boolean" } ], - "parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterCompanion" + "parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterFunctions" }, { "name": "UpdateReport", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 96cdf1585..74bdde758 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -5,7 +5,7 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ -abstract class InlineConfigurationCompanion { +abstract class InlineConfigurationFunctions { def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = if (explicitConfigurations.isEmpty) { defaultConfiguration match { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala index 590d686c8..e3a2d2793 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala @@ -30,7 +30,7 @@ abstract class ArtifactExtra { import Configurations.{ Optional, Pom, Test } -abstract class ArtifactCompanion { +abstract class ArtifactFunctions { def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra) def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None) def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Vector.empty, None) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 88b15cf6a..77cf913ed 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -5,7 +5,7 @@ import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) -abstract class CrossVersionCompanion { +abstract class CrossVersionFunctions { /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 538dd0b80..cded9dcb5 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement import org.apache.ivy.core.module.descriptor import org.apache.ivy.util.filter.{ Filter => IvyFilter } -abstract class InclExclRuleCompanion { +abstract class InclExclRuleFunctions { def everything = new InclExclRule("*", "*", "*", Vector.empty) } @@ -20,7 +20,7 @@ abstract class ArtifactTypeFilterExtra { def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted } -abstract class ArtifactTypeFilterCompanion { +abstract class ArtifactTypeFilterFunctions { def allow(types: Set[String]) = ArtifactTypeFilter(types, false) def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) @@ -29,7 +29,7 @@ abstract class ArtifactTypeFilterCompanion { } } -abstract class ConflictManagerCompanion { +abstract class ConflictManagerFunctions { // To avoid NPE (or making the val's below lazy) // For case classes refchecks rewrites apply calls to constructor calls, we have to do it manually def apply(name: String, organization: String = "*", module: String = "*"): ConflictManager diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala index c45b84799..39ecbace4 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala @@ -45,7 +45,7 @@ object SbtArtifacts { import ScalaArtifacts._ -private[sbt] abstract class IvyScalaCompanion { +private[sbt] abstract class IvyScalaFunctions { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index 2f802017e..d3bb3feaa 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -151,7 +151,7 @@ abstract class ModuleIDExtra { def branch(branchName: Option[String]) = copy(branchName = branchName) } -abstract class ModuleIDCompanion { +abstract class ModuleIDFunctions { /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 12a4c03f6..75be6d228 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -26,7 +26,7 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver(res } } -abstract class PatternsCompanion { +abstract class PatternsFunctions { implicit def defaultPatterns: Patterns = Resolver.defaultPatterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*) @@ -48,7 +48,7 @@ trait ResolversSyntax { val JCenterRepository = new MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) } -abstract class ResolverCompanion { +abstract class ResolverFunctions { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) From 301ec787f2f17367064cda5eef3a9009ba66e21f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 10:11:41 +0000 Subject: [PATCH 0538/1030] Drop "serialising" Function1. It's easily fallible --- .../src/main/datatype/librarymanagement.json | 8 +------ .../formats/Function1Format.scala | 8 ------- .../sbt/librarymanagement/CrossVersion.scala | 23 ++++--------------- .../sbt/librarymanagement/ModuleID.scala | 3 --- project/DatatypeConfig.scala | 3 --- 5 files changed, 5 insertions(+), 40 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index 7e01e4424..940f65d2d 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -315,10 +315,7 @@ "For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",", "the module is cross-versioned with \"2.10\"." ], - "type": "record", - "fields": [ - { "name": "remapVersion", "type": "Function1[String, String]" } - ] + "type": "record" }, { "name": "Full", @@ -329,9 +326,6 @@ "Cross-versions a module with the result of applying `remapVersion` to the full version.", "For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",", "the module is cross-versioned with \"2.10\"." - ], - "fields": [ - { "name": "remapVersion", "type": "Function1[String, String]" } ] } ], diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala deleted file mode 100644 index 12f4f2f94..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/Function1Format.scala +++ /dev/null @@ -1,8 +0,0 @@ -package sbt.internal.librarymanagement.formats - -import sjsonnew._ - -trait Function1Format { self: BasicJsonProtocol => - implicit def Function1Format[T, U]: JsonFormat[T => U] = - project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[T => U])) -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 77cf913ed..d212e0e0a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -13,25 +13,10 @@ abstract class CrossVersionFunctions { val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion /** Cross-versions a module with the full version (typically the full Scala version). */ - def full: CrossVersion = new Full(idStringFun) - - /** - * Cross-versions a module with the result of applying `remapVersion` to the full version - * (typically the full Scala version). See also [[sbt.librarymanagement.CrossVersion.Full]]. - */ - def fullMapped(remapVersion: String => String): CrossVersion = new Full(remapVersion) + def full: CrossVersion = new Full() /** Cross-versions a module with the binary version (typically the binary Scala version). */ - def binary: CrossVersion = new Binary(idStringFun) - - /** - * Cross-versions a module with the result of applying `remapVersion` to the binary version - * (typically the binary Scala version). See also [[sbt.librarymanagement.CrossVersion.Binary]]. - */ - def binaryMapped(remapVersion: String => String): CrossVersion = new Binary(remapVersion) - - private[this] def idFun[T]: T => T = x => x - private[this] val idStringFun = idFun[String] + def binary: CrossVersion = new Binary() private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s)) @@ -43,8 +28,8 @@ abstract class CrossVersionFunctions { def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { case _: Disabled => None - case b: Binary => append(b.remapVersion(binaryVersion)) - case f: Full => append(f.remapVersion(fullVersion)) + case _: Binary => append(binaryVersion) + case _: Full => append(fullVersion) } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala index d3bb3feaa..e4f12fd3d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala @@ -47,9 +47,6 @@ abstract class ModuleIDExtra { @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled()) - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") - def cross(v: Boolean, verRemap: String => String): ModuleID = cross(if (v) CrossVersion.binaryMapped(verRemap) else Disabled()) - /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index a83fb618a..78159c476 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -20,9 +20,6 @@ object DatatypeConfig { val myCodecs: PartialFunction[String, TpeRef => List[String]] = { case "java.util.Date" => { _ => "sbt.internal.librarymanagement.formats.DateFormat" :: Nil } - case "Function1" => - { tpe => "sbt.internal.librarymanagement.formats.Function1Format" :: twoArgs(tpe).flatMap(getFormats) } - case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil } case "org.apache.ivy.plugins.resolver.DependencyResolver" => From b2b606f8aa623f939d04c5edbe9a03290ca62862 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 10:43:16 +0000 Subject: [PATCH 0539/1030] Actually, just kill the crazy MyCrazyReferences idea --- .../formats/DependencyResolverFormat.scala | 6 +----- .../formats/GlobalLockFormat.scala | 3 +-- .../librarymanagement/formats/LoggerFormat.scala | 3 +-- .../formats/MyCrazyReferences.scala | 15 --------------- .../librarymanagement/formats/NodeSeqFormat.scala | 3 +-- 5 files changed, 4 insertions(+), 26 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala index 3a8920373..e365b961b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala @@ -4,9 +4,5 @@ import sjsonnew._ import org.apache.ivy.plugins.resolver.DependencyResolver trait DependencyResolverFormat { self: BasicJsonProtocol => - implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] = - project( - MyCrazyReferences.referenced _, - (ref: String) => MyCrazyReferences(ref, classOf[DependencyResolver]) - ) + implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] = ??? } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala index fda66ae6b..2f4342d24 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala @@ -4,6 +4,5 @@ import sjsonnew._ import xsbti._ trait GlobalLockFormat { self: BasicJsonProtocol => - implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = - project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[GlobalLock])) + implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = ??? } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala index 5b84703d9..b751672bd 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala @@ -4,6 +4,5 @@ import sjsonnew._ import xsbti._ trait LoggerFormat { self: BasicJsonProtocol => - implicit lazy val LoggerFormat: JsonFormat[Logger] = - project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[Logger])) + implicit lazy val LoggerFormat: JsonFormat[Logger] = ??? } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala deleted file mode 100644 index 7051e327e..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/MyCrazyReferences.scala +++ /dev/null @@ -1,15 +0,0 @@ -package sbt.internal.librarymanagement.formats - -import scala.collection.mutable - -object MyCrazyReferences { - private val references: mutable.Map[String, Any] = mutable.Map.empty - - def apply[T](key: String, clazz: Class[T]): T = synchronized(clazz.cast(references(key))) - - def referenced[T](value: T): String = synchronized { - val key = java.util.UUID.randomUUID.toString - references(key) = value - key - } -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala index df862fb61..ad527c35d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala @@ -4,6 +4,5 @@ import sjsonnew._ import scala.xml._ trait NodeSeqFormat { self: BasicJsonProtocol => - implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = - project(MyCrazyReferences.referenced _, (ref: String) => MyCrazyReferences(ref, classOf[NodeSeq])) + implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = ??? } From f6c98f69b9848f7b441fa951c853e5ad1a92faa4 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 10:52:42 +0000 Subject: [PATCH 0540/1030] Organise contraband descriptor by package name & alphabetically --- .../src/main/datatype/librarymanagement.json | 861 +++++++++--------- 1 file changed, 431 insertions(+), 430 deletions(-) diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index 940f65d2d..994dba15e 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -2,6 +2,48 @@ "codecNamespace": "sbt.librarymanagement", "fullCodec": "LibraryManagementCodec", "types": [ + { + "name": "Artifact", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "parents": "sbt.librarymanagement.ArtifactExtra", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, + { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, + { "name": "classifier", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" + }, + { + "name": "ArtifactTypeFilter", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)", + "parents": "sbt.librarymanagement.ArtifactTypeFilterExtra", + "fields": [ + { + "name": "types", + "doc": [ + "Represents the artifact types that we should try to resolve for (as in the allowed values of", + "`artifact[type]` from a dependency `` section). One can use this to filter", + "source / doc artifacts." + ], + "type": "Set[String]" + }, + { + "name": "inverted", + "doc": [ "Whether to invert the types filter (i.e. allow only types NOT in the set)" ], + "type": "boolean" + } + ], + "parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterFunctions" + }, { "name": "Caller", "namespace": "sbt.librarymanagement", @@ -18,6 +60,222 @@ ], "toString": "s\"$caller\"" }, + { + "name": "Configuration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Represents an Ivy configuration.", + "parents": "sbt.librarymanagement.ConfigurationExtra", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" } + ], + "toString": "name" + }, + { + "name": "ConfigurationReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Provides information about resolution of a single configuration." + ], + "parents": "sbt.librarymanagement.ConfigurationReportExtra", + "fields": [ + { "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] }, + { + "name": "modules", + "type": "sbt.librarymanagement.ModuleReport*", + "doc": [ + "a sequence containing one report for each module resolved for this configuration." + ] + }, + { + "name": "details", + "type": "sbt.librarymanagement.OrganizationArtifactReport*", + "doc": [ "a sequence containing one report for each org/name, which may or may not be part of the final resolution." ] + } + ] + }, + { + "name": "ConflictManager", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.", + "fields": [ + { "name": "name", "type": "String" }, + { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "module", "type": "String", "default": "\"*\"", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.ConflictManagerFunctions" + }, + { + "name": "CrossVersion", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "doc": "Configures how a module will be cross-versioned.", + "types": [ + { + "name": "Disabled", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": "Disables cross versioning for a module.", + "type": "record" + }, + { + "name": "Binary", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": [ + "Cross-versions a module using the result of applying `remapVersion` to the binary version.", + "For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",", + "the module is cross-versioned with \"2.10\"." + ], + "type": "record" + }, + { + "name": "Full", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Cross-versions a module with the result of applying `remapVersion` to the full version.", + "For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",", + "the module is cross-versioned with \"2.10\"." + ] + } + ], + "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" + }, + { + "name": "Developer", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "id", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "email", "type": "String" }, + { "name": "url", "type": "java.net.URL" } + ] + }, + { + "name": "FileConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Configuration specific to an Ivy filesystem resolver.", + "fields": [ + { "name": "isLocal", "type": "boolean" }, + { "name": "isTransactional", "type": "boolean?" } + ] + }, + { + "name": "InclExclRule", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Rule to either:", + "
    ", + "
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • ", + "
  • include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
  • ", + "
", + "Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases." + ], + "fields": [ + { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" + }, + { + "name": "IvyScala", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "scalaFullVersion", "type": "String" }, + { "name": "scalaBinaryVersion", "type": "String" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, + { "name": "checkExplicit", "type": "boolean" }, + { "name": "filterImplicit", "type": "boolean" }, + { "name": "overrideScalaVersion", "type": "boolean" }, + { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, + { "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } + ], + "parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions" + }, + { + "name": "ModuleConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "revision", "type": "String" }, + { "name": "resolver", "type": "sbt.librarymanagement.Resolver" } + ], + "extraCompanion": [ + "def apply(org: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = apply(org, \"*\", \"*\", resolver)", + "def apply(org: String, name: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = ModuleConfiguration(org, name, \"*\", resolver)" + ] + }, + { + "name": "ModuleID", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "parents": "sbt.librarymanagement.ModuleIDExtra", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "revision", "type": "String" }, + { "name": "configurations", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, + { "name": "branchName", "type": "String?", "default": "None", "since": "0.0.1" } + ], + "toString": [ + "organization + \":\" + name + \":\" + revision +", + " (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +", + " (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)" + ], + "parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions" + }, + { + "name": "ModuleInfo", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Additional information about a project module", + "fields": [ + { "name": "nameFormal", "type": "String" }, + { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "homepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "startYear", "type": "int?", "default": "None", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "scmInfo", "type": "sbt.librarymanagement.ScmInfo?", "default": "None", "since": "0.0.1" }, + { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } + ] + }, { "name": "ModuleReport", "namespace": "sbt.librarymanagement", @@ -53,164 +311,6 @@ "(if (arts.size <= 1) \"\" else \"\\n\\t\\t\\t\") + arts.mkString(\"\\n\\t\\t\\t\") + \"\\n\"" ] }, - { - "name": "OrganizationArtifactReport", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.", - "In sbt's terminology, \"module\" consists of organization, name, and version.", - "In Ivy's, \"module\" means just organization and name, and the one including version numbers", - "are called revisions.", - "", - "A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.", - "(Note old evicted was just a seq of ModuleIDs).", - "OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,", - "which can be used to calculate detailed eviction warning etc." - ], - "fields": [ - { "name": "organization", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" } - ] - }, - { - "name": "UpdateStats", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "resolveTime", "type": "long" }, - { "name": "downloadTime", "type": "long" }, - { "name": "downloadSize", "type": "long" }, - { "name": "cached", "type": "boolean" } - ], - "toString": "Seq(\"Resolve time: \" + resolveTime + \" ms\", \"Download time: \" + downloadTime + \" ms\", \"Download size: \" + downloadSize + \" bytes\").mkString(\", \")" - }, - { - "name": "UpdateLogging", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "enumeration", - "doc": [ - "Configures logging during an 'update'. `level` determines the amount of other information logged.", - "`Full` is the default and logs the most.", - "`DownloadOnly` only logs what is downloaded.", - "`Quiet` only displays errors.", - "`Default` uses the current log level of `update` task." - ], - "symbols": [ "Full", "DownloadOnly", "Quiet", "Default" ] - }, - { - "name": "RetrieveConfiguration", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "retrieveDirectory", "type": "java.io.File" }, - { "name": "outputPattern", "type": "String" }, - { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "configurationsToRetrieve", "type": "Set[sbt.librarymanagement.Configuration]?", "default": "None", "since": "0.0.1" } - ] - }, - { - "name": "UpdateConfiguration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" }, - { "name": "missingOk", "type": "boolean" }, - { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, - { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" } - ] - }, - { - "name": "ScmInfo", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Basic SCM information for a project module", - "fields": [ - { "name": "browseUrl", "type": "java.net.URL" }, - { "name": "connection", "type": "String" }, - { "name": "devConnection", "type": "String?" } - ] - }, - { - "name": "Developer", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "id", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "email", "type": "String" }, - { "name": "url", "type": "java.net.URL" } - ] - }, - { - "name": "SbtExclusionRule", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "organization", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "artifact", "type": "String" }, - { "name": "configurations", "type": "String*" }, - { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" } - ] - }, - { - "name": "ModuleInfo", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Additional information about a project module", - "fields": [ - { "name": "nameFormal", "type": "String" }, - { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "homepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, - { "name": "startYear", "type": "int?", "default": "None", "since": "0.0.1" }, - { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "organizationHomepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, - { "name": "scmInfo", "type": "sbt.librarymanagement.ScmInfo?", "default": "None", "since": "0.0.1" }, - { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } - ] - }, - { - "name": "ConflictManager", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers.", - "fields": [ - { "name": "name", "type": "String" }, - { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "module", "type": "String", "default": "\"*\"", "since": "0.0.1" } - ], - "parentsCompanion": "sbt.librarymanagement.ConflictManagerFunctions" - }, - { - "name": "IvyScala", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "scalaFullVersion", "type": "String" }, - { "name": "scalaBinaryVersion", "type": "String" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, - { "name": "checkExplicit", "type": "boolean" }, - { "name": "filterImplicit", "type": "boolean" }, - { "name": "overrideScalaVersion", "type": "boolean" }, - { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, - { "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } - ], - "parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions" - }, { "name": "ModuleSettings", "namespace": "sbt.librarymanagement", @@ -262,157 +362,25 @@ ] }, { - "name": "IvyPaths", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "baseDirectory", "type": "java.io.File" }, - { "name": "ivyHome", "type": "java.io.File?" } - ] - }, - { - "name": "InclExclRule", + "name": "OrganizationArtifactReport", "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", "doc": [ - "Rule to either:", - "
    ", - "
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • ", - "
  • include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
  • ", - "
", - "Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases." + "OrganizationArtifactReport represents an organization+name entry in Ivy resolution report.", + "In sbt's terminology, \"module\" consists of organization, name, and version.", + "In Ivy's, \"module\" means just organization and name, and the one including version numbers", + "are called revisions.", + "", + "A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted.", + "(Note old evicted was just a seq of ModuleIDs).", + "OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name,", + "which can be used to calculate detailed eviction warning etc." ], "fields": [ - { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" } - ], - "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" - }, - { - "name": "CrossVersion", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "interface", - "doc": "Configures how a module will be cross-versioned.", - "types": [ - { - "name": "Disabled", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": "Disables cross versioning for a module.", - "type": "record" - }, - { - "name": "Binary", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": [ - "Cross-versions a module using the result of applying `remapVersion` to the binary version.", - "For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",", - "the module is cross-versioned with \"2.10\"." - ], - "type": "record" - }, - { - "name": "Full", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "Cross-versions a module with the result of applying `remapVersion` to the full version.", - "For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",", - "the module is cross-versioned with \"2.10\"." - ] - } - ], - "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" - }, - { - "name": "Configuration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Represents an Ivy configuration.", - "parents": "sbt.librarymanagement.ConfigurationExtra", - "fields": [ - { "name": "name", "type": "String" }, - { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" }, - { "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" } - ], - "toString": "name" - }, - { - "name": "Artifact", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "parents": "sbt.librarymanagement.ArtifactExtra", - "fields": [ - { "name": "name", "type": "String" }, - { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, - { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, - { "name": "classifier", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, - { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } - ], - "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" - }, - { - "name": "SshAuthentication", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "interface", - "types": [ - { - "name": "PasswordAuthentication", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "user", "type": "String" }, - { "name": "password", "type": "String?" } - ] - }, - { - "name": "KeyFileAuthentication", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "user", "type": "String" }, - { "name": "keyfile", "type": "java.io.File" }, - { "name": "password", "type": "String?" } - ] - } - ] - }, - { - "name": "SshConnection", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "authentication", "type": "sbt.librarymanagement.SshAuthentication?" }, - { "name": "hostname", "type": "String?" }, - { "name": "port", "type": "int?" } - ] - }, - { - "name": "FileConfiguration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Configuration specific to an Ivy filesystem resolver.", - "fields": [ - { "name": "isLocal", "type": "boolean" }, - { "name": "isTransactional", "type": "boolean?" } + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" } ] }, { @@ -572,19 +540,136 @@ "parentsCompanion": "sbt.librarymanagement.ResolverFunctions" }, { - "name": "ModuleConfiguration", + "name": "ScmInfo", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": "Basic SCM information for a project module", + "fields": [ + { "name": "browseUrl", "type": "java.net.URL" }, + { "name": "connection", "type": "String" }, + { "name": "devConnection", "type": "String?" } + ] + }, + { + "name": "SshAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "interface", + "types": [ + { + "name": "PasswordAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "user", "type": "String" }, + { "name": "password", "type": "String?" } + ] + }, + { + "name": "KeyFileAuthentication", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "user", "type": "String" }, + { "name": "keyfile", "type": "java.io.File" }, + { "name": "password", "type": "String?" } + ] + } + ] + }, + { + "name": "SshConnection", "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", "fields": [ - { "name": "organization", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "revision", "type": "String" }, - { "name": "resolver", "type": "sbt.librarymanagement.Resolver" } + { "name": "authentication", "type": "sbt.librarymanagement.SshAuthentication?" }, + { "name": "hostname", "type": "String?" }, + { "name": "port", "type": "int?" } + ] + }, + { + "name": "UpdateConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" }, + { "name": "missingOk", "type": "boolean" }, + { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, + { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" } + ] + }, + { + "name": "UpdateLogging", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "enumeration", + "doc": [ + "Configures logging during an 'update'. `level` determines the amount of other information logged.", + "`Full` is the default and logs the most.", + "`DownloadOnly` only logs what is downloaded.", + "`Quiet` only displays errors.", + "`Default` uses the current log level of `update` task." ], - "extraCompanion": [ - "def apply(org: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = apply(org, \"*\", \"*\", resolver)", - "def apply(org: String, name: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = ModuleConfiguration(org, name, \"*\", resolver)" + "symbols": [ "Full", "DownloadOnly", "Quiet", "Default" ] + }, + { + "name": "UpdateReport", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Provides information about dependency resolution.", + "It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.", + "This means that for a given configuration, there should only be one revision for a given organization and module name." + ], + "parents": "sbt.librarymanagement.UpdateReportExtra", + "fields": [ + { + "name": "cachedDescriptor", + "type": "java.io.File", + "doc": [ "the location of the resolved module descriptor in the cache" ] + }, + { + "name": "configurations", + "type": "sbt.librarymanagement.ConfigurationReport*", + "doc": [ "a sequence containing one report for each configuration resolved." ] + }, + { + "name": "stats", + "type": "sbt.librarymanagement.UpdateStats", + "doc": [ "stats information about the update that produced this report" ] + }, + { "name": "stamps", "type": "Map[java.io.File, Long]" } + ], + "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" + }, + { + "name": "UpdateStats", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "resolveTime", "type": "long" }, + { "name": "downloadTime", "type": "long" }, + { "name": "downloadSize", "type": "long" }, + { "name": "cached", "type": "boolean" } + ], + "toString": "Seq(\"Resolve time: \" + resolveTime + \" ms\", \"Download time: \" + downloadTime + \" ms\", \"Download size: \" + downloadSize + \" bytes\").mkString(\", \")" + }, + + { + "name": "ConfigurationReportLite", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "configuration", "type": "String" }, + { "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" } ] }, { @@ -642,6 +727,41 @@ } ] }, + { + "name": "IvyPaths", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "baseDirectory", "type": "java.io.File" }, + { "name": "ivyHome", "type": "java.io.File?" } + ] + }, + { + "name": "RetrieveConfiguration", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "retrieveDirectory", "type": "java.io.File" }, + { "name": "outputPattern", "type": "String" }, + { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "configurationsToRetrieve", "type": "Set[sbt.librarymanagement.Configuration]?", "default": "None", "since": "0.0.1" } + ] + }, + { + "name": "SbtExclusionRule", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "organization", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "artifact", "type": "String" }, + { "name": "configurations", "type": "String*" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" } + ] + }, { "name": "UpdateReportLite", "namespace": "sbt.internal.librarymanagement", @@ -650,125 +770,6 @@ "fields": [ { "name": "configurations", "type": "sbt.internal.librarymanagement.ConfigurationReportLite*" } ] - }, - { - "name": "ConfigurationReportLite", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "configuration", "type": "String" }, - { "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" } - ] - }, - { - "name": "ModuleID", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "parents": "sbt.librarymanagement.ModuleIDExtra", - "fields": [ - { "name": "organization", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "revision", "type": "String" }, - { "name": "configurations", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, - { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, - { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, - { "name": "branchName", "type": "String?", "default": "None", "since": "0.0.1" } - ], - "toString": [ - "organization + \":\" + name + \":\" + revision +", - " (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +", - " (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)" - ], - "parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions" - }, - { - "name": "ArtifactTypeFilter", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter)", - "parents": "sbt.librarymanagement.ArtifactTypeFilterExtra", - "fields": [ - { - "name": "types", - "doc": [ - "Represents the artifact types that we should try to resolve for (as in the allowed values of", - "`artifact[type]` from a dependency `` section). One can use this to filter", - "source / doc artifacts." - ], - "type": "Set[String]" - }, - { - "name": "inverted", - "doc": [ "Whether to invert the types filter (i.e. allow only types NOT in the set)" ], - "type": "boolean" - } - ], - "parentsCompanion": "sbt.librarymanagement.ArtifactTypeFilterFunctions" - }, - { - "name": "UpdateReport", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "Provides information about dependency resolution.", - "It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager.", - "This means that for a given configuration, there should only be one revision for a given organization and module name." - ], - "parents": "sbt.librarymanagement.UpdateReportExtra", - "fields": [ - { - "name": "cachedDescriptor", - "type": "java.io.File", - "doc": [ "the location of the resolved module descriptor in the cache" ] - }, - { - "name": "configurations", - "type": "sbt.librarymanagement.ConfigurationReport*", - "doc": [ "a sequence containing one report for each configuration resolved." ] - }, - { - "name": "stats", - "type": "sbt.librarymanagement.UpdateStats", - "doc": [ "stats information about the update that produced this report" ] - }, - { "name": "stamps", "type": "Map[java.io.File, Long]" } - ], - "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" - }, - { - "name": "ConfigurationReport", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "Provides information about resolution of a single configuration." - ], - "parents": "sbt.librarymanagement.ConfigurationReportExtra", - "fields": [ - { "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] }, - { - "name": "modules", - "type": "sbt.librarymanagement.ModuleReport*", - "doc": [ - "a sequence containing one report for each module resolved for this configuration." - ] - }, - { - "name": "details", - "type": "sbt.librarymanagement.OrganizationArtifactReport*", - "doc": [ "a sequence containing one report for each org/name, which may or may not be part of the final resolution." ] - } - ] } ] } From 3192b3ee1a91357b27372e7324cccbec00b89928 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 11:14:42 +0000 Subject: [PATCH 0541/1030] Remove unused warnings --- librarymanagement/src/test/scala/CachedResolutionSpec.scala | 4 ++-- .../scala/sbt/internal/librarymanagement/IvyRepoSpec.scala | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 85796bd20..182fa9521 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -14,7 +14,7 @@ class CachedResolutionSpec extends BaseIvySpecification { ) val report = ivyUpdate(m) cleanCachedResolutionCache(m) - val report2 = ivyUpdate(m) + val _ = ivyUpdate(m) // first resolution creates the minigraph println(report) // second resolution reads from the minigraph @@ -57,7 +57,7 @@ class CachedResolutionSpec extends BaseIvySpecification { Some("2.10.2"), UpdateOptions().withCachedResolution(true) ) // first resolution creates the minigraph - val report0 = ivyUpdate(m) + val _ = ivyUpdate(m) cleanCachedResolutionCache(m) // second resolution reads from the minigraph val report = ivyUpdate(m) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index fd7896c5b..b86e51117 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -58,7 +58,6 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val clMod = { import language.implicitConversions - implicit val key = (m: ModuleID) => (m.organization, m.name, m.revision) val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) GetClassifiersModule(ourModuleID, externalModules, Vector(Configurations.Compile), attemptedClassifiers) From af1c19034bc206faa591501d84b63fdb5ebaa576 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 16 Nov 2016 11:17:27 +0000 Subject: [PATCH 0542/1030] Remove unused imports --- librarymanagement/src/test/scala/BaseIvySpecification.scala | 2 -- librarymanagement/src/test/scala/ComponentManagerTest.scala | 3 +-- librarymanagement/src/test/scala/CrossVersionTest.scala | 1 - librarymanagement/src/test/scala/CustomPomParserTest.scala | 1 - librarymanagement/src/test/scala/MakePomSpec.scala | 2 -- librarymanagement/src/test/scala/ResolverTest.scala | 1 - librarymanagement/src/test/scala/ScalaOverrideTest.scala | 2 +- .../scala/sbt/internal/librarymanagement/IvyRepoSpec.scala | 1 - 8 files changed, 2 insertions(+), 11 deletions(-) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index a0f4bdfc0..dc7f2a4bf 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -4,10 +4,8 @@ import sbt.io.IO import sbt.io.syntax._ import java.io.File import cross.CrossVersionUtil -import sbt.util.Logger import sbt.internal.util.ConsoleLogger import sbt.librarymanagement._ -import ivyint.SbtChainResolver import Configurations._ import sbt.internal.util.FileBasedStore diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index 8f6bec88f..ff429aee1 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -2,12 +2,11 @@ package sbt.internal.librarymanagement import java.io.File import java.util.concurrent.Callable -import sbt.io.IO.{ createDirectory, delete, touch, withTemporaryDirectory } +import sbt.io.IO.withTemporaryDirectory import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider -import sbt.util.Logger // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 921ee1b18..c179623fb 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -1,6 +1,5 @@ package sbt.librarymanagement -import java.io.File import sbt.internal.util.UnitSpec class CrossVersionTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index e90b0ba20..eceec0d93 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -6,7 +6,6 @@ import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions import sbt.librarymanagement._ import sbt.io.IO.withTemporaryDirectory -import sbt.util.Logger import sbt.internal.util.ConsoleLogger class CustomPomParserTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index 1a910ca91..fb2c55001 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -1,7 +1,5 @@ package sbt.internal.librarymanagement -import java.io.File -import sbt.util.Logger import sbt.internal.util.ConsoleLogger // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index b2625304e..d2090c502 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -2,7 +2,6 @@ package sbt.librarymanagement import java.net.URL -import sbt._ import sbt.internal.util.UnitSpec object ResolverTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala index 6fd2425c4..bf0b82e3e 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId } +import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor import sbt.internal.util.UnitSpec diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index b86e51117..b6238b3d5 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -57,7 +57,6 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val dep = "com.test" % "module-with-srcs" % "0.1.00" % "compile" val clMod = { - import language.implicitConversions val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) GetClassifiersModule(ourModuleID, externalModules, Vector(Configurations.Compile), attemptedClassifiers) From f9a066fe922bf8e701ffe10910e48b1bbd2d0b05 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 17 Nov 2016 00:40:15 +0000 Subject: [PATCH 0543/1030] Id the root project as lmRoot .. like sbt/util and sbt/zinc name their root projects --- build.sbt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 9f0c79fb4..7f64b8cf6 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,6 @@ import Dependencies._ import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "0.1.0" -def internalPath = file("internal") def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala211, @@ -22,7 +21,7 @@ def commonSettings: Seq[Setting[_]] = Seq( publishArtifact in Test := false ) -lazy val root = (project in file(".")). +lazy val lmRoot = (project in file(".")). aggregate(lm). settings( inThisBuild(Seq( From 1bf74ddffa0528d29b5c8f0d0e97dcd6c30839b4 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 2 Dec 2016 16:49:47 +0000 Subject: [PATCH 0544/1030] Make MavenRepository the top level class Also reintroduce "isCache". --- .../src/main/datatype/librarymanagement.json | 14 +++++++---- .../impl/DependencyBuilders.scala | 2 +- .../sbt/librarymanagement/Resolver.scala | 23 +++++++++++-------- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index 994dba15e..d6e3aff88 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -420,7 +420,7 @@ ] }, { - "name": "IMavenRepository", + "name": "MavenRepository", "namespace": "sbt.librarymanagement", "target": "Scala", "type": "interface", @@ -431,10 +431,11 @@ ], "types": [ { - "name": "MavenRepository", + "name": "MavenRepo", "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", + "extra": "def isCache: Boolean = false", "toString": "s\"$name: $root\"" }, { @@ -449,11 +450,16 @@ "fields": [ { "name": "rootFile", "type": "java.io.File" } ], - "extra": "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)", + "extra": [ + "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)", + "def isCache: Boolean = true" + ], "toString": "s\"cache:$name: ${rootFile.getAbsolutePath}\"", "extraCompanion": "def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile)" } - ] + ], + "extra": "def isCache: Boolean", + "parentsCompanion": "sbt.librarymanagement.MavenRepositoryFunctions" }, { "name": "PatternsBasedRepository", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index 6260f5ad6..c5e117c72 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -60,6 +60,6 @@ final class RepositoryName private[sbt] (name: String) { def at(location: String) = { nonEmpty(location, "Repository location") - new MavenRepository(name, location) + MavenRepository(name, location) } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala index 75be6d228..9e73c1d7b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala @@ -26,6 +26,11 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver(res } } +abstract class MavenRepositoryFunctions { + def apply(name: String, root: String, localIfFile: Boolean = true): MavenRepository = + new MavenRepo(name, root, localIfFile) +} + abstract class PatternsFunctions { implicit def defaultPatterns: Patterns = Resolver.defaultPatterns @@ -43,9 +48,9 @@ private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Re trait ResolversSyntax { import Resolver._ - val DefaultMavenRepository = new MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) - val JavaNet2Repository = new MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) - val JCenterRepository = new MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) + val DefaultMavenRepository = MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) + val JavaNet2Repository = MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) + val JCenterRepository = MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) } abstract class ResolverFunctions { @@ -77,15 +82,15 @@ abstract class ResolverFunctions { private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" - private[sbt] val ScalaToolsReleases = new MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) - private[sbt] val ScalaToolsSnapshots = new MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) + private[sbt] val ScalaToolsReleases = MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) + private[sbt] val ScalaToolsSnapshots = MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) - def typesafeRepo(status: String) = new MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) + def typesafeRepo(status: String) = MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) def sbtIvyRepo(status: String) = url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) - def sonatypeRepo(status: String) = new MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) - def bintrayRepo(owner: String, repo: String) = new MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") + def sonatypeRepo(status: String) = MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))(Resolver.ivyStylePatterns) def jcenterRepo = JCenterRepository @@ -259,7 +264,7 @@ abstract class ResolverFunctions { } // TODO - should this just be the *exact* same as mavenLocal? probably... def publishMavenLocal: MavenCache = new MavenCache("publish-m2-local", mavenLocalDir) - def mavenLocal: IMavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) + def mavenLocal: MavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") def defaultUserFileRepository(id: String) = From e209499544d01edb8fb3fa8da43dc6bf09ad8fbb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Dec 2016 10:30:26 +0000 Subject: [PATCH 0545/1030] Avoid source file path clash with generated sources --- .../sbt/librarymanagement/{Artifact.scala => ArtifactExtra.scala} | 0 .../{Configuration.scala => ConfigurationExtra.scala} | 0 .../{CrossVersion.scala => CrossVersionExtra.scala} | 0 .../sbt/librarymanagement/{IvyScala.scala => IvyScalaExtra.scala} | 0 .../sbt/librarymanagement/{ModuleID.scala => ModuleIDExtra.scala} | 0 .../sbt/librarymanagement/{Resolver.scala => ResolverExtra.scala} | 0 .../{UpdateReport.scala => UpdateReportExtra.scala} | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename librarymanagement/src/main/scala/sbt/librarymanagement/{Artifact.scala => ArtifactExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{Configuration.scala => ConfigurationExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{CrossVersion.scala => CrossVersionExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{IvyScala.scala => IvyScalaExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{ModuleID.scala => ModuleIDExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{Resolver.scala => ResolverExtra.scala} (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/{UpdateReport.scala => UpdateReportExtra.scala} (100%) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Artifact.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersion.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/IvyScala.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ModuleID.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Resolver.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReport.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala From 7c221ef97f5d37a0d9862a5b7c0902dfe24ae88b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Dec 2016 10:26:53 +0000 Subject: [PATCH 0546/1030] Include managed sources in packageSrc --- build.sbt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7f64b8cf6..04511e60a 100644 --- a/build.sbt +++ b/build.sbt @@ -49,7 +49,14 @@ lazy val lm = (project in file("librarymanagement")). libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue, binaryIssueFilters ++= Seq(), - datatypeFormatsForType in generateDatatypes in Compile := DatatypeConfig.getFormats + datatypeFormatsForType in generateDatatypes in Compile := DatatypeConfig.getFormats, + // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc + mappings in (Compile, packageSrc) ++= { + val srcs = (managedSources in Compile).value + val sdirs = (managedSourceDirectories in Compile).value + val base = baseDirectory.value + (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) + } ). configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache). enablePlugins(DatatypePlugin, JsonCodecPlugin) From 19f40a16685ea936e4c9430c415ac2c33f33d8bd Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 28 Dec 2016 16:13:50 +0000 Subject: [PATCH 0547/1030] Fix ConfigurationReport.toString Move the toString implementation from ConfigurationReportExtra to inside the ConfigurationReport JSON schema definition, that way the synthetic toString generated by contraband doesn't override the carefully defined one. --- librarymanagement/src/main/datatype/librarymanagement.json | 5 +++++ .../main/scala/sbt/librarymanagement/UpdateReportExtra.scala | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index d6e3aff88..e0e6068d6 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -99,6 +99,11 @@ "type": "sbt.librarymanagement.OrganizationArtifactReport*", "doc": [ "a sequence containing one report for each org/name, which may or may not be part of the final resolution." ] } + ], + "toString": [ + "s\"\\t$configuration:\\n\" +", + "(if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map(\"\\t\\t(EVICTED) \" + _ + \"\\n\").mkString", + "else details.mkString)" ] }, { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index ecc81493b..a0f98b020 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -15,10 +15,6 @@ abstract class ConfigurationReportExtra { def evicted: Seq[ModuleID] = details flatMap (_.modules) filter (_.evicted) map (_.module) - override def toString = s"\t$configuration:\n" + - (if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map("\t\t(EVICTED) " + _ + "\n").mkString - else details.mkString) - /** * All resolved modules for this configuration. * For a given organization and module name, there is only one revision/`ModuleID` in this sequence. From 04904ed34dabdaf0628faa5a65ea014c7d8a2820 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Dec 2016 17:10:37 +0000 Subject: [PATCH 0548/1030] Add back SbtExclusionRule companion implicit lifts --- .../src/main/datatype/librarymanagement.json | 3 ++- .../SbtExclusionRuleExtra.scala | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/datatype/librarymanagement.json index d6e3aff88..d39e8b333 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/datatype/librarymanagement.json @@ -766,7 +766,8 @@ { "name": "artifact", "type": "String" }, { "name": "configurations", "type": "String*" }, { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" } - ] + ], + "parentsCompanion": "sbt.internal.librarymanagement.SbtExclusionRuleFunctions" }, { "name": "UpdateReportLite", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala new file mode 100644 index 000000000..ec144cfee --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala @@ -0,0 +1,17 @@ +package sbt.internal.librarymanagement + +import sbt.internal.librarymanagement.impl._ +import sbt.librarymanagement._ + +abstract class SbtExclusionRuleFunctions { + def apply(organization: String, name: String): SbtExclusionRule = + SbtExclusionRule(organization, name, "*", Vector.empty, Disabled()) + + def apply(organization: String): SbtExclusionRule = apply(organization, "*") + + implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = apply(organization.groupID) + implicit def stringToExclusionRule(organization: String): SbtExclusionRule = apply(organization) + + implicit def groupArtifactIDToExclusionRule(gaid: GroupArtifactID): SbtExclusionRule = + SbtExclusionRule(gaid.groupID, gaid.artifactID, "*", Vector.empty, gaid.crossVersion) +} From 06c7f382ad4f1ab55ac55c595ecb8ede7636f44b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Jan 2017 13:32:44 +0000 Subject: [PATCH 0549/1030] Cleanup & simplify Deps --- project/Dependencies.scala | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 250adc2e2..ffd6d43ac 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,18 +2,18 @@ import sbt._ import Keys._ object Dependencies { - lazy val scala211 = "2.11.8" + val scala211 = "2.11.8" - val ioVersion = "1.0.0-M6" - val utilVersion = "0.1.0-M15" + private val ioVersion = "1.0.0-M6" + private val utilVersion = "0.1.0-M15" - private lazy val sbtIO = "org.scala-sbt" %% "io" % ioVersion + private val sbtIO = "org.scala-sbt" %% "io" % ioVersion - private lazy val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion - private lazy val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - private lazy val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion - private lazy val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion - private lazy val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion + private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion + private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion + private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion + private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion + private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion def getSbtModulePath(key: String, name: String) = { val localProps = new java.util.Properties() @@ -32,7 +32,7 @@ object Dependencies { case None => p settings (libraryDependencies += c.fold(m)(m % _)) } - def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) + def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) @@ -40,13 +40,13 @@ object Dependencies { def addSbtUtilCompletion(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) - lazy val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - lazy val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" - lazy val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () - lazy val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } - lazy val scalaXml = scala211Module("scala-xml", "1.0.5") - lazy val sjsonnewVersion = "0.4.1" - lazy val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion + val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" + val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () + val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } + val scalaXml = scala211Module("scala-xml", "1.0.5") + val sjsonnewVersion = "0.4.1" + val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion private def scala211Module(name: String, moduleVersion: String) = Def.setting { From 946f30708203ef7bb1f68e795ef7eac6b5a13fa8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 19 Dec 2016 15:57:55 +0000 Subject: [PATCH 0550/1030] Implement JsonFormat[NodeSeq] like it was in IvyCache --- .../internal/librarymanagement/formats/NodeSeqFormat.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala index ad527c35d..fbc99e9b9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala @@ -4,5 +4,8 @@ import sjsonnew._ import scala.xml._ trait NodeSeqFormat { self: BasicJsonProtocol => - implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = ??? + implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = project[NodeSeq, String]( + xml => { xml }.toString, + str => XML.loadString(str).child + ) } From 71fddd5e3f44157faa3a1ae2bdc5ec1a7d2def44 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Jan 2017 13:33:19 +0000 Subject: [PATCH 0551/1030] Upgrade from sbt/datatype to sbt/contraband --- build.sbt | 4 +- .../librarymanagement.json | 72 +++++++++---------- .../internal/librarymanagement/IvyCache.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 10 +-- .../internal/librarymanagement/JsonUtil.scala | 10 +-- .../librarymanagement/RichUpdateReport.scala | 6 +- .../CachedResolutionResolveEngine.scala | 12 ++-- .../sbt/librarymanagement/ArtifactExtra.scala | 2 +- .../ConfigurationExtra.scala | 2 +- .../librarymanagement/CrossVersionExtra.scala | 4 +- .../sbt/librarymanagement/IvyInterface.scala | 2 +- .../sbt/librarymanagement/ResolverExtra.scala | 2 +- .../librarymanagement/UpdateReportExtra.scala | 4 +- .../src/test/scala/BaseIvySpecification.scala | 8 +-- .../src/test/scala/CustomPomParserTest.scala | 2 +- .../src/test/scala/DMSerializationSpec.scala | 8 +-- project/DatatypeConfig.scala | 29 ++++---- project/Dependencies.scala | 6 +- project/contraband.sbt | 1 + project/sbt-datatype.sbt | 1 - 20 files changed, 94 insertions(+), 93 deletions(-) rename librarymanagement/src/main/{datatype => contraband}/librarymanagement.json (93%) create mode 100644 project/contraband.sbt delete mode 100644 project/sbt-datatype.sbt diff --git a/build.sbt b/build.sbt index 04511e60a..1ff4aaa3d 100644 --- a/build.sbt +++ b/build.sbt @@ -49,7 +49,7 @@ lazy val lm = (project in file("librarymanagement")). libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue, binaryIssueFilters ++= Seq(), - datatypeFormatsForType in generateDatatypes in Compile := DatatypeConfig.getFormats, + contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc mappings in (Compile, packageSrc) ++= { val srcs = (managedSources in Compile).value @@ -59,7 +59,7 @@ lazy val lm = (project in file("librarymanagement")). } ). configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache). - enablePlugins(DatatypePlugin, JsonCodecPlugin) + enablePlugins(ContrabandPlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/librarymanagement/src/main/datatype/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json similarity index 93% rename from librarymanagement/src/main/datatype/librarymanagement.json rename to librarymanagement/src/main/contraband/librarymanagement.json index bbcd2ed38..b6dd96e23 100644 --- a/librarymanagement/src/main/datatype/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -12,9 +12,9 @@ { "name": "name", "type": "String" }, { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, - { "name": "classifier", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "url", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, + { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } ], "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" @@ -208,14 +208,14 @@ "target": "Scala", "type": "record", "fields": [ - { "name": "scalaFullVersion", "type": "String" }, - { "name": "scalaBinaryVersion", "type": "String" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, - { "name": "checkExplicit", "type": "boolean" }, - { "name": "filterImplicit", "type": "boolean" }, - { "name": "overrideScalaVersion", "type": "boolean" }, - { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, - { "name": "scalaArtifacts", "type": "String*", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } + { "name": "scalaFullVersion", "type": "String" }, + { "name": "scalaBinaryVersion", "type": "String" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, + { "name": "checkExplicit", "type": "boolean" }, + { "name": "filterImplicit", "type": "boolean" }, + { "name": "overrideScalaVersion", "type": "boolean" }, + { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, + { "name": "scalaArtifacts", "type": "scala.Vector[String]", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } ], "parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions" }, @@ -245,7 +245,7 @@ { "name": "organization", "type": "String" }, { "name": "name", "type": "String" }, { "name": "revision", "type": "String" }, - { "name": "configurations", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "configurations", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, @@ -254,7 +254,7 @@ { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, - { "name": "branchName", "type": "String?", "default": "None", "since": "0.0.1" } + { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" } ], "toString": [ "organization + \":\" + name + \":\" + revision +", @@ -270,15 +270,15 @@ "type": "record", "doc": "Additional information about a project module", "fields": [ - { "name": "nameFormal", "type": "String" }, - { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "homepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, - { "name": "startYear", "type": "int?", "default": "None", "since": "0.0.1" }, - { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "organizationHomepage", "type": "java.net.URL?", "default": "None", "since": "0.0.1" }, - { "name": "scmInfo", "type": "sbt.librarymanagement.ScmInfo?", "default": "None", "since": "0.0.1" }, - { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } + { "name": "nameFormal", "type": "String" }, + { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "homepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "startYear", "type": "Option[Int]", "default": "None", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "scmInfo", "type": "Option[sbt.librarymanagement.ScmInfo]", "default": "None", "since": "0.0.1" }, + { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } ] }, { @@ -295,18 +295,18 @@ { "name": "module", "type": "sbt.librarymanagement.ModuleID" }, { "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*" }, { "name": "missingArtifacts", "type": "sbt.librarymanagement.Artifact*" }, - { "name": "status", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "publicationDate", "type": "java.util.Date?", "default": "None", "since": "0.0.1" }, - { "name": "resolver", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "artifactResolver", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "status", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "publicationDate", "type": "Option[java.util.Date]", "default": "None", "since": "0.0.1" }, + { "name": "resolver", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "artifactResolver", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "evicted", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "evictedData", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "evictedReason", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "problem", "type": "String?", "default": "None", "since": "0.0.1" }, - { "name": "homepage", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "evictedData", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "evictedReason", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "problem", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "homepage", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, - { "name": "isDefault", "type": "boolean?", "default": "None", "since": "0.0.1" }, - { "name": "branch", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "isDefault", "type": "Option[Boolean]", "default": "None", "since": "0.0.1" }, + { "name": "branch", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "licenses", "type": "scala.Tuple2[String, Option[String]]*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "callers", "type": "sbt.librarymanagement.Caller*", "default": "Vector.empty", "since": "0.0.1" } @@ -359,7 +359,7 @@ { "name": "excludes", "type": "sbt.internal.librarymanagement.SbtExclusionRule*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "defaultConfiguration", "type": "sbt.librarymanagement.Configuration?", "default": "None", "since": "0.0.1" }, + { "name": "defaultConfiguration", "type": "Option[sbt.librarymanagement.Configuration]", "default": "None", "since": "0.0.1" }, { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } ], "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationFunctions" @@ -754,10 +754,10 @@ "target": "Scala", "type": "record", "fields": [ - { "name": "retrieveDirectory", "type": "java.io.File" }, - { "name": "outputPattern", "type": "String" }, - { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "configurationsToRetrieve", "type": "Set[sbt.librarymanagement.Configuration]?", "default": "None", "since": "0.0.1" } + { "name": "retrieveDirectory", "type": "java.io.File" }, + { "name": "outputPattern", "type": "String" }, + { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "configurationsToRetrieve", "type": "Option[Set[sbt.librarymanagement.Configuration]]", "default": "None", "since": "0.0.1" } ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 0c1c1f969..80eff7470 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -90,7 +90,7 @@ class IvyCache(val ivyHome: Option[File], fileToStore: File => CacheStore) { private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal - val paths = new IvyPaths(new File("."), ivyHome) + val paths = IvyPaths(new File("."), ivyHome) val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) (new IvySbt(conf, fileToStore), local) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 6f0a7d42e..e27d40c0f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -85,7 +85,7 @@ object IvyRetrieve { case Some(dd) => (toExtraAttributes(dd.getExtraAttributes), dd.isForce, dd.isChanging, dd.isTransitive, false) case None => (Map.empty[String, String], false, false, true, false) } - new Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) + Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) } val revId = dep.getResolvedId val moduleId = toModuleID(revId) @@ -142,7 +142,7 @@ object IvyRetrieve { val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) - new ModuleReport(moduleId, resolved, missing, status, publicationDate, resolver, artifactResolver, + ModuleReport(moduleId, resolved, missing, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } @@ -161,11 +161,11 @@ object IvyRetrieve { } def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = - new UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps () + UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps () def updateStats(report: ResolveReport): UpdateStats = - new UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) + UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - new ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport)) + ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport)) /** * Tries to find Ivy graph path the from node to target. diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 7be87317a..df6f6490d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -34,8 +34,8 @@ private[sbt] class JsonUtil(fileToStore: File => CacheStore) { def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite(cr.configuration, cr.details map { oar => - new OrganizationArtifactReport(oar.organization, oar.name, oar.modules map { mr => - new ModuleReport( + OrganizationArtifactReport(oar.organization, oar.name, oar.modules map { mr => + ModuleReport( mr.module, mr.artifacts, mr.missingArtifacts, mr.status, mr.publicationDate, mr.resolver, mr.artifactResolver, mr.evicted, mr.evictedData, mr.evictedReason, @@ -63,7 +63,7 @@ private[sbt] class JsonUtil(fileToStore: File => CacheStore) { def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = { - val stats = new UpdateStats(0L, 0L, 0L, false) + val stats = UpdateStats(0L, 0L, 0L, false) val configReports = lite.configurations map { cr => val details = cr.details val modules = details flatMap { @@ -71,8 +71,8 @@ private[sbt] class JsonUtil(fileToStore: File => CacheStore) { !mr.evicted && mr.problem.isEmpty } } - new ConfigurationReport(cr.configuration, modules, details) + ConfigurationReport(cr.configuration, modules, details) } - new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala index 8b9f82922..ad6d3ae01 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala @@ -11,7 +11,7 @@ final class RichUpdateReport(report: UpdateReport) { { val files = report.cachedDescriptor +: allFiles val stamps = files.map(f => (f, f.lastModified)).toMap - new UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) + UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) } import DependencyFilter._ @@ -64,8 +64,8 @@ final class RichUpdateReport(report: UpdateReport) { val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => f(configuration, modReport) } - new ConfigurationReport(configuration, newModules, details) + ConfigurationReport(configuration, newModules, details) } - new UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) + UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 8c94be6f6..887a057f3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -402,13 +402,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val rootModuleConfigs = md0.getConfigurations.toVector val cachedReports = reports filter { !_.stats.cached } - val stats = new UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) + val stats = UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) val configReports = rootModuleConfigs map { conf => log.debug("::: -----------") val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } mergeConfigurationReports(conf.getName, crs, os, log) } - new UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } // memory usage 62%, of which 58% is in mergeOrganizationArtifactReports def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], os: Vector[IvyOverride], log: Logger): ConfigurationReport = @@ -420,7 +420,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { !mr.evicted && mr.problem.isEmpty } } - new ConfigurationReport(rootModuleConf, modules, details) + ConfigurationReport(rootModuleConf, modules, details) } /** * Returns a tuple of (merged org + name combo, newly evicted modules) @@ -579,7 +579,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val notEvicted = (survivor ++ newlyEvicted) filter { m => !m.evicted } log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) - val x = new OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) + val x = OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) val nextModules = transitivelyEvict(rootModuleConf, rest, allModules, evicted, log) x :: resolveConflicts(rest, nextModules) }) @@ -644,7 +644,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val newlyEvicted = affected map { _.withEvicted(true).withEvictedReason(Some("transitive-evict")) } if (affected.isEmpty) oar - else new OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) + else OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) } Seq(((organization, name), oars)) } @@ -761,7 +761,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } mergeConfigurationReports(conf0.getName, remappedCRs, os, log) } - new UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) + UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index e3a2d2793..fe662ca78 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -38,7 +38,7 @@ abstract class ArtifactFunctions { def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, Some(url)) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[Configuration], url: Option[URL]): Artifact = - Artifact(name, `type`, extension, classifier, configurations, url, Map.empty) + Artifact(name, `type`, extension, classifier, configurations, url, Map.empty[String, String]) val DefaultExtension = "jar" val DefaultType = "jar" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index f0d0fff7f..f3b267e24 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -4,7 +4,7 @@ package sbt.librarymanagement object Configurations { - def config(name: String) = new Configuration(name) + def config(name: String) = Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index d212e0e0a..ae1ec1c61 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -13,10 +13,10 @@ abstract class CrossVersionFunctions { val TransitionSbtVersion = CrossVersionUtil.TransitionSbtVersion /** Cross-versions a module with the full version (typically the full Scala version). */ - def full: CrossVersion = new Full() + def full: CrossVersion = Full() /** Cross-versions a module with the binary version (typically the binary Scala version). */ - def binary: CrossVersion = new Binary() + def binary: CrossVersion = Binary() private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s)) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index cded9dcb5..7f7e1dc91 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -7,7 +7,7 @@ import org.apache.ivy.core.module.descriptor import org.apache.ivy.util.filter.{ Filter => IvyFilter } abstract class InclExclRuleFunctions { - def everything = new InclExclRule("*", "*", "*", Vector.empty) + def everything = InclExclRule("*", "*", "*", Vector.empty) } abstract class ArtifactTypeFilterExtra { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 9e73c1d7b..ce939a1ce 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -28,7 +28,7 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver(res abstract class MavenRepositoryFunctions { def apply(name: String, root: String, localIfFile: Boolean = true): MavenRepository = - new MavenRepo(name, root, localIfFile) + MavenRepo(name, root, localIfFile) } abstract class PatternsFunctions { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index a0f98b020..23a93db8d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -29,7 +29,7 @@ abstract class ConfigurationReportExtra { } def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - new ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) + ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) } abstract class ModuleReportExtra { @@ -141,7 +141,7 @@ abstract class UpdateReportExtra { } def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = - new UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) + UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ def configuration(s: String) = configurations.find(_.configuration == s) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index dc7f2a4bf..7906abb4f 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -30,7 +30,7 @@ trait BaseIvySpecification extends UnitSpec { def module(moduleId: ModuleID, deps: Vector[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => - new IvyScala( + IvyScala( scalaFullVersion = fv, scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), configurations = Vector.empty, @@ -56,7 +56,7 @@ trait BaseIvySpecification extends UnitSpec { def chainResolver = ChainedResolver("sbt-chain", resolvers) def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { - val paths = new IvyPaths(currentBase, Some(currentTarget)) + val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val off = false @@ -66,8 +66,8 @@ trait BaseIvySpecification extends UnitSpec { } def makeUpdateConfiguration: UpdateConfiguration = { - val retrieveConfig = new RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) - new UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) + val retrieveConfig = RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) + UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index eceec0d93..ba4b48161 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -14,7 +14,7 @@ class CustomPomParserTest extends UnitSpec { withTemporaryDirectory { cacheDir => val repoUrl = getClass.getResource("/test-maven-repo") val local = MavenRepository("Test Repo", repoUrl.toExternalForm) - val paths = new IvyPaths(new File("."), Some(cacheDir)) + val paths = IvyPaths(new File("."), Some(cacheDir)) val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, None, Vector("sha1", "md5"), None, UpdateOptions(), log) val ivySbt = new IvySbt(conf, DefaultFileToStore) val resolveOpts = new ResolveOptions().setConfs(Array("default")) diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index ab1bb457b..bbbeef4f8 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -51,13 +51,13 @@ class DMSerializationSpec extends UnitSpec { } lazy val updateReportExample = - new UpdateReport(new File("./foo"), Vector(configurationReportExample), - new UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) + UpdateReport(new File("./foo"), Vector(configurationReportExample), + UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) lazy val configurationReportExample = - new ConfigurationReport("compile", Vector(moduleReportExample), + ConfigurationReport("compile", Vector(moduleReportExample), Vector(organizationArtifactReportExample)) lazy val organizationArtifactReportExample = - new OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) + OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) lazy val moduleReportExample = ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index 78159c476..9e5c8ffc5 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -1,23 +1,24 @@ -import sbt.datatype.{ CodecCodeGen, TpeRef } +import sbt.contraband.ast._ +import sbt.contraband.CodecCodeGen object DatatypeConfig { /** Extract the only type parameter from a TpeRef */ - def oneArg(tpe: TpeRef): TpeRef = { - val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?)[>\\]]""".r + def oneArg(tpe: Type): Type = { + val pat = s"""${tpe.removeTypeParameters.name}[<\\[](.+?)[>\\]]""".r val pat(arg0) = tpe.name - TpeRef(arg0, false, false, false) + NamedType(arg0 split '.' toList) } /** Extract the two type parameters from a TpeRef */ - def twoArgs(tpe: TpeRef): List[TpeRef] = { - val pat = s"""${CodecCodeGen.removeTypeParameters(tpe.name)}[<\\[](.+?), (.+?)[>\\]]""".r + def twoArgs(tpe: Type): List[Type] = { + val pat = s"""${tpe.removeTypeParameters.name}[<\\[](.+?), (.+?)[>\\]]""".r val pat(arg0, arg1) = tpe.name - TpeRef(arg0, false, false, false) :: TpeRef(arg1, false, false, false) :: Nil + NamedType(arg0 split '.' toList) :: NamedType(arg1 split '.' toList) :: Nil } /** Codecs that were manually written. */ - val myCodecs: PartialFunction[String, TpeRef => List[String]] = { + val myCodecs: PartialFunction[String, Type => List[String]] = { case "java.util.Date" => { _ => "sbt.internal.librarymanagement.formats.DateFormat" :: Nil } case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil } @@ -32,7 +33,7 @@ object DatatypeConfig { { _ => "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil } // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo - case "Option" | "Set" => { tpe => getFormats(oneArg(tpe)) } + case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) } case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) } case "Int" | "Long" => { _ => Nil } } @@ -43,13 +44,13 @@ object DatatypeConfig { "sbt.librarymanagement.ExclusionRule") /** Returns the list of formats required to encode the given `TpeRef`. */ - val getFormats: TpeRef => List[String] = + val getFormats: Type => List[String] = CodecCodeGen.extensibleFormatsForType { - case TpeRef("sbt.internal.librarymanagement.RetrieveConfiguration", false, false, false) => + case NamedType(List("sbt", "internal", "librarymanagement", "RetrieveConfiguration"), _) => "sbt.librarymanagement.RetrieveConfigurationFormats" :: Nil - case tpe @ TpeRef(name, _, _, _) if myCodecs isDefinedAt CodecCodeGen.removeTypeParameters(name) => - myCodecs(CodecCodeGen.removeTypeParameters(name))(tpe) - case TpeRef(name, _, _, _) if excluded contains CodecCodeGen.removeTypeParameters(name) => + case tpe: Type if myCodecs isDefinedAt tpe.removeTypeParameters.name => + myCodecs(tpe.removeTypeParameters.name)(tpe) + case tpe: Type if excluded contains tpe.removeTypeParameters.name => Nil case other => CodecCodeGen.formatsForType(other) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ffd6d43ac..5403ebe05 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,8 +4,8 @@ import Keys._ object Dependencies { val scala211 = "2.11.8" - private val ioVersion = "1.0.0-M6" - private val utilVersion = "0.1.0-M15" + private val ioVersion = "1.0.0-M9" + private val utilVersion = "1.0.0-M17" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -45,7 +45,7 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") - val sjsonnewVersion = "0.4.1" + val sjsonnewVersion = "0.7.0" val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion private def scala211Module(name: String, moduleVersion: String) = diff --git a/project/contraband.sbt b/project/contraband.sbt new file mode 100644 index 000000000..88961b8f9 --- /dev/null +++ b/project/contraband.sbt @@ -0,0 +1 @@ +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M3") diff --git a/project/sbt-datatype.sbt b/project/sbt-datatype.sbt deleted file mode 100644 index c13a23ad7..000000000 --- a/project/sbt-datatype.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("org.scala-sbt" % "sbt-datatype" % "0.2.8") From 4ca5b5ae0a7587ac655bac8cb3b3a1bfc0605c0a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Jan 2017 23:30:05 -0500 Subject: [PATCH 0552/1030] Change publicationDate to java.util.Calendar This migrates to java.util.Calendar, which is better than java.util.Date and is supported by sjson-new out of the box. --- .../src/main/contraband/librarymanagement.json | 2 +- .../sbt/internal/librarymanagement/IvyRetrieve.scala | 4 +++- .../librarymanagement/formats/DateFormat.scala | 11 ----------- .../ivyint/CachedResolutionResolveEngine.scala | 4 +++- .../sbt/librarymanagement/UpdateReportExtra.scala | 4 ++-- project/DatatypeConfig.scala | 2 -- 6 files changed, 9 insertions(+), 18 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index b6dd96e23..0dd0a5580 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -296,7 +296,7 @@ { "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*" }, { "name": "missingArtifacts", "type": "sbt.librarymanagement.Artifact*" }, { "name": "status", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "publicationDate", "type": "Option[java.util.Date]", "default": "None", "since": "0.0.1" }, + { "name": "publicationDate", "type": "Option[java.util.Calendar]", "default": "None", "since": "0.0.1" }, { "name": "resolver", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "artifactResolver", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "evicted", "type": "boolean", "default": "false", "since": "0.0.1" }, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index e27d40c0f..2c8ef1049 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -92,9 +92,11 @@ object IvyRetrieve { val branch = nonEmptyString(revId.getBranch) val (status, publicationDate, resolver, artifactResolver) = dep.isLoaded match { case true => + val c = new ju.GregorianCalendar() + c.setTimeInMillis(dep.getPublication) ( nonEmptyString(dep.getDescriptor.getStatus), - Some(new ju.Date(dep.getPublication)), + Some(c), nonEmptyString(dep.getModuleRevision.getResolver.getName), nonEmptyString(dep.getModuleRevision.getArtifactResolver.getName) ) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala deleted file mode 100644 index 337ff3bd8..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DateFormat.scala +++ /dev/null @@ -1,11 +0,0 @@ -package sbt.internal.librarymanagement.formats - -import sjsonnew._ -import java.util._ -import java.text._ - -trait DateFormat { self: BasicJsonProtocol => - private val format = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy") - - implicit lazy val DateFormat: JsonFormat[Date] = project(_.toString, format.parse _) -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 887a057f3..7dcc35d65 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -686,6 +686,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case _ => val strategy = lcm.getStrategy val infos = conflicts map { ModuleReportArtifactInfo(_) } + log.debug(s"- Using $strategy with $infos") Option(strategy.findLatest(infos.toArray, None.orNull)) match { case Some(ModuleReportArtifactInfo(m)) => (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some(lcm.toString)) }, lcm.toString) @@ -766,8 +767,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) extends IvyArtifactInfo { - override def getLastModified: Long = moduleReport.publicationDate map { _.getTime } getOrElse 0L + override def getLastModified: Long = moduleReport.publicationDate map { _.getTimeInMillis } getOrElse 0L override def getRevision: String = moduleReport.module.revision + override def toString: String = s"ModuleReportArtifactInfo(${moduleReport.module}, $getRevision, $getLastModified)" } private[sbt] case class IvyOverride(moduleId: IvyModuleId, pm: PatternMatcher, ddm: OverrideDependencyDescriptorMediator) { override def toString: String = s"""IvyOverride($moduleId,$pm,${ddm.getVersion},${ddm.getBranch})""" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 23a93db8d..594588b44 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -37,7 +37,7 @@ abstract class ModuleReportExtra { def artifacts: Vector[(Artifact, File)] def missingArtifacts: Vector[Artifact] def status: Option[String] - def publicationDate: Option[ju.Date] + def publicationDate: Option[ju.Calendar] def resolver: Option[String] def artifactResolver: Option[String] def evicted: Boolean @@ -99,7 +99,7 @@ abstract class ModuleReportExtra { artifacts: Vector[(Artifact, File)] = artifacts, missingArtifacts: Vector[Artifact] = missingArtifacts, status: Option[String] = status, - publicationDate: Option[ju.Date] = publicationDate, + publicationDate: Option[ju.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index 9e5c8ffc5..4b39d3cad 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -19,8 +19,6 @@ object DatatypeConfig { /** Codecs that were manually written. */ val myCodecs: PartialFunction[String, Type => List[String]] = { - case "java.util.Date" => { _ => "sbt.internal.librarymanagement.formats.DateFormat" :: Nil } - case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil } case "org.apache.ivy.plugins.resolver.DependencyResolver" => From a87ed10dc7042b269a296e560f4707866ba849c5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Jan 2017 23:35:40 -0500 Subject: [PATCH 0553/1030] Move ModuleID toString out --- .../main/contraband/librarymanagement.json | 4 +-- .../sbt/librarymanagement/ModuleIDExtra.scala | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 0dd0a5580..8dd2d1cc9 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -257,9 +257,7 @@ { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" } ], "toString": [ - "organization + \":\" + name + \":\" + revision +", - " (configurations match { case Some(s) => \":\" + s; case None => \"\" }) +", - " (if (extraAttributes.isEmpty) \"\" else \" \" + extraString)" + "this.toStringImpl" ], "parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions" }, diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index e4f12fd3d..572fd194d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -6,6 +6,7 @@ package sbt.librarymanagement import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties +import scala.collection.mutable.ListBuffer abstract class ModuleIDExtra { def organization: String @@ -38,6 +39,31 @@ abstract class ModuleIDExtra { branchName: Option[String] = branchName ): ModuleID + protected def toStringImpl: String = + s"""$organization:$name:$revision""" + + (configurations match { case Some(s) => ":" + s; case None => "" }) + + { + val attr = attributeString + if (attr == "") "" + else " " + attr + } + + (if (extraAttributes.isEmpty) "" else " " + extraString) + + protected def attributeString: String = + { + val buffer = ListBuffer.empty[String] + if (isChanging) { + buffer += "changing" + } + if (!isTransitive) { + buffer += "intransitive" + } + if (isForce) { + buffer += "force" + } + buffer.toList.mkString(";") + } + /** String representation of the extra attributes, excluding any information only attributes. */ def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") From 6fc84b09e9d90e20c75a01ee230ce7463e9d7677 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Jan 2017 17:14:30 +0000 Subject: [PATCH 0554/1030] Only build on jdk8 As of https://github.com/sbt/util/pull/66 sbt/util is built and published using jdk8. Trying to use jdk7 will fail with "Unsupported major.minor version 52.0", e.g. for xsbti/Logger. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 44dc5a257..d1d78a0d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,4 @@ language: scala scala: - 2.11.8 jdk: - - openjdk7 - - oraclejdk7 - oraclejdk8 From 9d812f4d980ed6f1a09bc0235a897f26e3cd3ce0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 7 Jan 2017 00:43:52 -0500 Subject: [PATCH 0555/1030] Cross publish to Scala 2.12 --- .java-version | 1 + .travis.yml | 6 ++++++ build.sbt | 10 +++++----- project/Dependencies.scala | 1 + project/house.sbt | 2 +- 5 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 .java-version diff --git a/.java-version b/.java-version new file mode 100644 index 000000000..625934097 --- /dev/null +++ b/.java-version @@ -0,0 +1 @@ +1.8 diff --git a/.travis.yml b/.travis.yml index d1d78a0d1..ff0899634 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,11 @@ language: scala + scala: - 2.11.8 + - 2.12.1 + +script: + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "++$TRAVIS_SCALA_VERSION test" + jdk: - oraclejdk8 diff --git a/build.sbt b/build.sbt index 1ff4aaa3d..81b9b1519 100644 --- a/build.sbt +++ b/build.sbt @@ -4,19 +4,19 @@ import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "0.1.0" def commonSettings: Seq[Setting[_]] = Seq( - scalaVersion := scala211, + scalaVersion := scala212, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), - javacOptions in compile ++= Seq("-target", "6", "-source", "6", "-Xlint", "-Xlint:-serial"), + javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), incOptions := incOptions.value.withNameHashing(true), - crossScalaVersions := Seq(scala211), + crossScalaVersions := Seq(scala211, scala212), resolvers += Resolver.sonatypeRepo("public"), scalacOptions += "-Ywarn-unused", - previousArtifact := None, // Some(organization.value %% moduleName.value % "1.0.0"), + mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false ) @@ -48,7 +48,7 @@ lazy val lm = (project in file("librarymanagement")). ivy, jsch, scalaReflect.value, launcherInterface, sjsonnewScalaJson % Optional), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue, - binaryIssueFilters ++= Seq(), + mimaBinaryIssueFilters ++= Seq(), contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc mappings in (Compile, packageSrc) ++= { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 5403ebe05..8117fe756 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,6 +3,7 @@ import Keys._ object Dependencies { val scala211 = "2.11.8" + val scala212 = "2.12.1" private val ioVersion = "1.0.0-M9" private val utilVersion = "1.0.0-M17" diff --git a/project/house.sbt b/project/house.sbt index 555559b37..bad061ebe 100644 --- a/project/house.sbt +++ b/project/house.sbt @@ -1 +1 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.1") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") From 9dd1dff6cb5f7e45728f1b8c61885206557e9389 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 13 Jan 2017 22:48:32 -0500 Subject: [PATCH 0556/1030] Bump util --- build.sbt | 2 +- project/Dependencies.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 81b9b1519..b5e89d6c4 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,7 @@ import Dependencies._ import com.typesafe.tools.mima.core._, ProblemFilters._ -def baseVersion = "0.1.0" +def baseVersion = "1.0.0" def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8117fe756..8aa939206 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,7 @@ object Dependencies { val scala212 = "2.12.1" private val ioVersion = "1.0.0-M9" - private val utilVersion = "1.0.0-M17" + private val utilVersion = "1.0.0-M18" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From df53eefbb0bd5a3bbbd0ddb32ec9536514fbaf53 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 14 Jan 2017 06:54:23 -0500 Subject: [PATCH 0557/1030] Fixes merged ModuleID dropping configuration specification Fixes #2002/#1500 Given a dependency graph such as: libraryDependencies += "com.google.guava" % "guava-tests" % "18.0" libraryDependencies += "com.google.guava" % "guava-tests" % "18.0" % "test" classifier "tests" previous releases of sbt would drop the Test configuration from the classifier "tests" artifacts, and end up including the test JARs into the Compile configuration instead of the Test configuration, which would result in runtime error. This fix configures the explicit artifacts into the configuration during merge even when it says `"*"`. --- .../ivyint/MergeDescriptors.scala | 15 ++++---- .../src/test/scala/MergeDescriptorSpec.scala | 34 +++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 librarymanagement/src/test/scala/MergeDescriptorSpec.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index b3c8c378c..1f9cfa152 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -31,7 +31,7 @@ private[sbt] object MergeDescriptors { // combines the artifacts, configurations, includes, and excludes for DependencyDescriptors `a` and `b` // that otherwise have equal IDs -private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor { +private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor { def getDependencyId = a.getDependencyId def isForce = a.isForce def isChanging = a.isChanging @@ -80,11 +80,14 @@ private final class MergedDescriptors(a: DependencyDescriptor, b: DependencyDesc arts map { art => explicitConfigurations(base, art) } private[this] def explicitConfigurations(base: DependencyDescriptor, art: DependencyArtifactDescriptor): DependencyArtifactDescriptor = { - val aConfs = art.getConfigurations - if (aConfs == null || aConfs.isEmpty) - copyWithConfigurations(art, base.getModuleConfigurations) - else - art + val aConfs = Option(art.getConfigurations) map { _.toList } + // In case configuration list is "*", we should still specify the module configuration of the DependencyDescriptor + // otherwise the explicit specified artifacts from one dd can leak over to the other. + // See gh-1500, gh-2002 + aConfs match { + case None | Some(Nil) | Some(List("*")) => copyWithConfigurations(art, base.getModuleConfigurations) + case _ => art + } } private[this] def defaultArtifact(a: DependencyDescriptor): Array[DependencyArtifactDescriptor] = { diff --git a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala new file mode 100644 index 000000000..65749a28d --- /dev/null +++ b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala @@ -0,0 +1,34 @@ +package sbt.internal.librarymanagement + +import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor } +import sbt.librarymanagement._ +import sbt.internal.librarymanagement.ivyint._ + +class MergeDescriptorSpec extends BaseIvySpecification { + "Merging duplicate dependencies" should "work" in { + cleanIvyCache() + val m = module( + ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), + Vector(guavaTest, guavaTestTests), None, UpdateOptions() + ) + m.withModule(log) { + case (ivy, md, _) => + val deps = md.getDependencies + assert(deps.size == 1) + deps.headOption.getOrElse(sys.error("Dependencies not found")) match { + case dd @ MergedDescriptors(dd0, dd1) => + val arts = dd.getAllDependencyArtifacts + val a0: DependencyArtifactDescriptor = arts.toList(0) + val a1: DependencyArtifactDescriptor = arts.toList(1) + val configs0 = a0.getConfigurations.toList + val configs1 = a1.getConfigurations.toList + configs0 shouldEqual List("compile") + configs1 shouldEqual List("test") + } + } + } + def guavaTest = ModuleID("com.google.guava", "guava-tests", "18.0").withConfigurations(Option("compile")) + def guavaTestTests = ModuleID("com.google.guava", "guava-tests", "18.0").withConfigurations(Option("test")).classifier("tests") + def defaultOptions = EvictionWarningOptions.default + +} From 5b752c8522e3a334e7d16b55dfc2de4da7bb60aa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 15 Jan 2017 03:00:14 -0500 Subject: [PATCH 0558/1030] Adds DefaultLibraryManagement https://github.com/sbt/sbt/pull/2780/ --- .../DefaultLibraryManagement.scala | 83 +++++++++++++++++++ .../librarymanagement/LibraryManagement.scala | 8 ++ 2 files changed, 91 insertions(+) create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala new file mode 100644 index 000000000..127084e30 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -0,0 +1,83 @@ +package sbt +package librarymanagement + +import java.io.File +import scala.util.Try +import sbt.internal.librarymanagement._ +import sbt.util.Logger +import sbt.io.Hash + +class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) extends LibraryManagement { + private[sbt] val ivySbt: IvySbt = new IvySbt(ivyConfiguration, DefaultFileToStore) + private val sbtOrgTemp = JsonUtil.sbtOrgTemp + private val modulePrefixTemp = "temp-module-" + + type Module = ivySbt.Module + + /** + * Returns a dummy module that depends on `moduleID`. + * Note: Sbt's implementation of Ivy requires us to do this, because only the dependencies + * of the specified module will be downloaded. + */ + def getModule(moduleId: ModuleID): Module = getModule(moduleId, None) + + def getModule(moduleId: ModuleID, ivyScala: Option[IvyScala]): ivySbt.Module = { + val sha1 = Hash.toHex(Hash(moduleId.name)) + val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleId.revision).withConfigurations(moduleId.configurations) + getModule(dummyID, Vector(moduleId), UpdateOptions(), ivyScala) + } + + def getModule(moduleId: ModuleID, deps: Vector[ModuleID], + uo: UpdateOptions = UpdateOptions(), ivyScala: Option[IvyScala]): ivySbt.Module = { + val moduleSetting = InlineConfiguration( + validate = false, + ivyScala = ivyScala, + module = moduleId, + moduleInfo = ModuleInfo(moduleId.name), + dependencies = deps + ).withConfigurations(Vector(Configurations.Component)) + new ivySbt.Module(moduleSetting) + } + + private def dependenciesNames(module: ivySbt.Module): String = + module.moduleSettings match { + // `module` is a dummy module, we will only fetch its dependencies. + case ic: InlineConfiguration => + ic.dependencies map { + case mID: ModuleID => + import mID._ + s"$organization % $name % $revision" + } mkString ", " + case _ => + s"unknown" + } + + def update(module: ivySbt.Module, retrieveDirectory: File)(predicate: File => Boolean): Option[Seq[File]] = { + val specialArtifactTypes = Artifact.DefaultSourceTypes union Artifact.DefaultDocTypes + val artifactFilter = ArtifactTypeFilter.forbid(specialArtifactTypes) + val retrieveConfiguration = RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern).withSync(false) + val updateConfiguration = UpdateConfiguration(Some(retrieveConfiguration), true, UpdateLogging.DownloadOnly, artifactFilter) + + log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.") + IvyActions.updateEither(module, updateConfiguration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { + case Left(unresolvedWarning) => + log.debug("Couldn't retrieve module ${dependenciesNames(module)}.") + None + + case Right(updateReport) => + val allFiles = + for { + conf <- updateReport.configurations + m <- conf.modules + (_, f) <- m.artifacts + } yield f + + log.debug(s"Files retrieved for ${dependenciesNames(module)}:") + log.debug(allFiles mkString ", ") + allFiles filter predicate match { + case Seq() => None + case files => Some(files) + } + } + } +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala new file mode 100644 index 000000000..ce86cc0b5 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala @@ -0,0 +1,8 @@ +package sbt.librarymanagement + +// Interface for library management + +trait LibraryManagement { + type Module + def getModule(moduleId: ModuleID): Module +} From 5380b2fe7302c7a83148066aa62f25657374ca37 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 15 Jan 2017 05:36:39 -0500 Subject: [PATCH 0559/1030] Forward port "Support wildcard exclusions" Ref https://github.com/sbt/sbt/pull/2731 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8aa939206..f93084d11 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -42,7 +42,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cc8d2761242b072cedb0a04cb39435c4fa24f9a" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cf13e211b2cb31f0d3b317289dca70eca3362f6" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") From f495291eddde0dc2863a2ccb60882f5cd2cf6d40 Mon Sep 17 00:00:00 2001 From: Miles Sabin Date: Sun, 15 Jan 2017 07:55:18 -0500 Subject: [PATCH 0560/1030] fport: CrossVersion.patch CrossVersion.full strips off -bin-suffix. Ref https://github.com/sbt/sbt/pull/2757 --- .../src/main/contraband/librarymanagement.json | 10 ++++++++++ .../librarymanagement/CrossVersionExtra.scala | 14 ++++++++++++++ .../src/test/scala/CrossVersionTest.scala | 18 ++++++++++++++++++ 3 files changed, 42 insertions(+) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 8dd2d1cc9..6497a557f 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -144,6 +144,16 @@ ], "type": "record" }, + { + "name": "Patch", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": [ + "Cross-versions a module by stripping off -bin-suffix.", + "This is intented for patch-version compatible alternative replacements." + ], + "type": "record" + }, { "name": "Full", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index ae1ec1c61..d8d63b7a8 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -18,6 +18,19 @@ abstract class CrossVersionFunctions { /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() + /** + * Cross-versions a module with the full Scala version excluding any `-bin` suffix. + */ + def patch: CrossVersion = Patch() + + private[sbt] def patchFun(fullVersion: String): String = { + val BinCompatV = """(\d+)\.(\d+)\.(\d+)(-\w+)??-bin(-.*)?""".r + fullVersion match { + case BinCompatV(x, y, z, w, _) => s"""$x.$y.$z${if (w == null) "" else w}""" + case other => other + } + } + private[sbt] def append(s: String): Option[String => String] = Some(x => crossName(x, s)) /** @@ -29,6 +42,7 @@ abstract class CrossVersionFunctions { cross match { case _: Disabled => None case _: Binary => append(binaryVersion) + case _: Patch => append(patchFun(fullVersion)) case _: Full => append(fullVersion) } diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index c179623fb..e5b1b1f9c 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -114,6 +114,24 @@ class CrossVersionTest extends UnitSpec { it should "return binary Scala version for 2.10.1 as 2.10" in { CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" } + it should "return patch Scala version for 2.11.8 as 2.11.8" in { + CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8") + } + it should "return patch Scala version for 2.11.8-M1 as 2.11.8-M1" in { + CrossVersion(CrossVersion.patch, "2.11.8-M1", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") + } + it should "return patch Scala version for 2.11.8-RC1 as 2.11.8-RC1" in { + CrossVersion(CrossVersion.patch, "2.11.8-RC1", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") + } + it should "return patch Scala version for 2.11.8-bin-extra as 2.11.8" in { + CrossVersion(CrossVersion.patch, "2.11.8-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8") + } + it should "return patch Scala version for 2.11.8-M1-bin-extra as 2.11.8-M1" in { + CrossVersion(CrossVersion.patch, "2.11.8-M1-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") + } + it should "return patch Scala version for 2.11.8-RC1-bin-extra as 2.11.8-RC1" in { + CrossVersion(CrossVersion.patch, "2.11.8-RC1-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") + } it should "return disabled cross version as equal to a copy" in { Disabled() shouldBe Disabled() } From c12c9c6187baf15bc24796693bb9f949d53406c8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 11 Nov 2016 02:44:56 -0500 Subject: [PATCH 0561/1030] Apply scalaVersion enforcement to Compile related configs Fixes #2786. Ref #2634. sbt 0.13.12 added Ivy mediator that enforces scalaOrganization and scalaVersion for Scala toolchain artifacts. This turns out to be a bit too aggressive because Ivy configurations can be used as an independent dependency graph that does not rely on the scalaVersion used by Compile configuration. By enforcing scalaVersion in those graph causes runtime failure. This change checks if the configuration extends Default, Compile, Provided, or Optional before enforcing scalaVersion. --- .../sbt/internal/librarymanagement/Ivy.scala | 16 +++++++++++++++- .../librarymanagement/ConfigurationExtra.scala | 9 +++++++++ .../sbt/librarymanagement/IvyScalaExtra.scala | 16 ++++++++++------ 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 320f549a0..3198c95d0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -168,7 +168,21 @@ final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => Cac case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } - moduleSettings.ivyScala.foreach(IvyScala.checkModule(baseModule, baseConfiguration, configuration.log)) + + val configs = + moduleSettings match { + case ic: InlineConfiguration => ic.configurations + case ic: InlineConfigurationWithExcludes => ic.configurations + case ec: EmptyConfiguration => Nil + case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal + case ifc: IvyFileConfiguration => Configurations.default ++ Configurations.defaultInternal + } + moduleSettings.ivyScala match { + case Some(is) => + val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } + IvyScala.checkModule(baseModule, baseConfiguration, svc, configuration.log)(is) + case _ => // do nothing + } IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index f3b267e24..8e30e5c6c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -47,6 +47,15 @@ object Configurations { private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) + + /** Returns true if the configuration should be under the influence of scalaVersion. */ + private[sbt] def underScalaVersion(c: Configuration): Boolean = + c match { + case Default | Compile | IntegrationTest | Provided | Runtime | Test | Optional | + CompilerPlugin | CompileInternal | RuntimeInternal | TestInternal => true + case config => + config.extendsConfigs exists underScalaVersion + } } abstract class ConfigurationExtra { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 39ecbace4..625c5e00f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -47,24 +47,28 @@ import ScalaArtifacts._ private[sbt] abstract class IvyScalaFunctions { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String, log: Logger)(check: IvyScala): Unit = { + def checkModule(module: DefaultModuleDescriptor, conf: String, scalaVersionConfigs: Vector[String], log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, check.configurations, log) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion) + overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion, scalaVersionConfigs) } - class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String) extends DependencyDescriptorMediator { + class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String, scalaVersionConfigs0: Vector[String]) extends DependencyDescriptorMediator { + private[this] val scalaVersionConfigs = scalaVersionConfigs0.toSet def mediate(dd: DependencyDescriptor): DependencyDescriptor = { + // Mediate only for the dependencies in scalaVersion configurations. https://github.com/sbt/sbt/issues/2786 + def configQualifies: Boolean = + (dd.getModuleConfigurations exists { scalaVersionConfigs }) val transformer = new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid else mrid.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) if configQualifies => ModuleRevisionId.newInstance(scalaOrganization, name, mrid.getBranch, scalaVersion, mrid.getQualifiedExtraAttributes) case _ => mrid } @@ -77,8 +81,8 @@ private[sbt] abstract class IvyScalaFunctions { } } - def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String): Unit = { - val mediator = new OverrideScalaMediator(organization, version) + def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String, scalaVersionConfigs: Vector[String]): Unit = { + val mediator = new OverrideScalaMediator(organization, version, scalaVersionConfigs) module.addDependencyDescriptorMediator(new ModuleId(Organization, "*"), ExactPatternMatcher.INSTANCE, mediator) if (organization != Organization) module.addDependencyDescriptorMediator(new ModuleId(organization, "*"), ExactPatternMatcher.INSTANCE, mediator) From a809e8744efa69755139b920d4f9fbfefa99d98f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 11 Nov 2016 14:42:48 -0500 Subject: [PATCH 0562/1030] Bump up Ivy Fixes #2015 --- project/Dependencies.scala | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f93084d11..82c63e485 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -34,7 +34,6 @@ object Dependencies { } def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) - def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) def addSbtUtilTesting(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) @@ -42,7 +41,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-2cf13e211b2cb31f0d3b317289dca70eca3362f6" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") From 95a209b033499c0bf05cb40ee40741acae7f5805 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 11 Nov 2016 04:25:18 -0500 Subject: [PATCH 0563/1030] Apply binary version conflict check to Compile related configs Fixes #1466 Ref #2786 Even after fixing the mediator issue, we still have spurious binary version conflict warning that does not account for sandbox configurations. This change follows the scalaVersionConfigs work. --- .../main/scala/sbt/librarymanagement/IvyScalaExtra.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 625c5e00f..13cd79154 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -49,7 +49,7 @@ private[sbt] abstract class IvyScalaFunctions { /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ def checkModule(module: DefaultModuleDescriptor, conf: String, scalaVersionConfigs: Vector[String], log: Logger)(check: IvyScala): Unit = { if (check.checkExplicit) - checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, check.configurations, log) + checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, scalaVersionConfigs, log) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) @@ -98,8 +98,8 @@ private[sbt] abstract class IvyScalaFunctions { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Seq[String], scalaBinaryVersion: String, configurations: Iterable[Configuration], log: Logger): Unit = { - val configSet = if (configurations.isEmpty) (c: String) => true else configurationSet(configurations) + private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Vector[String], scalaBinaryVersion: String, scalaVersionConfigs0: Vector[String], log: Logger): Unit = { + val scalaVersionConfigs: String => Boolean = if (scalaVersionConfigs0.isEmpty) (c: String) => false else scalaVersionConfigs0.toSet def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId @@ -107,7 +107,7 @@ private[sbt] abstract class IvyScalaFunctions { def isScalaLangOrg = id.getOrganisation == scalaOrganization def isScalaArtifact = scalaArtifacts.contains(id.getName) def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion - def matchesOneOfTheConfigs = dep.getModuleConfigurations.exists(configSet) + def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some("Binary version (" + depBinaryVersion + ") for dependency " + id + From 27397de8cfcd824f8ab15901e9a951f16a305647 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 15 Jan 2017 09:27:26 -0500 Subject: [PATCH 0564/1030] Adjust to upstream --- .../main/scala/sbt/internal/librarymanagement/Ivy.scala | 8 +++----- librarymanagement/src/test/scala/ScalaOverrideTest.scala | 4 +++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 3198c95d0..76ba4ce33 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -171,11 +171,9 @@ final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => Cac val configs = moduleSettings match { - case ic: InlineConfiguration => ic.configurations - case ic: InlineConfigurationWithExcludes => ic.configurations - case ec: EmptyConfiguration => Nil - case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal - case ifc: IvyFileConfiguration => Configurations.default ++ Configurations.defaultInternal + case ic: InlineConfiguration => ic.configurations + case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal + case ifc: IvyFileConfiguration => Configurations.default ++ Configurations.defaultInternal } moduleSettings.ivyScala match { case Some(is) => diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala index bf0b82e3e..f14a2d6ca 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -12,10 +12,12 @@ class ScalaOverrideTest extends UnitSpec { val OtherOrgID = "other.org" def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { - val osm = new OverrideScalaMediator(org0, version0) + val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map { _.name } + val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) val mrid = ModuleRevisionId.newInstance(org1, name1, version1) val dd = new DefaultDependencyDescriptor(mrid, false) + dd.addDependencyConfiguration("compile", "compile") val res = osm.mediate(dd) res.getDependencyRevisionId shouldBe ModuleRevisionId.newInstance(org0, name1, version0) From caecbbabe77d3527e7314fd7d29ce8ed176786e2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 15 Feb 2017 23:12:01 -0500 Subject: [PATCH 0565/1030] util 1.0.0-M19 --- .../scala/sbt/internal/librarymanagement/IvyActions.scala | 4 ++-- .../main/scala/sbt/librarymanagement/EvictionWarning.scala | 2 +- project/Dependencies.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 13a5d040b..2157f9113 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -17,8 +17,8 @@ import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import sbt.io.{ IO, PathFinder } -import sbt.util.Logger -import sbt.internal.util.{ ShowLines, SourcePosition, LinePosition, RangePosition, LineRange } +import sbt.util.{ Logger, ShowLines } +import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } import sbt.librarymanagement._ import sbt.internal.librarymanagement.syntax._ import sbt.internal.librarymanagement._ diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index dde946c1f..853efa332 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -4,7 +4,7 @@ import collection.mutable import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } import sbt.util.Logger -import sbt.internal.util.ShowLines +import sbt.util.ShowLines import sbt.internal.librarymanagement.{ InlineConfiguration, IvySbt } final class EvictionWarningOptions private[sbt] ( diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 82c63e485..d73001e7e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,7 @@ object Dependencies { val scala212 = "2.12.1" private val ioVersion = "1.0.0-M9" - private val utilVersion = "1.0.0-M18" + private val utilVersion = "1.0.0-M19" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From c793c33740fc191f0434c398e683c31fedb571ea Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 15 Feb 2017 23:41:23 -0500 Subject: [PATCH 0566/1030] fix test --- librarymanagement/src/test/scala/CachedResolutionSpec.scala | 2 +- librarymanagement/src/test/scala/EvictionWarningSpec.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 182fa9521..066286f46 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -1,6 +1,6 @@ package sbt.internal.librarymanagement -import sbt.internal.util.ShowLines +import sbt.util.ShowLines import sbt.librarymanagement._ class CachedResolutionSpec extends BaseIvySpecification { diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 21d59b10a..ce834ac76 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -60,7 +60,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def defaultOptions = EvictionWarningOptions.default - import sbt.internal.util.ShowLines._ + import sbt.util.ShowLines._ def scalaVersionDeps = Vector(scala2102, akkaActor230) From 31a7407640d7569aa8e6dfe2c0cec8f4f0b51a24 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 2 Mar 2017 14:42:36 +0100 Subject: [PATCH 0567/1030] Remove build warnings Also collapse into one meta-build sbt file.. imo a better alternative toa adding a 5th single-line sbt file. --- project/bintray.sbt | 1 - project/contraband.sbt | 1 - project/doge.sbt | 1 - project/house.sbt | 1 - project/plugins.sbt | 6 ++++++ 5 files changed, 6 insertions(+), 4 deletions(-) delete mode 100644 project/bintray.sbt delete mode 100644 project/contraband.sbt delete mode 100644 project/doge.sbt delete mode 100644 project/house.sbt create mode 100644 project/plugins.sbt diff --git a/project/bintray.sbt b/project/bintray.sbt deleted file mode 100644 index 8dd913f98..000000000 --- a/project/bintray.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") diff --git a/project/contraband.sbt b/project/contraband.sbt deleted file mode 100644 index 88961b8f9..000000000 --- a/project/contraband.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M3") diff --git a/project/doge.sbt b/project/doge.sbt deleted file mode 100644 index fedea9490..000000000 --- a/project/doge.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") diff --git a/project/house.sbt b/project/house.sbt deleted file mode 100644 index bad061ebe..000000000 --- a/project/house.sbt +++ /dev/null @@ -1 +0,0 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") diff --git a/project/plugins.sbt b/project/plugins.sbt new file mode 100644 index 000000000..3c7fb1497 --- /dev/null +++ b/project/plugins.sbt @@ -0,0 +1,6 @@ +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") +addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M3") +addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") + +scalacOptions += "-language:postfixOps" From 016db588d489e6e32743b9119bb651bc8a3052d1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 17 Mar 2017 23:03:37 -0400 Subject: [PATCH 0568/1030] sbt-contraband 0.3.0-M4 --- project/plugins.sbt | 2 +- sbt-allsources.sh | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100755 sbt-allsources.sh diff --git a/project/plugins.sbt b/project/plugins.sbt index 3c7fb1497..767bccb53 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M3") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M4") addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") scalacOptions += "-language:postfixOps" diff --git a/sbt-allsources.sh b/sbt-allsources.sh new file mode 100755 index 000000000..1751f0fb9 --- /dev/null +++ b/sbt-allsources.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +sbt -Dsbtio.path=../io -Dsbtutil.path=../util "$@" From d6f0924689606ab2ddd4c2430196ebca999ec724 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 22 Mar 2017 13:59:51 -0400 Subject: [PATCH 0569/1030] Util 1.0.0-M20 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d73001e7e..26271740c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,7 @@ object Dependencies { val scala212 = "2.12.1" private val ioVersion = "1.0.0-M9" - private val utilVersion = "1.0.0-M19" + private val utilVersion = "1.0.0-M20" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 92cc7c4cb1a648c7830d9a63da8957dff9c7fc1c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 31 Mar 2017 10:10:37 +0100 Subject: [PATCH 0570/1030] Remove some compile warnings --- .../sbt/internal/librarymanagement/IvyActions.scala | 1 - .../ivyint/CachedResolutionResolveEngine.scala | 6 +++--- .../main/scala/sbt/librarymanagement/Credentials.scala | 4 ++-- .../sbt/librarymanagement/DefaultLibraryManagement.scala | 3 +-- .../src/test/scala/DMSerializationSpec.scala | 9 ++++++--- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 2157f9113..0230b5791 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -21,7 +21,6 @@ import sbt.util.{ Logger, ShowLines } import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } import sbt.librarymanagement._ import sbt.internal.librarymanagement.syntax._ -import sbt.internal.librarymanagement._ final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Vector[Configuration]], val logging: UpdateLogging) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Vector[String], val logging: UpdateLogging, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7dcc35d65..ddff21597 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -123,13 +123,13 @@ private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) } def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { - import scala.collection.JavaConversions._ - (md0.getAllDependencyDescriptorMediators.getAllRules).toSeq.toVector sortBy { + import scala.collection.JavaConverters._ + md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { case (k, v) => k.toString } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => - val attr: Map[Any, Any] = k.getAttributes.toMap + val attr: Map[Any, Any] = k.getAttributes.asScala.toMap val module = IvyModuleId.newInstance(attr(IvyPatternHelper.ORGANISATION_KEY).toString, attr(IvyPatternHelper.MODULE_KEY).toString) val pm = k.getPatternMatcher IvyOverride(module, pm, v) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala index 3f075f2b7..55dffa367 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala @@ -58,12 +58,12 @@ object Credentials { private[this] val UserKeys = List("user", "user.name", "username") private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") - import collection.JavaConversions._ + import collection.JavaConverters._ private[this] def read(from: File): Map[String, String] = { val properties = new java.util.Properties IO.load(properties, from) - properties.map { case (k, v) => (k.toString, v.toString.trim) }.toMap + properties.asScala.map { case (k, v) => (k.toString, v.toString.trim) }.toMap } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 127084e30..01a87378b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement import java.io.File -import scala.util.Try import sbt.internal.librarymanagement._ import sbt.util.Logger import sbt.io.Hash @@ -61,7 +60,7 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.") IvyActions.updateEither(module, updateConfiguration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { case Left(unresolvedWarning) => - log.debug("Couldn't retrieve module ${dependenciesNames(module)}.") + log.debug(s"Couldn't retrieve module ${dependenciesNames(module)}.") None case Right(updateReport) => diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index bbbeef4f8..5c6a89db7 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -6,6 +6,7 @@ import java.io.File import sbt.internal._, librarymanagement._, util.UnitSpec import scala.json.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ +import org.scalatest.Assertion import LibraryManagementCodec._ @@ -61,11 +62,13 @@ class DMSerializationSpec extends UnitSpec { lazy val moduleReportExample = ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) - def roundtrip[A: JsonReader: JsonWriter](a: A): Unit = + def roundtrip[A: JsonReader: JsonWriter](a: A): Assertion = roundtripBuilder(a) { _ shouldBe _ } - def roundtripStr[A: JsonReader: JsonWriter](a: A): Unit = + + def roundtripStr[A: JsonReader: JsonWriter](a: A): Assertion = roundtripBuilder(a) { _.toString shouldBe _.toString } - def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit = + + def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Assertion): Assertion = { val json = isoString to (Converter toJsonUnsafe a) println(json) From 87e8d878114ea4c6e1b7da4851ea67f03b11ed7c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 31 Mar 2017 10:24:16 +0100 Subject: [PATCH 0571/1030] Allow for some customization in CrossVersion results The old way to customize CrossVersion results was a `String => String` function called 'remapVersion', removed in 301ec787f2f17367064cda5eef3a9009ba66e21f. That was removed because it's not possible to serialise Function1s, and we want to serialise CrossVersion (and therefore ModuleID, etc) to be able to transfer them in sbt server. This commit reintroduces a less-powerful way to vary the results of apply CrossVersion, but just providing the opportunity to define a suffix. From looking at the users of CrossVersion (Scala.js' sbt-scalajs-plugin & Scala Native's sbt-crossproject) this looks to be sufficient. --- .../main/contraband/librarymanagement.json | 20 ++++++++++--------- .../librarymanagement/CrossVersionExtra.scala | 16 +++++++++++++-- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 6497a557f..34d1c8e63 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -138,11 +138,12 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "doc": [ - "Cross-versions a module using the result of applying `remapVersion` to the binary version.", - "For example, if `remapVersion = v => \"2.10\"` and the binary version is \"2.9.2\" or \"2.10\",", - "the module is cross-versioned with \"2.10\"." + "Cross-versions a module using the result of appending `suffix` to the binary version.", + "For example, if `suffix = \"_foo\"` and the binary version is \"2.10\",", + "the module is cross-versioned with \"2.10_foo\"." ], - "type": "record" + "type": "record", + "fields": [ { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } ] }, { "name": "Patch", @@ -150,7 +151,7 @@ "target": "Scala", "doc": [ "Cross-versions a module by stripping off -bin-suffix.", - "This is intented for patch-version compatible alternative replacements." + "This is intended for patch-version compatible alternative replacements." ], "type": "record" }, @@ -160,10 +161,11 @@ "target": "Scala", "type": "record", "doc": [ - "Cross-versions a module with the result of applying `remapVersion` to the full version.", - "For example, if `remapVersion = v => \"2.10\"` and the full version is \"2.9.2\" or \"2.10.3\",", - "the module is cross-versioned with \"2.10\"." - ] + "Cross-versions a module with the result of appending `suffix` to the full version.", + "For example, if `suffix = \"_foo\"` and the full version is \"2.12.1\",", + "the module is cross-versioned with \"2.12.1_foo\"." + ], + "fields": [ { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } ] } ], "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index d8d63b7a8..d9227b841 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -15,9 +15,21 @@ abstract class CrossVersionFunctions { /** Cross-versions a module with the full version (typically the full Scala version). */ def full: CrossVersion = Full() + /** + * Cross-versions a module with the result of appending `suffix` to the full version. + * (typically the full Scala version). See also [[sbt.librarymanagement.Full]] + */ + def fullSuffixed(suffix: String): CrossVersion = Full(suffix) + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() + /** + * Cross-versions a module with the result of appending `suffix` to the binary version + * (typically the binary Scala version). See also [[sbt.librarymanagement.Binary]]. + */ + def binarySuffixed(suffix: String): CrossVersion = Binary(suffix) + /** * Cross-versions a module with the full Scala version excluding any `-bin` suffix. */ @@ -41,9 +53,9 @@ abstract class CrossVersionFunctions { def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { case _: Disabled => None - case _: Binary => append(binaryVersion) + case b: Binary => append(binaryVersion + b.suffix) case _: Patch => append(patchFun(fullVersion)) - case _: Full => append(fullVersion) + case f: Full => append(fullVersion + f.suffix) } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ From fb049d181b4a30a10ab11e67aa06411cad0db74b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 31 Mar 2017 10:47:35 +0100 Subject: [PATCH 0572/1030] Add prefix support to Binary/Full --- .../main/contraband/librarymanagement.json | 24 ++++++++++++------- .../librarymanagement/CrossVersionExtra.scala | 12 +++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 34d1c8e63..2880c89e1 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -138,12 +138,16 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "doc": [ - "Cross-versions a module using the result of appending `suffix` to the binary version.", - "For example, if `suffix = \"_foo\"` and the binary version is \"2.10\",", - "the module is cross-versioned with \"2.10_foo\"." + "Cross-versions a module using the result of", + "prepending `prefix` and appending `suffix` to the binary version.", + "For example, if `prefix = \"foo_\"` and `suffix = \"_bar\"` and the binary version is \"2.10\",", + "the module is cross-versioned with \"foo_2.10_bar\"." ], "type": "record", - "fields": [ { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } ] + "fields": [ + { "name": "prefix", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } + ] }, { "name": "Patch", @@ -161,11 +165,15 @@ "target": "Scala", "type": "record", "doc": [ - "Cross-versions a module with the result of appending `suffix` to the full version.", - "For example, if `suffix = \"_foo\"` and the full version is \"2.12.1\",", - "the module is cross-versioned with \"2.12.1_foo\"." + "Cross-versions a module with the result of", + "prepending `prefix` and appending `suffix` to the full version.", + "For example, if `prefix = \"foo_\"` and `suffix = \"_bar\"` and the full version is \"2.12.1\",", + "the module is cross-versioned with \"foo_2.12.1_bar\"." ], - "fields": [ { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } ] + "fields": [ + { "name": "prefix", "type": "String", "default": "\"\"", "since": "0.0.1" }, + { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } + ] } ], "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index d9227b841..e4d172b7a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -16,19 +16,19 @@ abstract class CrossVersionFunctions { def full: CrossVersion = Full() /** - * Cross-versions a module with the result of appending `suffix` to the full version. + * Cross-versions a module with the result of prepending `prefix` and appending `suffix` to the full version. * (typically the full Scala version). See also [[sbt.librarymanagement.Full]] */ - def fullSuffixed(suffix: String): CrossVersion = Full(suffix) + def fullWith(prefix: String, suffix: String): CrossVersion = Full(prefix, suffix) /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() /** - * Cross-versions a module with the result of appending `suffix` to the binary version + * Cross-versions a module with the result of prepending `prefix` and appending `suffix` to the binary version * (typically the binary Scala version). See also [[sbt.librarymanagement.Binary]]. */ - def binarySuffixed(suffix: String): CrossVersion = Binary(suffix) + def binaryWith(prefix: String, suffix: String): CrossVersion = Binary(prefix, suffix) /** * Cross-versions a module with the full Scala version excluding any `-bin` suffix. @@ -53,9 +53,9 @@ abstract class CrossVersionFunctions { def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = cross match { case _: Disabled => None - case b: Binary => append(binaryVersion + b.suffix) + case b: Binary => append(b.prefix + binaryVersion + b.suffix) case _: Patch => append(patchFun(fullVersion)) - case f: Full => append(fullVersion + f.suffix) + case f: Full => append(f.prefix + fullVersion + f.suffix) } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ From 084c94a93c5a8809b3e4aefc49e6d4ffd6a9ba9a Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 31 Mar 2017 15:02:12 +0100 Subject: [PATCH 0573/1030] Recover lost ssh-based repo API Recover APIs I accidentally removed in f2efa10af1ead99b830edc01caf3b9b1be7e0d15. --- .../main/contraband/librarymanagement.json | 3 ++ .../sbt/librarymanagement/ResolverExtra.scala | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 6497a557f..8c0c59b16 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -514,6 +514,7 @@ "target": "Scala", "type": "interface", "doc": "sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library..", + "parents": "sbt.librarymanagement.SshBasedRepositoryExtra", "fields": [ { "name": "connection", "type": "sbt.librarymanagement.SshConnection" } ], @@ -524,6 +525,7 @@ "target": "Scala", "type": "record", "doc": "sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh.", + "parents": "sbt.librarymanagement.SshRepositoryExtra", "fields": [ { "name": "publishPermissions", "type": "String?" } ], @@ -542,6 +544,7 @@ "target": "Scala", "type": "record", "doc": "sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp.", + "parents": "sbt.librarymanagement.SftpRepositoryExtra", "extra": [ "def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = ", " this(name, patterns, connection)" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index ce939a1ce..b772e0840 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -41,6 +41,48 @@ abstract class PatternsFunctions { } } +trait SshBasedRepositoryExtra { + /** The object representing the configured ssh connection for this repository. */ + def connection: SshConnection + + type RepositoryType <: SshBasedRepository + protected def copy(connection: SshConnection): RepositoryType + private def copy(authentication: SshAuthentication): RepositoryType = + copy(connection withAuthentication authentication) + + /** Configures this to use the specified user name and password when connecting to the remote repository. */ + def as(user: String, password: String): RepositoryType = as(user, Some(password)) + def as(user: String): RepositoryType = as(user, None) + def as(user: String, password: Option[String]): RepositoryType = copy(PasswordAuthentication(user, password)) + + /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ + def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) + def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) + + def as(user: String, keyfile: File, password: Option[String]): RepositoryType = + copy(KeyFileAuthentication(user, keyfile, password)) +} + +trait SshRepositoryExtra extends SshBasedRepositoryExtra { + def name: String + def patterns: sbt.librarymanagement.Patterns + def publishPermissions: Option[String] + + type RepositoryType = SshRepository + + protected def copy(connection: SshConnection): SshRepository = + SshRepository(name, connection, patterns, publishPermissions) +} + +trait SftpRepositoryExtra extends SshBasedRepositoryExtra { + def name: String + def patterns: sbt.librarymanagement.Patterns + + type RepositoryType = SftpRepository + + protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) +} + /** A repository that conforms to sbt launcher's interface */ private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Repository { def rawRepository = new RawRepository(resolver) From cbdbf23127a1737c82e026d4d1e62520901ae54b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 31 Mar 2017 18:05:32 +0100 Subject: [PATCH 0574/1030] Expose RichUpdateReport & DependencyFilter Fixes #42 --- .../librarymanagement/DependencyFilter.scala | 3 +-- .../librarymanagement/RichUpdateReport.scala | 25 +++++++++++-------- 2 files changed, 15 insertions(+), 13 deletions(-) rename librarymanagement/src/main/scala/sbt/{internal => }/librarymanagement/DependencyFilter.scala (98%) rename librarymanagement/src/main/scala/sbt/{internal => }/librarymanagement/RichUpdateReport.scala (77%) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 3b0cc28ef..644e43579 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/DependencyFilter.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -1,10 +1,9 @@ /* sbt -- Simple Build Tool * Copyright 2011 Mark Harrah */ -package sbt.internal.librarymanagement +package sbt.librarymanagement import sbt.io.{ AllPassFilter, NameFilter } -import sbt.librarymanagement._ trait DependencyFilterExtra { def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala similarity index 77% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala rename to librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index ad6d3ae01..d9b63c928 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -1,13 +1,11 @@ package sbt -package internal package librarymanagement import java.io.File -import sbt.librarymanagement._ /** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ final class RichUpdateReport(report: UpdateReport) { - def recomputeStamps(): UpdateReport = + private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles val stamps = files.map(f => (f, f.lastModified)).toMap @@ -17,13 +15,17 @@ final class RichUpdateReport(report: UpdateReport) { import DependencyFilter._ /** Obtains all successfully retrieved files in all configurations and modules. */ - def allFiles: Seq[File] = matching(DependencyFilter.allPass) + private[sbt] def allFiles: Seq[File] = matching(DependencyFilter.allPass) /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + private[sbt] def matching(f: DependencyFilter): Seq[File] = select0(f).distinct /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ - def select(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): Seq[File] = + def select( + configuration: ConfigurationFilter = configurationFilter(), + module: ModuleFilter = moduleFilter(), + artifact: ArtifactFilter = artifactFilter() + ): Seq[File] = matching(DependencyFilter.make(configuration, module, artifact)) private[this] def select0(f: DependencyFilter): Seq[File] = @@ -39,7 +41,8 @@ final class RichUpdateReport(report: UpdateReport) { .withArtifacts(modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }) .withMissingArtifacts(modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }) } - def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport = + + private[sbt] def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) modReport @@ -47,19 +50,19 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts(modReport.missingArtifacts) } - def toSeq: Seq[(String, ModuleID, Artifact, File)] = + private[sbt] def toSeq: Seq[(String, ModuleID, Artifact, File)] = for (confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) - def allMissing: Seq[(String, ModuleID, Artifact)] = + private[sbt] def allMissing: Seq[(String, ModuleID, Artifact)] = for (confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield (confReport.configuration, modReport.module, artifact) - def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = + private[sbt] def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => modReport .withMissingArtifacts((modReport.missingArtifacts ++ f(modReport.module)).distinct) } - def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = + private[sbt] def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = { val newConfigurations = report.configurations.map { confReport => import confReport._ From 723abc945f8e5a5239af9abd297b3fa33c91eaa2 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 3 Apr 2017 11:22:38 +0100 Subject: [PATCH 0575/1030] Overload RichUpdateReport#select instead of using default args --- .../sbt/librarymanagement/RichUpdateReport.scala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index d9b63c928..12fb4be8d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -20,14 +20,14 @@ final class RichUpdateReport(report: UpdateReport) { /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ private[sbt] def matching(f: DependencyFilter): Seq[File] = select0(f).distinct - /** Obtains all successfully retrieved files matching all provided filters. An unspecified argument matches all files. */ - def select( - configuration: ConfigurationFilter = configurationFilter(), - module: ModuleFilter = moduleFilter(), - artifact: ArtifactFilter = artifactFilter() - ): Seq[File] = + /** Obtains all successfully retrieved files matching all provided filters. */ + def select(configuration: ConfigurationFilter, module: ModuleFilter, artifact: ArtifactFilter): Seq[File] = matching(DependencyFilter.make(configuration, module, artifact)) + def select(configuration: ConfigurationFilter): Seq[File] = select(configuration, moduleFilter(), artifactFilter()) + def select(module: ModuleFilter): Seq[File] = select(configurationFilter(), module, artifactFilter()) + def select(artifact: ArtifactFilter): Seq[File] = select(configurationFilter(), moduleFilter(), artifact) + private[this] def select0(f: DependencyFilter): Seq[File] = for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { if (file == null) sys.error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) From 1afe7114e88cfc154304e6a7f84cf2c240b9526d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 3 Apr 2017 12:12:51 +0100 Subject: [PATCH 0576/1030] Expose RichUpdateReport enrichment --- .../sbt/internal/librarymanagement/IvyActions.scala | 3 +-- .../sbt/internal/librarymanagement/IvyRetrieve.scala | 3 +-- .../ivyint/CachedResolutionResolveEngine.scala | 3 +-- .../scala/sbt/internal/librarymanagement/syntax.scala | 10 ---------- .../librarymanagement/LibraryManagementSyntax.scala | 7 +++++++ 5 files changed, 10 insertions(+), 16 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 0230b5791..cc1a2eda0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -19,8 +19,7 @@ import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import sbt.io.{ IO, PathFinder } import sbt.util.{ Logger, ShowLines } import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } -import sbt.librarymanagement._ -import sbt.internal.librarymanagement.syntax._ +import sbt.librarymanagement._, syntax._ final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Vector[Configuration]], val logging: UpdateLogging) final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Vector[String], val logging: UpdateLogging, diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 2c8ef1049..fa55c51e3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -13,8 +13,7 @@ import report.{ ArtifactDownloadReport, ConfigurationResolveReport, ResolveRepor import resolve.{ IvyNode, IvyNodeCallers } import IvyNodeCallers.{ Caller => IvyCaller } import ivyint.SbtDefaultDependencyDescriptor -import sbt.librarymanagement._ -import sbt.internal.librarymanagement.syntax._ +import sbt.librarymanagement._, syntax._ object IvyRetrieve { def reports(report: ResolveReport): Vector[ConfigurationResolveReport] = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index ddff21597..7159e33e9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -22,8 +22,7 @@ import annotation.tailrec import scala.concurrent.duration._ import sbt.io.{ DirectoryFilter, Hash, IO } import sbt.util.Logger -import sbt.librarymanagement._ -import sbt.internal.librarymanagement.syntax._ +import sbt.librarymanagement._, syntax._ import sbt.internal.util.CacheStore private[sbt] object CachedResolutionResolveCache { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala deleted file mode 100644 index 4ddc5d243..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/syntax.scala +++ /dev/null @@ -1,10 +0,0 @@ -package sbt -package internal -package librarymanagement - -import sbt.librarymanagement._ - -object syntax { - implicit def richUpateReport(ur: UpdateReport): RichUpdateReport = - new RichUpdateReport(ur) -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala new file mode 100644 index 000000000..e6c43d872 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala @@ -0,0 +1,7 @@ +package sbt.librarymanagement + +trait LibraryManagementSyntax { + implicit def richUpdateReport(ur: UpdateReport): RichUpdateReport = new RichUpdateReport(ur) +} + +object syntax extends LibraryManagementSyntax From 9375c88a8bcf970ffd64582a7c83dbff7a0869e5 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Sun, 8 Jan 2017 21:59:19 +0100 Subject: [PATCH 0577/1030] OverrideScalaMediator: fix bootstrapping a Scala compiler Fixes #2867, #2896 --- .../scala/sbt/librarymanagement/IvyScalaExtra.scala | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 13cd79154..4cfffd856 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -62,13 +62,22 @@ private[sbt] abstract class IvyScalaFunctions { // Mediate only for the dependencies in scalaVersion configurations. https://github.com/sbt/sbt/issues/2786 def configQualifies: Boolean = (dd.getModuleConfigurations exists { scalaVersionConfigs }) + // Do not rewrite the dependencies of Scala dependencies themselves, this prevents bootstrapping + // a Scala compiler using another Scala compiler. + def dependeeQualifies: Boolean = + dd.getParentRevisionId.getName match { + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + false + case _ => + true + } val transformer = new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid else mrid.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) if configQualifies => + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) if configQualifies && dependeeQualifies => ModuleRevisionId.newInstance(scalaOrganization, name, mrid.getBranch, scalaVersion, mrid.getQualifiedExtraAttributes) case _ => mrid } From 45288b5f800ab48814e773082e8c01f78e206d2a Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Mon, 9 Jan 2017 01:15:08 +0100 Subject: [PATCH 0578/1030] Avoid NullPointerException in sbt.ScalaOverrideTest --- .../sbt/librarymanagement/IvyScalaExtra.scala | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 4cfffd856..ebab0c081 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -65,12 +65,14 @@ private[sbt] abstract class IvyScalaFunctions { // Do not rewrite the dependencies of Scala dependencies themselves, this prevents bootstrapping // a Scala compiler using another Scala compiler. def dependeeQualifies: Boolean = - dd.getParentRevisionId.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => - false - case _ => - true - } + dd.getParentRevisionId == null || ( + dd.getParentRevisionId.getName match { + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + false + case _ => + true + } + ) val transformer = new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { From 0561c12d193604d07b969b888f6589903b254267 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Tue, 10 Jan 2017 18:44:49 +0100 Subject: [PATCH 0579/1030] Fix support for published dotty nightly builds Dotty nightly builds are published to maven, so they end up in configuration "default", not "compile". We still need to look into "compile" when dotty is published locally. You can test this using https://github.com/smarter/dotty-example-project by updating the sbt version used in project/build.properties and by replacing "0.1.1-SNAPSHOT" by a nightly version like "0.1.1-20170109-be64643-NIGHTLY" in build.sbt --- .../src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index ebab0c081..5a6300430 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -28,7 +28,7 @@ object ScalaArtifacts { private[sbt] def toolDependencies(org: String, version: String, isDotty: Boolean = false): Seq[ModuleID] = if (isDotty) - Seq(ModuleID(org, DottyIDPrefix, version).withConfigurations(Some(Configurations.ScalaTool.name + "->compile")) + Seq(ModuleID(org, DottyIDPrefix, version).withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) .withCrossVersion(CrossVersion.binary)) else Seq( From bb258f42a632f044d40d7d92b0bcd6ffb2fe9701 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 Feb 2017 02:43:26 -0500 Subject: [PATCH 0580/1030] Maven version range improvement Previously, when the dependency resolver (Ivy) encountered a Maven version range such as `[1.3.0,)` it would go out to the Internet to find the latest version. This would result to a surprising behavior where the eventual version keeps changing over time *even when there's a version of the library that satisfies the range condition*. This changes to some Maven version ranges would be replaced with its lower bound so that when a satisfactory version is found in the dependency graph it will be used. You can disable this behavior using the JVM flag `-Dsbt.modversionrange=false`. Fixes #2954 Ref #2291 / #2953 --- .gitignore | 1 + .../librarymanagement/CustomPomParser.scala | 16 +++- .../internal/librarymanagement/MakePom.scala | 50 +---------- .../librarymanagement/VersionRange.scala | 83 +++++++++++++++++++ .../librarymanagement/VersionRangeSpec.scala | 19 +++++ 5 files changed, 120 insertions(+), 49 deletions(-) create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala diff --git a/.gitignore b/.gitignore index 3cedeeb25..96c1348b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ tmp/ target/ +__pycache__ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index fbcf53649..a8336662e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -162,6 +162,17 @@ object CustomPomParser { def isIdentity = false } + // TODO: It would be better if we can make dd.isForce to `false` when VersionRange.isVersionRange is `true`. + private[this] def stripVersionRange(dd: DependencyDescriptor): DependencyDescriptor = + VersionRange.stripMavenVersionRange(dd.getDependencyRevisionId.getRevision) match { + case Some(newVersion) => + val id = dd.getDependencyRevisionId + val newId = ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, newVersion, id.getExtraAttributes) + transform(dd, _ => newId) + case None => dd + } + private[sbt] lazy val versionRangeFlag = sys.props.get("sbt.modversionrange") map { _.toLowerCase == "true" } getOrElse true + import collection.JavaConverters._ def addExtra(properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String, String]], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = { @@ -187,7 +198,10 @@ object CustomPomParser { IvySbt.addExtraNamespace(dmd) val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } - val unique = IvySbt.mergeDuplicateDefinitions(withExtra) + val withVersionRangeMod: Seq[DependencyDescriptor] = + if (versionRangeFlag) withExtra map { stripVersionRange } + else withExtra + val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency for (ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor(new DefaultExtendsDescriptor(md, ed.getLocation, ed.getExtendsTypes)) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 2103cc6f0..5544d0d52 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -26,56 +26,10 @@ import sbt.io.IO object MakePom { /** True if the revision is an ivy-range, not a complete revision. */ - def isDependencyVersionRange(revision: String): Boolean = { - (revision endsWith "+") || - (revision contains "[") || - (revision contains "]") || - (revision contains "(") || - (revision contains ")") - } + def isDependencyVersionRange(revision: String): Boolean = VersionRange.isVersionRange(revision) /** Converts Ivy revision ranges to that of Maven POM */ - def makeDependencyVersion(revision: String): String = { - def plusRange(s: String, shift: Int = 0) = { - def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 - val (prefixVersion, lastVersion) = (s + "0" * shift).reverse.split("\\.", 2) match { - case Array(revLast, revRest) => - (revRest.reverse + ".", revLast.reverse) - case Array(revLast) => ("", revLast.reverse) - } - val lastVersionInt = lastVersion.toInt - s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt + pow(shift)})" - } - val startSym = Set(']', '[', '(') - val stopSym = Set(']', '[', ')') - val DotPlusPattern = """(.+)\.\+""".r - val DotNumPlusPattern = """(.+)\.(\d+)\+""".r - val NumPlusPattern = """(\d+)\+""".r - val maxDigit = 5 - try { - revision match { - case "+" => "[0,)" - case DotPlusPattern(base) => plusRange(base) - // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so - // we assume version ranges never go beyond 5 siginificant digits. - case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") - case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") - case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") - case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => - val start = rev(0) - val stop = rev(rev.length - 1) - val mid = rev.substring(1, rev.length - 1) - (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) - case _ => revision - } - } catch { - case e: NumberFormatException => - // TODO - if the version doesn't meet our expectations, maybe we just issue a hard - // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") - revision - } - } + def makeDependencyVersion(revision: String): String = VersionRange.fromIvyToMavenVersion(revision) } class MakePom(val log: Logger) { import MakePom._ diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala new file mode 100644 index 000000000..bb73c882a --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -0,0 +1,83 @@ +package sbt +package internal +package librarymanagement + +object VersionRange { + /** True if the revision is an ivy-range, not a complete revision. */ + def isVersionRange(revision: String): Boolean = { + (revision endsWith "+") || + (revision contains "[") || + (revision contains "]") || + (revision contains "(") || + (revision contains ")") + } + + // Assuming Ivy is used to resolve conflict, this removes the version range + // when it is open-ended to avoid dependency resolution hitting the Internet to get the latest. + // See https://github.com/sbt/sbt/issues/2954 + def stripMavenVersionRange(version: String): Option[String] = + if (isVersionRange(version)) { + val noSpace = version.replaceAllLiterally(" ", "") + noSpace match { + case MavenVersionSetPattern(open1, x1, comma, x2, close1, rest) => + // http://maven.apache.org/components/enforcer/enforcer-rules/versionRanges.html + (open1, Option(x1), Option(comma), Option(x2), close1) match { + case (_, None, _, Some(x2), "]") => Some(x2) + // a good upper bound is unknown + case (_, None, _, Some(x2), ")") => None + case (_, Some(x1), _, None, _) => Some(x1) + case _ => None + } + case _ => None + } + } else None + + /** Converts Ivy revision ranges to that of Maven POM */ + def fromIvyToMavenVersion(revision: String): String = { + def plusRange(s: String, shift: Int = 0) = { + def pow(i: Int): Int = if (i > 0) 10 * pow(i - 1) else 1 + val (prefixVersion, lastVersion) = (s + "0" * shift).reverse.split("\\.", 2) match { + case Array(revLast, revRest) => + (revRest.reverse + ".", revLast.reverse) + case Array(revLast) => ("", revLast.reverse) + } + val lastVersionInt = lastVersion.toInt + s"[${prefixVersion}${lastVersion},${prefixVersion}${lastVersionInt + pow(shift)})" + } + val DotPlusPattern = """(.+)\.\+""".r + val DotNumPlusPattern = """(.+)\.(\d+)\+""".r + val NumPlusPattern = """(\d+)\+""".r + val maxDigit = 5 + try { + revision match { + case "+" => "[0,)" + case DotPlusPattern(base) => plusRange(base) + // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so + // we assume version ranges never go beyond 5 siginificant digits. + case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") + case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") + case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") + case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => + val start = rev(0) + val stop = rev(rev.length - 1) + val mid = rev.substring(1, rev.length - 1) + (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + case _ => revision + } + } catch { + case e: NumberFormatException => + // TODO - if the version doesn't meet our expectations, maybe we just issue a hard + // error instead of softly ignoring the attempt to rewrite. + //sys.error(s"Could not fix version [$revision] into maven style version") + revision + } + } + + def hasMavenVersionRange(version: String): Boolean = + if (version.length <= 1) false + else startSym(version(0)) && stopSym(version(version.length - 1)) + + private[this] val startSym = Set(']', '[', '(') + private[this] val stopSym = Set(']', '[', ')') + private[this] val MavenVersionSetPattern = """([\]\[\(])([\w\.\-]+)?(,)?([\w\.\-]+)?([\]\[\)])(,.+)?""".r +} diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala new file mode 100644 index 000000000..e8bd99028 --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala @@ -0,0 +1,19 @@ +package sbt +package internal +package librarymanagement + +class VersionRangeSpec extends UnitSpec { + "Version range" should "strip 1.0 to None" in stripTo("1.0", None) + it should "strip (,1.0] to 1.0" in stripTo("(,1.0]", Some("1.0")) + it should "strip (,1.0) to None" in stripTo("(,1.0)", None) + it should "strip [1.0] to 1.0" in stripTo("[1.0]", Some("1.0")) + it should "strip [1.0,) to 1.0" in stripTo("[1.0,)", Some("1.0")) + it should "strip (1.0,) to 1.0" in stripTo("(1.0,)", Some("1.0")) + it should "strip (1.0,2.0) to None" in stripTo("(1.0,2.0)", None) + it should "strip [1.0,2.0] to None" in stripTo("[1.0,2.0]", None) + it should "strip (,1.0],[1.2,) to 1.0" in stripTo("(,1.0],[1.2,)", Some("1.0")) + it should "strip (,1.1),(1.1,) to None" in stripTo("(,1.1),(1.1,)", None) + + def stripTo(s: String, expected: Option[String]) = + assert(VersionRange.stripMavenVersionRange(s) == expected) +} From 36121bed74688032e36e20e5cafb31f49f790d06 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 15 Mar 2017 00:50:58 -0400 Subject: [PATCH 0581/1030] Fix version parsing Fixes sbt/sbt#3011 --- .../cross/CrossVersionUtil.scala | 17 ++++++++++------- .../src/test/scala/CrossVersionTest.scala | 3 +++ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index f9f6e069e..7524f0851 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -15,6 +15,9 @@ object CrossVersionUtil { def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) def isBinary(s: String): Boolean = (s == binaryString) + private lazy val intPattern = """\d{1,10}""" + private lazy val basicVersion = """(""" + intPattern + """)\.(""" + intPattern + """)\.(""" + intPattern + """)""" + private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined /** * Returns sbt binary interface x.y API compatible with the given version string v. @@ -23,9 +26,9 @@ object CrossVersionUtil { */ private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val CandidateV = """(\d+)\.(\d+)\.(\d+)(-RC\d+)""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)([-\w+]*)""".r + val ReleaseV = (basicVersion + """(-\d+)?""").r + val CandidateV = (basicVersion + """(-RC\d+)""").r + val NonReleaseV = (basicVersion + """([-\w+]*)""").r v match { case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) @@ -40,9 +43,9 @@ object CrossVersionUtil { */ private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = { - val ReleaseV = """(\d+)\.(\d+)\.(\d+)(-\d+)?""".r - val BinCompatV = """(\d+)\.(\d+)\.(\d+)-bin(-.*)?""".r - val NonReleaseV = """(\d+)\.(\d+)\.(\d+)(-\w+)""".r + val ReleaseV = (basicVersion + """(-\d+)?""").r + val BinCompatV = (basicVersion + """-bin(-.*)?""").r + val NonReleaseV = (basicVersion + """(-\w+)""").r v match { case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) @@ -50,7 +53,7 @@ object CrossVersionUtil { case _ => None } } - private[sbt] val PartialVersion = """(\d+)\.(\d+)(?:\..+)?""".r + private[sbt] val PartialVersion = ("""(""" + intPattern + """)\.(""" + intPattern + """)(?:\..+)?""").r private[sbt] def partialVersion(s: String): Option[(Int, Int)] = s match { case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index e5b1b1f9c..fb4dfacf5 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -114,6 +114,9 @@ class CrossVersionTest extends UnitSpec { it should "return binary Scala version for 2.10.1 as 2.10" in { CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" } + it should "return binary Scala version for 2.20170314093845.0-87654321 as 2.20170314093845.0-87654321" in { + CrossVersion.binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" + } it should "return patch Scala version for 2.11.8 as 2.11.8" in { CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8") } From 3244e6704072895270940f0556508ee9280b6cdf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 5 Apr 2017 00:13:49 -0400 Subject: [PATCH 0582/1030] Bump io and util --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 26271740c..3da73e3cc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,8 +5,8 @@ object Dependencies { val scala211 = "2.11.8" val scala212 = "2.12.1" - private val ioVersion = "1.0.0-M9" - private val utilVersion = "1.0.0-M20" + private val ioVersion = "1.0.0-M10" + private val utilVersion = "1.0.0-M22" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 80715dfb57336c51e8ad0eaa9b50c0a7543ee72d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 5 Apr 2017 15:51:36 +0100 Subject: [PATCH 0583/1030] Make ScmInfo devConnection default to None --- .../src/main/contraband/librarymanagement.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 50035dd53..e9f16c123 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -578,9 +578,9 @@ "type": "record", "doc": "Basic SCM information for a project module", "fields": [ - { "name": "browseUrl", "type": "java.net.URL" }, - { "name": "connection", "type": "String" }, - { "name": "devConnection", "type": "String?" } + { "name": "browseUrl", "type": "java.net.URL" }, + { "name": "connection", "type": "String" }, + { "name": "devConnection", "type": "String?", "default": "None", "since": "0.0.1" } ] }, { From 7f25614d71848310c1402f0bb0ef519a26012973 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 13 Apr 2017 09:27:31 +0100 Subject: [PATCH 0584/1030] Expose more in RichUpdateReport Fixes #83 --- .../librarymanagement/RichUpdateReport.scala | 45 ++++++++++++++----- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 12fb4be8d..6a4adc7b2 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -3,7 +3,10 @@ package librarymanagement import java.io.File -/** Provides extra methods for filtering the contents of an `UpdateReport` and for obtaining references to a selected subset of the underlying files. */ +/** + * Provides extra methods for filtering the contents of an `UpdateReport` + * and for obtaining references to a selected subset of the underlying files. + */ final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { @@ -15,10 +18,10 @@ final class RichUpdateReport(report: UpdateReport) { import DependencyFilter._ /** Obtains all successfully retrieved files in all configurations and modules. */ - private[sbt] def allFiles: Seq[File] = matching(DependencyFilter.allPass) + def allFiles: Seq[File] = matching(DependencyFilter.allPass) /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - private[sbt] def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + def matching(f: DependencyFilter): Seq[File] = select0(f).distinct /** Obtains all successfully retrieved files matching all provided filters. */ def select(configuration: ConfigurationFilter, module: ModuleFilter, artifact: ArtifactFilter): Seq[File] = @@ -29,17 +32,27 @@ final class RichUpdateReport(report: UpdateReport) { def select(artifact: ArtifactFilter): Seq[File] = select(configurationFilter(), moduleFilter(), artifact) private[this] def select0(f: DependencyFilter): Seq[File] = - for (cReport <- report.configurations; mReport <- cReport.modules; (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact)) yield { - if (file == null) sys.error("Null file: conf=" + cReport.configuration + ", module=" + mReport.module + ", art: " + artifact) + for { + cReport <- report.configurations + mReport <- cReport.modules + (artifact, file) <- mReport.artifacts + if f(cReport.configuration, mReport.module, artifact) + } yield { + if (file == null) + sys.error(s"Null file: conf=${cReport.configuration}, module=${mReport.module}, art: $artifact") file } /** Constructs a new report that only contains files matching the specified filter.*/ - private[sbt] def filter(f: DependencyFilter): UpdateReport = + def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => modReport - .withArtifacts(modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) }) - .withMissingArtifacts(modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) }) + .withArtifacts( + modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) } + ) + .withMissingArtifacts( + modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } + ) } private[sbt] def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport = @@ -50,11 +63,19 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts(modReport.missingArtifacts) } - private[sbt] def toSeq: Seq[(String, ModuleID, Artifact, File)] = - for (confReport <- report.configurations; modReport <- confReport.modules; (artifact, file) <- modReport.artifacts) yield (confReport.configuration, modReport.module, artifact, file) + def toSeq: Seq[(String, ModuleID, Artifact, File)] = + for { + confReport <- report.configurations + modReport <- confReport.modules + (artifact, file) <- modReport.artifacts + } yield (confReport.configuration, modReport.module, artifact, file) - private[sbt] def allMissing: Seq[(String, ModuleID, Artifact)] = - for (confReport <- report.configurations; modReport <- confReport.modules; artifact <- modReport.missingArtifacts) yield (confReport.configuration, modReport.module, artifact) + def allMissing: Seq[(String, ModuleID, Artifact)] = + for { + confReport <- report.configurations + modReport <- confReport.modules + artifact <- modReport.missingArtifacts + } yield (confReport.configuration, modReport.module, artifact) private[sbt] def addMissing(f: ModuleID => Seq[Artifact]): UpdateReport = moduleReportMap { (configuration, modReport) => From 40e34b3e8eb27c9920b4505561f15273614ca094 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 13 Apr 2017 10:08:53 +0100 Subject: [PATCH 0585/1030] Make RichUpdateReport return Vectors & cuddle sys.error --- .../librarymanagement/RichUpdateReport.scala | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 6a4adc7b2..1d6e6c473 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -18,28 +18,29 @@ final class RichUpdateReport(report: UpdateReport) { import DependencyFilter._ /** Obtains all successfully retrieved files in all configurations and modules. */ - def allFiles: Seq[File] = matching(DependencyFilter.allPass) + def allFiles: Vector[File] = matching(DependencyFilter.allPass) /** Obtains all successfully retrieved files in configurations, modules, and artifacts matching the specified filter. */ - def matching(f: DependencyFilter): Seq[File] = select0(f).distinct + def matching(f: DependencyFilter): Vector[File] = select0(f).distinct /** Obtains all successfully retrieved files matching all provided filters. */ - def select(configuration: ConfigurationFilter, module: ModuleFilter, artifact: ArtifactFilter): Seq[File] = + def select(configuration: ConfigurationFilter, module: ModuleFilter, artifact: ArtifactFilter): Vector[File] = matching(DependencyFilter.make(configuration, module, artifact)) - def select(configuration: ConfigurationFilter): Seq[File] = select(configuration, moduleFilter(), artifactFilter()) - def select(module: ModuleFilter): Seq[File] = select(configurationFilter(), module, artifactFilter()) - def select(artifact: ArtifactFilter): Seq[File] = select(configurationFilter(), moduleFilter(), artifact) + def select(configuration: ConfigurationFilter): Vector[File] = select(configuration, moduleFilter(), artifactFilter()) + def select(module: ModuleFilter): Vector[File] = select(configurationFilter(), module, artifactFilter()) + def select(artifact: ArtifactFilter): Vector[File] = select(configurationFilter(), moduleFilter(), artifact) - private[this] def select0(f: DependencyFilter): Seq[File] = + private[this] def select0(f: DependencyFilter): Vector[File] = for { cReport <- report.configurations mReport <- cReport.modules (artifact, file) <- mReport.artifacts if f(cReport.configuration, mReport.module, artifact) } yield { - if (file == null) + if (file == null) { sys.error(s"Null file: conf=${cReport.configuration}, module=${mReport.module}, art: $artifact") + } file } @@ -63,14 +64,15 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts(modReport.missingArtifacts) } - def toSeq: Seq[(String, ModuleID, Artifact, File)] = + def toSeq: Seq[(String, ModuleID, Artifact, File)] = toVector + def toVector: Vector[(String, ModuleID, Artifact, File)] = for { confReport <- report.configurations modReport <- confReport.modules (artifact, file) <- modReport.artifacts } yield (confReport.configuration, modReport.module, artifact, file) - def allMissing: Seq[(String, ModuleID, Artifact)] = + def allMissing: Vector[(String, ModuleID, Artifact)] = for { confReport <- report.configurations modReport <- confReport.modules From 4b0b3a05f9900efbaf6fc15cae5ff80b53b49d1e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 17 Apr 2017 13:06:32 -0400 Subject: [PATCH 0586/1030] Bump to util 1.0.0-M23 I'm now going to use `CacheStore.apply` in `JsonUtil` (used by cached resolution). This gets rid of `fileToStore` parameter from a bunch of classes and simplifies the setup around librarymanagement. --- .../sbt/internal/librarymanagement/Ivy.scala | 10 ++++------ .../internal/librarymanagement/IvyCache.scala | 17 +++-------------- .../internal/librarymanagement/JsonUtil.scala | 10 +++------- .../ivyint/CachedResolutionResolveEngine.scala | 15 +++++---------- .../DefaultLibraryManagement.scala | 2 +- .../src/test/scala/BaseIvySpecification.scala | 11 +---------- .../src/test/scala/CustomPomParserTest.scala | 2 +- project/Dependencies.scala | 4 ++-- project/build.properties | 2 +- 9 files changed, 21 insertions(+), 52 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 76ba4ce33..44c53d826 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -30,9 +30,8 @@ import sbt.util.Logger import sbt.librarymanagement._ import Resolver.PluginPattern import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } -import sbt.internal.util.CacheStore -final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => CacheStore) { self => +final class IvySbt(val configuration: IvyConfiguration) { self => import configuration.baseDirectory /* @@ -93,8 +92,7 @@ final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => Cac setEventManager(new EventManager()) if (configuration.updateOptions.cachedResolution) { setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine { - override private[sbt] val fileToStore: File => CacheStore = self.fileToStore - val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache(fileToStore) + val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache val projectResolver = prOpt def makeInstance = mkIvy }) @@ -141,7 +139,7 @@ final class IvySbt(val configuration: IvyConfiguration, fileToStore: File => Cac withIvy(log) { i => val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } if (configuration.updateOptions.cachedResolution) { - IvySbt.cachedResolutionResolveCache(fileToStore).clean(md, prOpt) + IvySbt.cachedResolutionResolveCache.clean(md, prOpt) } } @@ -251,7 +249,7 @@ private[sbt] object IvySbt { val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" val DefaultChecksums = Vector("sha1", "md5") - private[sbt] def cachedResolutionResolveCache(fileToStore: File => CacheStore): CachedResolutionResolveCache = new CachedResolutionResolveCache(fileToStore) + private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 80eff7470..ae7d01275 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -12,16 +12,12 @@ import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, R import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil import sbt.io.Path -import sbt.util.Logger import sbt.librarymanagement._ - -import sbt.internal.util.{ CacheStore, FileBasedStore } +import sbt.util.Logger import scala.json.ast.unsafe._ import scala.collection.mutable import jawn.{ SupportParser, MutableFacade } -import sjsonnew.IsoString -import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { @@ -35,9 +31,7 @@ private object NotInCache { } } /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ -class IvyCache(val ivyHome: Option[File], fileToStore: File => CacheStore) { - def this(ivyHome: Option[File]) = this(ivyHome, DefaultFileToStore) - +class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { @@ -92,7 +86,7 @@ class IvyCache(val ivyHome: Option[File], fileToStore: File => CacheStore) { val local = Resolver.defaultLocal val paths = IvyPaths(new File("."), ivyHome) val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) - (new IvySbt(conf, fileToStore), local) + (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = @@ -131,8 +125,3 @@ object FixedParser extends SupportParser[JValue] { } } } - -object DefaultFileToStore extends (File => CacheStore) { - private implicit lazy val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply _, FixedParser.parseUnsafe _) - override def apply(f: File): CacheStore = new FileBasedStore(f, Converter) -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index df6f6490d..55d7dbd6a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -3,22 +3,18 @@ package sbt.internal.librarymanagement import java.io.File import org.apache.ivy.core import core.module.descriptor.ModuleDescriptor -import sbt.util.Logger -import sbt.internal.util.CacheStore +import sbt.util.{ CacheStore, Logger } import sbt.librarymanagement._ import sbt.librarymanagement.LibraryManagementCodec._ -import JsonUtil._ private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" def fakeCallerOrganization = "org.scala-sbt.temp-callers" -} -private[sbt] class JsonUtil(fileToStore: File => CacheStore) { def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = { try { - val lite = fileToStore(path).read[UpdateReportLite] + val lite = CacheStore(path).read[UpdateReportLite] fromLite(lite, cachedDescriptor) } catch { case e: Throwable => @@ -29,7 +25,7 @@ private[sbt] class JsonUtil(fileToStore: File => CacheStore) { def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { sbt.io.IO.createDirectory(graphPath.getParentFile) - fileToStore(graphPath).write(toLite(ur)) + CacheStore(graphPath).write(toLite(ur)) } def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7159e33e9..8b9cb5074 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -21,9 +21,8 @@ import org.apache.ivy.plugins.matcher.{ MapMatcher, PatternMatcher } import annotation.tailrec import scala.concurrent.duration._ import sbt.io.{ DirectoryFilter, Hash, IO } -import sbt.util.Logger import sbt.librarymanagement._, syntax._ -import sbt.internal.util.CacheStore +import sbt.util.Logger private[sbt] object CachedResolutionResolveCache { def createID(organization: String, name: String, revision: String) = @@ -38,9 +37,8 @@ private[sbt] object CachedResolutionResolveCache { lazy val yyyymmdd: SimpleDateFormat = new SimpleDateFormat("yyyy-MM-dd") } -private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) { +private[sbt] class CachedResolutionResolveCache { import CachedResolutionResolveCache._ - val jsonUtil = new JsonUtil(fileToStore) val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() // Used for subproject val projectReportCache: concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap() @@ -165,7 +163,7 @@ private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) else None) match { case Some(path) => log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = jsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) + val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) if (ur.allFiles forall { _.exists }) { updateReportCache(md.getModuleRevisionId) = Right(ur) Some(Right(ur)) @@ -199,7 +197,7 @@ private[sbt] class CachedResolutionResolveCache(fileToStore: File => CacheStore) if (changing) { cleanDynamicGraph() } - jsonUtil.writeUpdateReport(ur, gp) + JsonUtil.writeUpdateReport(ur, gp) // limit the update cache size if (updateReportCache.size > maxUpdateReportCacheSize) { updateReportCache.remove(updateReportCache.head._1) @@ -258,9 +256,6 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { private[sbt] def makeInstance: Ivy private[sbt] val ignoreTransitiveForce: Boolean = true - private[sbt] val fileToStore: File => CacheStore - private val jsonUtil = new JsonUtil(fileToStore) - def withIvy[A](log: Logger)(f: Ivy => A): A = withIvy(new IvyLoggerInterface(log))(f) def withIvy[A](log: MessageLogger)(f: Ivy => A): A = @@ -432,7 +427,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { if (mr.evicted || mr.problem.nonEmpty) None else // https://github.com/sbt/sbt/issues/1763 - Some(mr.withCallers(jsonUtil.filterOutArtificialCallers(mr.callers))) + Some(mr.withCallers(JsonUtil.filterOutArtificialCallers(mr.callers))) } match { case Vector() => None case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms)) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 01a87378b..4dddcab78 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -7,7 +7,7 @@ import sbt.util.Logger import sbt.io.Hash class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) extends LibraryManagement { - private[sbt] val ivySbt: IvySbt = new IvySbt(ivyConfiguration, DefaultFileToStore) + private[sbt] val ivySbt: IvySbt = new IvySbt(ivyConfiguration) private val sbtOrgTemp = JsonUtil.sbtOrgTemp private val modulePrefixTemp = "temp-module-" diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 7906abb4f..1400db7ac 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -8,13 +8,6 @@ import sbt.internal.util.ConsoleLogger import sbt.librarymanagement._ import Configurations._ -import sbt.internal.util.FileBasedStore - -import sjsonnew.IsoString -import sjsonnew.support.scalajson.unsafe.{ CompactPrinter, Converter } - -import scala.json.ast.unsafe.JValue - trait BaseIvySpecification extends UnitSpec { def currentBase: File = new File(".") def currentTarget: File = currentBase / "target" / "ivyhome" @@ -22,8 +15,6 @@ trait BaseIvySpecification extends UnitSpec { def currentDependency: File = currentBase / "target" / "dependency" def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) - implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) - val fileToStore = (f: File) => new FileBasedStore(f, Converter) lazy val log = ConsoleLogger() def configurations = Vector(Compile, Test, Runtime) @@ -47,7 +38,7 @@ trait BaseIvySpecification extends UnitSpec { moduleInfo = ModuleInfo("foo"), dependencies = deps ).withConfigurations(configurations) - val ivySbt = new IvySbt(mkIvyConfiguration(uo), fileToStore) + val ivySbt = new IvySbt(mkIvyConfiguration(uo)) new ivySbt.Module(moduleSetting) } diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index ba4b48161..e40771325 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -16,7 +16,7 @@ class CustomPomParserTest extends UnitSpec { val local = MavenRepository("Test Repo", repoUrl.toExternalForm) val paths = IvyPaths(new File("."), Some(cacheDir)) val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, None, Vector("sha1", "md5"), None, UpdateOptions(), log) - val ivySbt = new IvySbt(conf, DefaultFileToStore) + val ivySbt = new IvySbt(conf) val resolveOpts = new ResolveOptions().setConfs(Array("default")) val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 3da73e3cc..8777d53e7 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,8 +5,8 @@ object Dependencies { val scala211 = "2.11.8" val scala212 = "2.12.1" - private val ioVersion = "1.0.0-M10" - private val utilVersion = "1.0.0-M22" + private val ioVersion = "1.0.0-M11" + private val utilVersion = "1.0.0-M23" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/build.properties b/project/build.properties index 27e88aa11..64317fdae 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.13 +sbt.version=0.13.15 From 712c83f85900ea1802b7cd1586605fc7d358eeba Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 26 Apr 2017 22:41:50 +0200 Subject: [PATCH 0587/1030] Configure scalafmt and disable scalariform --- .scalafmt.conf | 18 ++++++++ .travis.yml | 2 +- build.sbt | 11 ++++- project/AutomateScalafmtPlugin.scala | 66 ++++++++++++++++++++++++++++ project/plugins.sbt | 1 + 5 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 .scalafmt.conf create mode 100644 project/AutomateScalafmtPlugin.scala diff --git a/.scalafmt.conf b/.scalafmt.conf new file mode 100644 index 000000000..0d5990db2 --- /dev/null +++ b/.scalafmt.conf @@ -0,0 +1,18 @@ +maxColumn = 100 +project.git = true +project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] + +# http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style. +# scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala +docstrings = JavaDoc + +# This also seems more idiomatic to include whitespace in import x.{ yyy } +spaces.inImportCurlyBraces = true + +# This works around sequence wildcard (`_*`) turning into `_ *` +spaces.beforeSeqWildcard = true + +# Vertical alignment only => for pattern matching +align.tokens.add = [ + { code = "=>", owner = "Case" } +] diff --git a/.travis.yml b/.travis.yml index ff0899634..535d8f33c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ scala: - 2.12.1 script: - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M "++$TRAVIS_SCALA_VERSION test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmtCheck" jdk: - oraclejdk8 diff --git a/build.sbt b/build.sbt index b5e89d6c4..1571c04bb 100644 --- a/build.sbt +++ b/build.sbt @@ -18,11 +18,19 @@ def commonSettings: Seq[Setting[_]] = Seq( scalacOptions += "-Ywarn-unused", mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, - publishArtifact in Test := false + publishArtifact in Test := false, + commands += Command.command("scalafmtCheck") { state => + sys.process.Process("git diff --name-only --exit-code").! match { + case 0 => // ok + case x => sys.error("git diff detected! Did you compile before committing?") + } + state + } ) lazy val lmRoot = (project in file(".")). aggregate(lm). + disablePlugins(com.typesafe.sbt.SbtScalariform). settings( inThisBuild(Seq( homepage := Some(url("https://github.com/sbt/librarymanagement")), @@ -41,6 +49,7 @@ lazy val lmRoot = (project in file(".")). ) lazy val lm = (project in file("librarymanagement")). + disablePlugins(com.typesafe.sbt.SbtScalariform). settings( commonSettings, name := "librarymanagement", diff --git a/project/AutomateScalafmtPlugin.scala b/project/AutomateScalafmtPlugin.scala new file mode 100644 index 000000000..f066d0567 --- /dev/null +++ b/project/AutomateScalafmtPlugin.scala @@ -0,0 +1,66 @@ +import org.scalafmt.bootstrap.ScalafmtBootstrap +import org.scalafmt.sbt.ScalafmtPlugin +import sbt._ +import sbt.Keys._ +import sbt.inc.Analysis + +// Taken from https://github.com/akka/alpakka/blob/master/project/AutomateScalafmtPlugin.scala +object AutomateScalafmtPlugin extends AutoPlugin { + object autoImport { + def automateScalafmtFor(configurations: Configuration*): Seq[Setting[_]] = + configurations.flatMap { c => + inConfig(c)( + Seq( + compileInputs.in(compile) := { + scalafmtInc.value + compileInputs.in(compile).value + }, + sourceDirectories.in(scalafmtInc) := Seq(scalaSource.value), + scalafmtInc := { + val cache = streams.value.cacheDirectory / "scalafmt" + val include = includeFilter.in(scalafmtInc).value + val exclude = excludeFilter.in(scalafmtInc).value + val sources = + sourceDirectories + .in(scalafmtInc) + .value + .descendantsExcept(include, exclude) + .get + .toSet + def format(handler: Set[File] => Unit, msg: String) = { + def update(handler: Set[File] => Unit, msg: String)(in: ChangeReport[File], + out: ChangeReport[File]) = { + val label = Reference.display(thisProjectRef.value) + val files = in.modified -- in.removed + Analysis + .counted("Scala source", "", "s", files.size) + .foreach(count => streams.value.log.info(s"$msg $count in $label ...")) + handler(files) + files + } + FileFunction.cached(cache)(FilesInfo.hash, FilesInfo.exists)(update(handler, msg))( + sources + ) + } + def formattingHandler(files: Set[File]) = + if (files.nonEmpty) { + val filesArg = files.map(_.getAbsolutePath).mkString(",") + ScalafmtBootstrap.main(List("--quiet", "-i", "-f", filesArg)) + } + format(formattingHandler, "Formatting") + format(_ => (), "Reformatted") // Recalculate the cache + } + ) + ) + } + } + + private val scalafmtInc = taskKey[Unit]("Incrementally format modified sources") + + override def requires = ScalafmtPlugin + + override def trigger = allRequirements + + override def projectSettings = + (includeFilter.in(scalafmtInc) := "*.scala") +: autoImport.automateScalafmtFor(Compile, Test) +} diff --git a/project/plugins.sbt b/project/plugins.sbt index 767bccb53..6d069c96c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,5 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M4") addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") +addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "0.6.8") scalacOptions += "-language:postfixOps" From d42ea869d064a28c692df7d93c506b698dd6937c Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 26 Apr 2017 22:55:38 +0200 Subject: [PATCH 0588/1030] Apply formatting --- build.sbt | 62 +- .../ReplaceMavenConfigurationMappings.scala | 125 +- .../CompatibilityWarning.scala | 21 +- .../librarymanagement/ComponentManager.scala | 100 +- .../librarymanagement/ConvertResolver.scala | 233 +-- .../librarymanagement/CustomPomParser.scala | 308 ++-- .../librarymanagement/CustomXmlParser.scala | 30 +- .../librarymanagement/FakeResolver.scala | 45 +- .../sbt/internal/librarymanagement/Ivy.scala | 969 +++++++----- .../librarymanagement/IvyActions.scala | 666 +++++--- .../internal/librarymanagement/IvyCache.scala | 105 +- .../librarymanagement/IvyConfigurations.scala | 8 +- .../librarymanagement/IvyLogger.scala | 1 + .../librarymanagement/IvyRetrieve.scala | 162 +- .../internal/librarymanagement/JsonUtil.scala | 100 +- .../internal/librarymanagement/MakePom.scala | 532 ++++--- .../librarymanagement/ProjectResolver.scala | 79 +- .../RepositoriesParser.scala | 44 +- .../librarymanagement/ResolutionCache.scala | 25 +- .../SbtExclusionRuleExtra.scala | 3 +- .../librarymanagement/StringUtilities.scala | 8 +- .../librarymanagement/VersionRange.scala | 24 +- .../cross/CrossVersionUtil.scala | 78 +- .../formats/UpdateOptionsFormat.scala | 22 +- .../impl/DependencyBuilders.scala | 71 +- .../CachedResolutionResolveEngine.scala | 1346 ++++++++++------- .../ivyint/CustomMavenResolver.scala | 3 +- .../ivyint/ErrorMessageAuthenticator.scala | 32 +- .../ivyint/IvyCredentialsLookup.scala | 4 +- .../ivyint/MergeDescriptors.scala | 180 ++- .../ivyint/SbtChainResolver.scala | 397 +++-- .../PomExtraDependencyAttributes.scala | 25 +- .../sbt/librarymanagement/ArtifactExtra.scala | 110 +- .../CircularDependencyLevel.scala | 7 +- .../ConfigurationExtra.scala | 29 +- .../librarymanagement/ConflictWarning.scala | 33 +- .../sbt/librarymanagement/Credentials.scala | 39 +- .../librarymanagement/CrossVersionExtra.scala | 49 +- .../DefaultLibraryManagement.scala | 37 +- .../librarymanagement/DependencyFilter.scala | 73 +- .../librarymanagement/EvictionWarning.scala | 135 +- .../sbt/librarymanagement/IvyInterface.scala | 9 +- .../sbt/librarymanagement/IvyScalaExtra.scala | 199 ++- .../sbt/librarymanagement/ModuleIDExtra.scala | 86 +- .../sbt/librarymanagement/ResolverExtra.scala | 206 ++- .../librarymanagement/RichUpdateReport.scala | 57 +- .../sbt/librarymanagement/UpdateOptions.scala | 60 +- .../librarymanagement/UpdateReportExtra.scala | 110 +- .../sbt/librarymanagement/VersionNumber.scala | 44 +- .../src/test/scala/BaseIvySpecification.scala | 42 +- .../src/test/scala/CachedResolutionSpec.scala | 37 +- .../src/test/scala/ComponentManagerTest.scala | 34 +- .../src/test/scala/CrossVersionTest.scala | 18 +- .../src/test/scala/CustomPomParserTest.scala | 14 +- .../src/test/scala/DMSerializationSpec.scala | 27 +- .../src/test/scala/EvictionWarningSpec.scala | 40 +- .../scala/InconsistentDuplicateSpec.scala | 9 +- .../src/test/scala/MakePomSpec.scala | 1 - .../src/test/scala/MergeDescriptorSpec.scala | 12 +- .../src/test/scala/ResolverTest.scala | 9 +- .../src/test/scala/ScalaOverrideTest.scala | 64 +- .../src/test/scala/VersionNumberSpec.scala | 68 +- .../FakeResolverSpecification.scala | 14 +- .../librarymanagement/IvyRepoSpec.scala | 23 +- .../RepositoriesParserSpecification.scala | 60 +- .../librarymanagement/TestLogger.scala | 11 +- project/AutomateScalafmtPlugin.scala | 4 +- project/DatatypeConfig.scala | 38 +- project/Dependencies.scala | 36 +- project/Util.scala | 42 +- project/plugins.sbt | 6 +- 71 files changed, 4878 insertions(+), 2822 deletions(-) diff --git a/build.sbt b/build.sbt index 1571c04bb..aed7152ab 100644 --- a/build.sbt +++ b/build.sbt @@ -28,17 +28,19 @@ def commonSettings: Seq[Setting[_]] = Seq( } ) -lazy val lmRoot = (project in file(".")). - aggregate(lm). - disablePlugins(com.typesafe.sbt.SbtScalariform). - settings( - inThisBuild(Seq( - homepage := Some(url("https://github.com/sbt/librarymanagement")), - description := "Library management module for sbt", - scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git")), - bintrayPackage := "librarymanagement", - git.baseVersion := baseVersion - )), +lazy val lmRoot = (project in file(".")) + .aggregate(lm) + .disablePlugins(com.typesafe.sbt.SbtScalariform) + .settings( + inThisBuild( + Seq( + homepage := Some(url("https://github.com/sbt/librarymanagement")), + description := "Library management module for sbt", + scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), + "git@github.com:sbt/librarymanagement.git")), + bintrayPackage := "librarymanagement", + git.baseVersion := baseVersion + )), commonSettings, name := "LM Root", publish := {}, @@ -48,15 +50,24 @@ lazy val lmRoot = (project in file(".")). customCommands ) -lazy val lm = (project in file("librarymanagement")). - disablePlugins(com.typesafe.sbt.SbtScalariform). - settings( +lazy val lm = (project in file("librarymanagement")) + .disablePlugins(com.typesafe.sbt.SbtScalariform) + .settings( commonSettings, name := "librarymanagement", - libraryDependencies ++= Seq( - ivy, jsch, scalaReflect.value, launcherInterface, sjsonnewScalaJson % Optional), + libraryDependencies ++= Seq(ivy, + jsch, + scalaReflect.value, + launcherInterface, + sjsonnewScalaJson % Optional), libraryDependencies ++= scalaXml.value, - resourceGenerators in Compile += Def.task(Util.generateVersionFile(version.value, resourceManaged.value, streams.value, (compile in Compile).value)).taskValue, + resourceGenerators in Compile += Def + .task( + Util.generateVersionFile(version.value, + resourceManaged.value, + streams.value, + (compile in Compile).value)) + .taskValue, mimaBinaryIssueFilters ++= Seq(), contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc @@ -66,16 +77,21 @@ lazy val lm = (project in file("librarymanagement")). val base = baseDirectory.value (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) } - ). - configure(addSbtIO, addSbtUtilLogging, addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache). - enablePlugins(ContrabandPlugin, JsonCodecPlugin) + ) + .configure(addSbtIO, + addSbtUtilLogging, + addSbtUtilTesting, + addSbtUtilCollection, + addSbtUtilCompletion, + addSbtUtilCache) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => // "clean" :: "so compile" :: - "so publishSigned" :: - "reload" :: - state + "so publishSigned" :: + "reload" :: + state } ) diff --git a/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index e59bd174e..410bdcfb7 100644 --- a/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -37,68 +37,83 @@ object ReplaceMavenConfigurationMappings { // NOTE - This code is copied from org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder // except with altered default configurations... - REPLACEMENT_MAPPINGS.put("compile", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { - if (isOptional) { - dd.addDependencyConfiguration("optional", "compile(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("optional", "master(compile)") - } else { - dd.addDependencyConfiguration("compile", "compile(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("compile", "master(compile)") - dd.addDependencyConfiguration("runtime", "runtime(*)") + REPLACEMENT_MAPPINGS.put( + "compile", + new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("compile", "compile(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("compile", "master(compile)") + dd.addDependencyConfiguration("runtime", "runtime(*)") + } } } - }) - REPLACEMENT_MAPPINGS.put("provided", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { - if (isOptional) { - dd.addDependencyConfiguration("optional", "compile(*)") - dd.addDependencyConfiguration("optional", "provided(*)") - dd.addDependencyConfiguration("optional", "runtime(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("optional", "master(compile)") - } else { - dd.addDependencyConfiguration("provided", "compile(*)") - dd.addDependencyConfiguration("provided", "provided(*)") - dd.addDependencyConfiguration("provided", "runtime(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("provided", "master(compile)") + ) + REPLACEMENT_MAPPINGS.put( + "provided", + new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + dd.addDependencyConfiguration("optional", "provided(*)") + dd.addDependencyConfiguration("optional", "runtime(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("provided", "compile(*)") + dd.addDependencyConfiguration("provided", "provided(*)") + dd.addDependencyConfiguration("provided", "runtime(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("provided", "master(compile)") + } } } - }) + ) - REPLACEMENT_MAPPINGS.put("runtime", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { - if (isOptional) { - dd.addDependencyConfiguration("optional", "compile(*)") - dd.addDependencyConfiguration("optional", "provided(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("optional", "master(compile)") - } else { - dd.addDependencyConfiguration("runtime", "compile(*)") - dd.addDependencyConfiguration("runtime", "runtime(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("runtime", "master(compile)") + REPLACEMENT_MAPPINGS.put( + "runtime", + new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { + if (isOptional) { + dd.addDependencyConfiguration("optional", "compile(*)") + dd.addDependencyConfiguration("optional", "provided(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("optional", "master(compile)") + } else { + dd.addDependencyConfiguration("runtime", "compile(*)") + dd.addDependencyConfiguration("runtime", "runtime(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("runtime", "master(compile)") + } } } - }) + ) - REPLACEMENT_MAPPINGS.put("test", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { - dd.addDependencyConfiguration("test", "runtime(*)") - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("test", "master(compile)") + REPLACEMENT_MAPPINGS.put( + "test", + new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { + dd.addDependencyConfiguration("test", "runtime(*)") + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("test", "master(compile)") + } } - }) + ) - REPLACEMENT_MAPPINGS.put("system", new PomModuleDescriptorBuilder.ConfMapper { - def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { - // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. - dd.addDependencyConfiguration("system", "master(compile)") + REPLACEMENT_MAPPINGS.put( + "system", + new PomModuleDescriptorBuilder.ConfMapper { + def addMappingConfs(dd: DefaultDependencyDescriptor, isOptional: Boolean): Unit = { + // FIX - Here we take a mroe conservative approach of depending on the compile configuration if master isn't there. + dd.addDependencyConfiguration("system", "master(compile)") + } } - }) + ) REPLACEMENT_MAPPINGS } @@ -106,13 +121,17 @@ object ReplaceMavenConfigurationMappings { def init(): Unit = { // Here we mutate a static final field, because we have to AND because it's evil. try { - val map = PomModuleDescriptorBuilder.MAVEN2_CONF_MAPPING.asInstanceOf[java.util.Map[String, PomModuleDescriptorBuilder.ConfMapper]] + val map = PomModuleDescriptorBuilder.MAVEN2_CONF_MAPPING + .asInstanceOf[java.util.Map[String, PomModuleDescriptorBuilder.ConfMapper]] map.clear() map.putAll(REPLACEMENT_MAVEN_MAPPINGS) } catch { case e: Exception => // TODO - Log that Ivy may not be configured correctly and you could have maven/ivy issues. - throw new RuntimeException("FAILURE to install Ivy maven hooks. Your ivy-maven interaction may suffer resolution errors", e) + throw new RuntimeException( + "FAILURE to install Ivy maven hooks. Your ivy-maven interaction may suffer resolution errors", + e + ) } } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index 0a4f9febb..42d3e6ca3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -6,16 +6,16 @@ import sbt.util.{ Level, Logger } import Configurations._ final class CompatibilityWarningOptions private[sbt] ( - val configurations: Seq[Configuration], - val level: Level.Value + val configurations: Seq[Configuration], + val level: Level.Value ) object CompatibilityWarningOptions { def default: CompatibilityWarningOptions = apply(configurations = List(Compile, Runtime), level = Level.Warn) def apply( - configurations: List[Configuration], - level: Level.Value + configurations: List[Configuration], + level: Level.Value ): CompatibilityWarningOptions = new CompatibilityWarningOptions( configurations = configurations, @@ -24,12 +24,21 @@ object CompatibilityWarningOptions { } private[sbt] object CompatibilityWarning { - def run(config: CompatibilityWarningOptions, module: IvySbt#Module, mavenStyle: Boolean, log: Logger): Unit = { + def run( + config: CompatibilityWarningOptions, + module: IvySbt#Module, + mavenStyle: Boolean, + log: Logger + ): Unit = { if (mavenStyle) { processIntransitive(config, module, log) } } - def processIntransitive(config: CompatibilityWarningOptions, module: IvySbt#Module, log: Logger): Unit = { + def processIntransitive( + config: CompatibilityWarningOptions, + module: IvySbt#Module, + log: Logger + ): Unit = { val monitoredConfigsStr: Set[String] = (config.configurations map { _.name }).toSet val directDependencies: Seq[ModuleID] = module.moduleSettings match { case x: InlineConfiguration => x.dependencies diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 480912e7a..244d86c62 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -18,54 +18,73 @@ import sbt.librarymanagement._ * This is used for compiled source jars so that the compilation need not be repeated for other projects on the same * machine. */ -class ComponentManager(globalLock: xsbti.GlobalLock, provider: xsbti.ComponentProvider, ivyHome: Option[File], val log: Logger) { +class ComponentManager( + globalLock: xsbti.GlobalLock, + provider: xsbti.ComponentProvider, + ivyHome: Option[File], + val log: Logger +) { private[this] val ivyCache = new IvyCache(ivyHome) - /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ - def files(id: String)(ifMissing: IfMissing): Iterable[File] = - { - def fromGlobal = - lockGlobalCache { - try { update(id); getOrElse(createAndCache) } - catch { case e: NotInCache => createAndCache } - } - def getOrElse(orElse: => Iterable[File]): Iterable[File] = - { - val existing = provider.component(id) - if (existing.isEmpty) orElse else existing - } - def notFound = invalid("Could not find required component '" + id + "'") - def createAndCache = - ifMissing match { - case IfMissing.Fail => notFound - case d: IfMissing.Define => - d() - if (d.cache) cache(id) - getOrElse(notFound) - } - lockLocalCache { getOrElse(fromGlobal) } + /** Get all of the files for component 'id', throwing an exception if no files exist for the component. */ + def files(id: String)(ifMissing: IfMissing): Iterable[File] = { + def fromGlobal = + lockGlobalCache { + try { update(id); getOrElse(createAndCache) } catch { + case e: NotInCache => createAndCache + } + } + def getOrElse(orElse: => Iterable[File]): Iterable[File] = { + val existing = provider.component(id) + if (existing.isEmpty) orElse else existing } + def notFound = invalid("Could not find required component '" + id + "'") + def createAndCache = + ifMissing match { + case IfMissing.Fail => notFound + case d: IfMissing.Define => + d() + if (d.cache) cache(id) + getOrElse(notFound) + } + + lockLocalCache { getOrElse(fromGlobal) } + } + /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action) + /** This is used to ensure atomic access to components in the global Ivy cache.*/ private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action) - private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) + private def lock[T](file: File)(action: => T): T = + globalLock(file, new Callable[T] { def call = action }) + /** Get the file for component 'id', throwing an exception if no files or multiple files exist for the component. */ def file(id: String)(ifMissing: IfMissing): File = files(id)(ifMissing).toList match { case x :: Nil => x - case xs => invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) + case xs => + invalid("Expected single file for component '" + id + "', found: " + xs.mkString(", ")) } private def invalid(msg: String) = throw new InvalidComponent(msg) - def define(id: String, files: Iterable[File]) = lockLocalCache { provider.defineComponent(id, files.toSeq.toArray) } - /** Retrieve the file for component 'id' from the local repository. */ - private def update(id: String): Unit = ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar))) + def define(id: String, files: Iterable[File]) = lockLocalCache { + provider.defineComponent(id, files.toSeq.toArray) + } + + /** Retrieve the file for component 'id' from the local repository. */ + private def update(id: String): Unit = + ivyCache.withCachedJar(sbtModuleID(id), Some(globalLock), log)(jar => define(id, Seq(jar))) + + private def sbtModuleID(id: String) = + ModuleID(SbtArtifacts.Organization, id, ComponentManager.stampedVersion) - private def sbtModuleID(id: String) = ModuleID(SbtArtifacts.Organization, id, ComponentManager.stampedVersion) /** Install the files for component 'id' to the local repository. This is usually used after writing files to the directory returned by 'location'. */ - def cache(id: String): Unit = ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) - def clearCache(id: String): Unit = lockGlobalCache { ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) } + def cache(id: String): Unit = + ivyCache.cacheJar(sbtModuleID(id), file(id)(IfMissing.Fail), Some(globalLock), log) + def clearCache(id: String): Unit = lockGlobalCache { + ivyCache.clearCachedJar(sbtModuleID(id), Some(globalLock), log) + } } class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(msg, cause) { def this(msg: String) = this(msg, null) @@ -73,16 +92,17 @@ class InvalidComponent(msg: String, cause: Throwable) extends RuntimeException(m sealed trait IfMissing object IfMissing { object Fail extends IfMissing - final class Define(val cache: Boolean, define: => Unit) extends IfMissing { def apply() = define } + final class Define(val cache: Boolean, define: => Unit) extends IfMissing { + def apply() = define + } } object ComponentManager { - lazy val (version, timestamp) = - { - val properties = new java.util.Properties - val propertiesStream = versionResource.openStream - try { properties.load(propertiesStream) } finally { propertiesStream.close() } - (properties.getProperty("version"), properties.getProperty("timestamp")) - } + lazy val (version, timestamp) = { + val properties = new java.util.Properties + val propertiesStream = versionResource.openStream + try { properties.load(propertiesStream) } finally { propertiesStream.close() } + (properties.getProperty("version"), properties.getProperty("timestamp")) + } lazy val stampedVersion = version + "_" + timestamp import java.net.URL diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index a1d67b99c..c90ece754 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -9,8 +9,20 @@ import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, TransferEvent } -import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, IBiblioResolver, RepositoryResolver } -import org.apache.ivy.plugins.resolver.{ AbstractPatternsBasedResolver, AbstractSshBasedResolver, FileSystemResolver, SFTPResolver, SshResolver, URLResolver } +import org.apache.ivy.plugins.resolver.{ + BasicResolver, + DependencyResolver, + IBiblioResolver, + RepositoryResolver +} +import org.apache.ivy.plugins.resolver.{ + AbstractPatternsBasedResolver, + AbstractSshBasedResolver, + FileSystemResolver, + SFTPResolver, + SshResolver, + URLResolver +} import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, FileResource } import java.io.{ IOException, File } @@ -41,25 +53,35 @@ private[sbt] object ConvertResolver { thing.setAccessible(true) Some(thing) } catch { - case (_: java.lang.NoSuchFieldException) | - (_: java.lang.SecurityException) | - (_: java.lang.NoSuchMethodException) => None + case (_: java.lang.NoSuchFieldException) | (_: java.lang.SecurityException) | + (_: java.lang.NoSuchMethodException) => + None } private val signerNameField: Option[java.lang.reflect.Field] = reflectiveLookup(_.getDeclaredField("signerName")) private val putChecksumMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod( - "putChecksum", - classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean], classOf[String] - )) + reflectiveLookup( + _.getDeclaredMethod( + "putChecksum", + classOf[IArtifact], + classOf[File], + classOf[String], + classOf[Boolean], + classOf[String] + ) + ) private val putSignatureMethod: Option[java.lang.reflect.Method] = - reflectiveLookup(_.getDeclaredMethod( - "putSignature", - classOf[IArtifact], classOf[File], classOf[String], - classOf[Boolean] - )) + reflectiveLookup( + _.getDeclaredMethod( + "putSignature", + classOf[IArtifact], + classOf[File], + classOf[String], + classOf[Boolean] + ) + ) } + /** * The default behavior of ivy's overwrite flags ignores the fact that a lot of repositories * will autogenerate checksums *for* an artifact if it doesn't already exist. Therefore @@ -76,7 +98,12 @@ private[sbt] object ConvertResolver { case Some(field) => field.get(this).asInstanceOf[String] case None => null } - override protected def put(artifact: IArtifact, src: File, dest: String, overwrite: Boolean): Unit = { + override protected def put( + artifact: IArtifact, + src: File, + dest: String, + overwrite: Boolean + ): Unit = { // verify the checksum algorithms before uploading artifacts! val checksums = getChecksumAlgorithms() val repository = getRepository() @@ -89,8 +116,9 @@ private[sbt] object ConvertResolver { // we need to overwrite what it has. for (checksum <- checksums) { putChecksumMethod match { - case Some(method) => method.invoke(this, artifact, src, dest, true: java.lang.Boolean, checksum) - case None => // TODO - issue warning? + case Some(method) => + method.invoke(this, artifact, src, dest, true: java.lang.Boolean, checksum) + case None => // TODO - issue warning? } } if (signerName != null) { @@ -108,77 +136,84 @@ private[sbt] object ConvertResolver { apply(r, settings, UpdateOptions(), log) /** Converts the given sbt resolver into an Ivy resolver. */ - def apply(r: Resolver, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = + def apply( + r: Resolver, + settings: IvySettings, + updateOptions: UpdateOptions, + log: Logger + ): DependencyResolver = (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) /** The default implementation of converter. */ lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => r match { - case repo: MavenRepository => - { - val pattern = Collections.singletonList(Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern)) - final class PluginCapableResolver extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - def setPatterns(): Unit = { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } + case repo: MavenRepository => { + val pattern = Collections.singletonList( + Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) + ) + final class PluginCapableResolver + extends IBiblioResolver + with ChecksumFriendlyURLResolver + with DescriptorRequired { + def setPatterns(): Unit = { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) } - val resolver = new PluginCapableResolver - if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver.setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver } - case repo: SshRepository => - { - val resolver = new SshResolver with DescriptorRequired - initializeSSHResolver(resolver, repo, settings) - repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - resolver + val resolver = new PluginCapableResolver + if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver + .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver + } + case repo: SshRepository => { + val resolver = new SshResolver with DescriptorRequired + initializeSSHResolver(resolver, repo, settings) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver + } + case repo: SftpRepository => { + val resolver = new SFTPResolver + initializeSSHResolver(resolver, repo, settings) + resolver + } + case repo: FileRepository => { + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) } - case repo: SftpRepository => - { - val resolver = new SFTPResolver - initializeSSHResolver(resolver, repo, settings) - resolver - } - case repo: FileRepository => - { - val resolver = new FileSystemResolver with DescriptorRequired { - // Workaround for #1156 - // Temporarily in sbt 0.13.x we deprecate overwriting - // in local files for non-changing revisions. - // This will be fully enforced in sbt 1.0. - setRepository(new WarnOnOverwriteFileRepo()) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - import repo.configuration.{ isLocal, isTransactional } - resolver.setLocal(isLocal) - isTransactional.foreach(value => resolver.setTransactional(value.toString)) - resolver - } - case repo: URLRepository => - { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - resolver - } - case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) - case repo: RawRepository => repo.resolver + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + import repo.configuration.{ isLocal, isTransactional } + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => { + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + resolver + } + case repo: ChainedResolver => + IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) + case repo: RawRepository => repo.resolver } } private sealed trait DescriptorRequired extends BasicResolver { - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = - { - val prev = descriptorString(isAllownomd) - setDescriptor(descriptorString(hasExplicitURL(dd))) - try super.getDependency(dd, data) finally setDescriptor(prev) - } + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { + val prev = descriptorString(isAllownomd) + setDescriptor(descriptorString(hasExplicitURL(dd))) + try super.getDependency(dd, data) + finally setDescriptor(prev) + } def descriptorString(optional: Boolean) = if (optional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED def hasExplicitURL(dd: DependencyDescriptor): Boolean = @@ -189,35 +224,49 @@ private[sbt] object ConvertResolver { resolver.setM2compatible(true) resolver.setRoot(root) } - private def initializeSSHResolver(resolver: AbstractSshBasedResolver, repo: SshBasedRepository, settings: IvySettings): Unit = { + private def initializeSSHResolver( + resolver: AbstractSshBasedResolver, + repo: SshBasedRepository, + settings: IvySettings + ): Unit = { resolver.setName(repo.name) resolver.setPassfile(null) initializePatterns(resolver, repo.patterns, settings) initializeConnection(resolver, repo.connection) } - private def initializeConnection(resolver: AbstractSshBasedResolver, connection: SshConnection): Unit = { + private def initializeConnection( + resolver: AbstractSshBasedResolver, + connection: SshConnection + ): Unit = { import resolver._ import connection._ hostname.foreach(setHost) port.foreach(setPort) - authentication foreach - { - case pa: PasswordAuthentication => - setUser(pa.user) - pa.password.foreach(setUserPassword) - case kfa: KeyFileAuthentication => - setKeyFile(kfa.keyfile) - kfa.password.foreach(setKeyFilePassword) - setUser(kfa.user) - } + authentication foreach { + case pa: PasswordAuthentication => + setUser(pa.user) + pa.password.foreach(setUserPassword) + case kfa: KeyFileAuthentication => + setKeyFile(kfa.keyfile) + kfa.password.foreach(setKeyFilePassword) + setUser(kfa.user) + } } - private def initializePatterns(resolver: AbstractPatternsBasedResolver, patterns: Patterns, settings: IvySettings): Unit = { + private def initializePatterns( + resolver: AbstractPatternsBasedResolver, + patterns: Patterns, + settings: IvySettings + ): Unit = { resolver.setM2compatible(patterns.isMavenCompatible) - resolver.setDescriptor(if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED) + resolver.setDescriptor( + if (patterns.descriptorOptional) BasicResolver.DESCRIPTOR_OPTIONAL + else BasicResolver.DESCRIPTOR_REQUIRED + ) resolver.setCheckconsistency(!patterns.skipConsistencyCheck) patterns.ivyPatterns.foreach(p => resolver.addIvyPattern(settings substitute p)) patterns.artifactPatterns.foreach(p => resolver.addArtifactPattern(settings substitute p)) } + /** * A custom Ivy URLRepository that returns FileResources for file URLs. * This allows using the artifacts from the Maven local repository instead of copying them to the Ivy cache. @@ -270,7 +319,9 @@ private[sbt] object ConvertResolver { catch { case e: java.io.IOException if e.getMessage.contains("destination already exists") => import org.apache.ivy.util.Message - Message.warn(s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0.") + Message.warn( + s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0." + ) super.put(source, destination, true) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index a8336662e..c906fc818 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -1,32 +1,62 @@ package sbt.internal.librarymanagement import org.apache.ivy.core.module.id.ModuleRevisionId -import org.apache.ivy.core.module.descriptor.{ DefaultArtifact, DefaultExtendsDescriptor, DefaultModuleDescriptor, ModuleDescriptor } +import org.apache.ivy.core.module.descriptor.{ + DefaultArtifact, + DefaultExtendsDescriptor, + DefaultModuleDescriptor, + ModuleDescriptor +} import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DependencyDescriptor } -import org.apache.ivy.plugins.parser.{ ModuleDescriptorParser, ModuleDescriptorParserRegistry, ParserSettings } -import org.apache.ivy.plugins.parser.m2.{ ReplaceMavenConfigurationMappings, PomModuleDescriptorBuilder, PomModuleDescriptorParser } +import org.apache.ivy.plugins.parser.{ + ModuleDescriptorParser, + ModuleDescriptorParserRegistry, + ParserSettings +} +import org.apache.ivy.plugins.parser.m2.{ + ReplaceMavenConfigurationMappings, + PomModuleDescriptorBuilder, + PomModuleDescriptorParser +} import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.namespace.NamespaceTransformer import org.apache.ivy.util.extendable.ExtendableItem import java.io.{ File, InputStream } import java.net.URL -import sbt.internal.librarymanagement.mavenint.{ PomExtraDependencyAttributes, SbtPomExtraProperties } +import sbt.internal.librarymanagement.mavenint.{ + PomExtraDependencyAttributes, + SbtPomExtraProperties +} import sbt.io.Hash // @deprecated("We now use an Aether-based pom parser.", "0.13.8") -final class CustomPomParser(delegate: ModuleDescriptorParser, transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor) extends ModuleDescriptorParser { - override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, validate: Boolean) = +final class CustomPomParser( + delegate: ModuleDescriptorParser, + transform: (ModuleDescriptorParser, ModuleDescriptor) => ModuleDescriptor +) extends ModuleDescriptorParser { + override def parseDescriptor( + ivySettings: ParserSettings, + descriptorURL: URL, + validate: Boolean + ) = transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, validate)) - override def parseDescriptor(ivySettings: ParserSettings, descriptorURL: URL, res: Resource, validate: Boolean) = + override def parseDescriptor( + ivySettings: ParserSettings, + descriptorURL: URL, + res: Resource, + validate: Boolean + ) = transform(this, delegate.parseDescriptor(ivySettings, descriptorURL, res, validate)) - override def toIvyFile(is: InputStream, res: Resource, destFile: File, md: ModuleDescriptor) = delegate.toIvyFile(is, res, destFile, md) + override def toIvyFile(is: InputStream, res: Resource, destFile: File, md: ModuleDescriptor) = + delegate.toIvyFile(is, res, destFile, md) override def accept(res: Resource) = delegate.accept(res) override def getType() = delegate.getType() - override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = delegate.getMetadataArtifact(mrid, res) + override def getMetadataArtifact(mrid: ModuleRevisionId, res: Resource) = + delegate.getMetadataArtifact(mrid, res) } // @deprecated("We now use an Aether-based pom parser.", "0.13.8") object CustomPomParser { @@ -41,7 +71,8 @@ object CustomPomParser { val SbtVersionKey = PomExtraDependencyAttributes.SbtVersionKey val ScalaVersionKey = PomExtraDependencyAttributes.ScalaVersionKey val ExtraAttributesKey = PomExtraDependencyAttributes.ExtraAttributesKey - private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) + private[this] val unqualifiedKeys = + Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) // packagings that should be jars, but that Ivy doesn't handle as jars // TODO - move this elsewhere. @@ -51,7 +82,8 @@ object CustomPomParser { private[this] val TransformedHashKey = "e:sbtTransformHash" // A hash of the parameters transformation is based on. // If a descriptor has a different hash, we need to retransform it. - private[this] def makeCoords(mrid: ModuleRevisionId): String = s"${mrid.getOrganisation}:${mrid.getName}:${mrid.getRevision}" + private[this] def makeCoords(mrid: ModuleRevisionId): String = + s"${mrid.getOrganisation}:${mrid.getName}:${mrid.getRevision}" // We now include the ModuleID in a hash, to ensure that parent-pom transformations don't corrupt child poms. private[this] def MakeTransformHash(md: ModuleDescriptor): String = { @@ -60,7 +92,8 @@ object CustomPomParser { hash((unqualifiedKeys ++ JarPackagings ++ Set(coords)).toSeq.sorted) } - private[this] def hash(ss: Seq[String]): String = Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) + private[this] def hash(ss: Seq[String]): String = + Hash.toHex(Hash(ss.flatMap(_ getBytes "UTF-8").toArray)) // Unfortunately, ModuleDescriptorParserRegistry is add-only and is a singleton instance. lazy val registerDefault: Unit = ModuleDescriptorParserRegistry.getInstance.addParser(default) @@ -69,74 +102,93 @@ object CustomPomParser { if (transformedByThisVersion(md)) md else defaultTransformImpl(parser, md) - private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = - { - val oldTransformedHashKey = "sbtTransformHash" - val extraInfo = md.getExtraInfo - val MyHash = MakeTransformHash(md) - // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both - Option(extraInfo).isDefined && - ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { - case Some(MyHash) => true - case _ => false - }) - } + private[this] def transformedByThisVersion(md: ModuleDescriptor): Boolean = { + val oldTransformedHashKey = "sbtTransformHash" + val extraInfo = md.getExtraInfo + val MyHash = MakeTransformHash(md) + // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both + Option(extraInfo).isDefined && + ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + case Some(MyHash) => true + case _ => false + }) + } - private[this] def defaultTransformImpl(parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - { - val properties = getPomProperties(md) + private[this] def defaultTransformImpl( + parser: ModuleDescriptorParser, + md: ModuleDescriptor + ): ModuleDescriptor = { + val properties = getPomProperties(md) - // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. - // These are attached to the module itself. - val filtered = shouldBeUnqualified(properties) + // Extracts extra attributes (currently, sbt and Scala versions) stored in the element of the pom. + // These are attached to the module itself. + val filtered = shouldBeUnqualified(properties) - // Extracts extra attributes for the dependencies. - // Because the tag in pom.xml cannot include additional metadata, - // sbt includes extra attributes in a 'extraDependencyAttributes' property. - // This is read/written from/to a pure string (no element structure) because Ivy only - // parses the immediate text nodes of the property. - val extraDepAttributes = getDependencyExtra(filtered) + // Extracts extra attributes for the dependencies. + // Because the tag in pom.xml cannot include additional metadata, + // sbt includes extra attributes in a 'extraDependencyAttributes' property. + // This is read/written from/to a pure string (no element structure) because Ivy only + // parses the immediate text nodes of the property. + val extraDepAttributes = getDependencyExtra(filtered) - val unqualify = toUnqualify(filtered) + val unqualify = toUnqualify(filtered) - // Here we always add extra attributes. There's a scenario where parent-pom information corrupts child-poms with "e:" namespaced xml elements - // and we have to force the every generated xml file to have the appropriate xml namespace - addExtra(unqualify, extraDepAttributes, parser, md) - } + // Here we always add extra attributes. There's a scenario where parent-pom information corrupts child-poms with "e:" namespaced xml elements + // and we have to force the every generated xml file to have the appropriate xml namespace + addExtra(unqualify, extraDepAttributes, parser, md) + } // The element of the pom is used to store additional metadata, such as for sbt plugins or for the base URL for API docs. // This is done because the pom XSD does not appear to allow extra metadata anywhere else. // The extra sbt plugin metadata in pom.xml does not need to be readable by maven, but the other information may be. // However, the pom.xml needs to be valid in all cases because other tools like repository managers may read the pom.xml. - private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String, String] = - { - import collection.JavaConverters._ - PomModuleDescriptorBuilder.extractPomProperties(md.getExtraInfo).asInstanceOf[java.util.Map[String, String]].asScala.toMap - } + private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String, String] = { + import collection.JavaConverters._ + PomModuleDescriptorBuilder + .extractPomProperties(md.getExtraInfo) + .asInstanceOf[java.util.Map[String, String]] + .asScala + .toMap + } private[sbt] def toUnqualify(propertyAttributes: Map[String, String]): Map[String, String] = (propertyAttributes - ExtraAttributesKey) map { case (k, v) => ("e:" + k, v) } - private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = m.filterKeys(unqualifiedKeys) + private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = + m.filterKeys(unqualifiedKeys) - private[this] def addExtra(properties: Map[String, String], id: ModuleRevisionId): ModuleRevisionId = - { - import collection.JavaConverters._ - val oldExtra = qualifiedExtra(id) - val newExtra = (oldExtra ++ properties).asJava - ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, newExtra) - } + private[this] def addExtra( + properties: Map[String, String], + id: ModuleRevisionId + ): ModuleRevisionId = { + import collection.JavaConverters._ + val oldExtra = qualifiedExtra(id) + val newExtra = (oldExtra ++ properties).asJava + ModuleRevisionId.newInstance( + id.getOrganisation, + id.getName, + id.getBranch, + id.getRevision, + newExtra + ) + } - private[this] def getDependencyExtra(m: Map[String, String]): Map[ModuleRevisionId, Map[String, String]] = + private[this] def getDependencyExtra( + m: Map[String, String] + ): Map[ModuleRevisionId, Map[String, String]] = PomExtraDependencyAttributes.getDependencyExtra(m) - def qualifiedExtra(item: ExtendableItem): Map[String, String] = PomExtraDependencyAttributes.qualifiedExtra(item) + def qualifiedExtra(item: ExtendableItem): Map[String, String] = + PomExtraDependencyAttributes.qualifiedExtra(item) def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = - (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) + (qualifiedExtra(item) filterKeys { k => + qualifiedIsExtra(k) == include + }) def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = PomExtraDependencyAttributes.writeDependencyExtra(s) // parses the sequence of dependencies with extra attribute information, with one dependency per line - def readDependencyExtra(s: String): Seq[ModuleRevisionId] = PomExtraDependencyAttributes.readDependencyExtra(s) + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = + PomExtraDependencyAttributes.readDependencyExtra(s) def qualifiedIsExtra(k: String): Boolean = PomExtraDependencyAttributes.qualifiedIsExtra(k) @@ -145,20 +197,33 @@ object CustomPomParser { // with the extra attributes from the section def simplify(id: ModuleRevisionId): ModuleRevisionId = PomExtraDependencyAttributes.simplify(id) - private[this] def addExtra(dep: DependencyDescriptor, extra: Map[ModuleRevisionId, Map[String, String]]): DependencyDescriptor = - { - val extras = if (extra.isEmpty) None else extra get simplify(dep.getDependencyRevisionId) - extras match { - case None => dep - case Some(extraAttrs) => transform(dep, revId => addExtra(extraAttrs, revId)) - } + private[this] def addExtra( + dep: DependencyDescriptor, + extra: Map[ModuleRevisionId, Map[String, String]] + ): DependencyDescriptor = { + val extras = if (extra.isEmpty) None else extra get simplify(dep.getDependencyRevisionId) + extras match { + case None => dep + case Some(extraAttrs) => transform(dep, revId => addExtra(extraAttrs, revId)) } - private[this] def transform(dep: DependencyDescriptor, f: ModuleRevisionId => ModuleRevisionId): DependencyDescriptor = - DefaultDependencyDescriptor.transformInstance(dep, namespaceTransformer(dep.getDependencyRevisionId, f), false) + } + private[this] def transform( + dep: DependencyDescriptor, + f: ModuleRevisionId => ModuleRevisionId + ): DependencyDescriptor = + DefaultDependencyDescriptor.transformInstance( + dep, + namespaceTransformer(dep.getDependencyRevisionId, f), + false + ) - private[this] def namespaceTransformer(txId: ModuleRevisionId, f: ModuleRevisionId => ModuleRevisionId): NamespaceTransformer = + private[this] def namespaceTransformer( + txId: ModuleRevisionId, + f: ModuleRevisionId => ModuleRevisionId + ): NamespaceTransformer = new NamespaceTransformer { - def transform(revId: ModuleRevisionId): ModuleRevisionId = if (revId == txId) f(revId) else revId + def transform(revId: ModuleRevisionId): ModuleRevisionId = + if (revId == txId) f(revId) else revId def isIdentity = false } @@ -167,53 +232,80 @@ object CustomPomParser { VersionRange.stripMavenVersionRange(dd.getDependencyRevisionId.getRevision) match { case Some(newVersion) => val id = dd.getDependencyRevisionId - val newId = ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, newVersion, id.getExtraAttributes) + val newId = ModuleRevisionId.newInstance( + id.getOrganisation, + id.getName, + id.getBranch, + newVersion, + id.getExtraAttributes + ) transform(dd, _ => newId) case None => dd } - private[sbt] lazy val versionRangeFlag = sys.props.get("sbt.modversionrange") map { _.toLowerCase == "true" } getOrElse true + private[sbt] lazy val versionRangeFlag = sys.props.get("sbt.modversionrange") map { + _.toLowerCase == "true" + } getOrElse true import collection.JavaConverters._ - def addExtra(properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String, String]], parser: ModuleDescriptorParser, md: ModuleDescriptor): ModuleDescriptor = - { - val dmd = new DefaultModuleDescriptor(parser, md.getResource) + def addExtra( + properties: Map[String, String], + dependencyExtra: Map[ModuleRevisionId, Map[String, String]], + parser: ModuleDescriptorParser, + md: ModuleDescriptor + ): ModuleDescriptor = { + val dmd = new DefaultModuleDescriptor(parser, md.getResource) - val mrid = addExtra(properties, md.getModuleRevisionId) - val resolvedMrid = addExtra(properties, md.getResolvedModuleRevisionId) - dmd.setModuleRevisionId(mrid) - dmd.setResolvedModuleRevisionId(resolvedMrid) + val mrid = addExtra(properties, md.getModuleRevisionId) + val resolvedMrid = addExtra(properties, md.getResolvedModuleRevisionId) + dmd.setModuleRevisionId(mrid) + dmd.setResolvedModuleRevisionId(resolvedMrid) - dmd.setDefault(md.isDefault) - dmd.setHomePage(md.getHomePage) - dmd.setDescription(md.getDescription) - dmd.setLastModified(md.getLastModified) - dmd.setStatus(md.getStatus()) - dmd.setPublicationDate(md.getPublicationDate()) - dmd.setResolvedPublicationDate(md.getResolvedPublicationDate()) + dmd.setDefault(md.isDefault) + dmd.setHomePage(md.getHomePage) + dmd.setDescription(md.getDescription) + dmd.setLastModified(md.getLastModified) + dmd.setStatus(md.getStatus()) + dmd.setPublicationDate(md.getPublicationDate()) + dmd.setResolvedPublicationDate(md.getResolvedPublicationDate()) - for (l <- md.getLicenses) dmd.addLicense(l) - for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again - for ((key, value) <- md.getExtraAttributesNamespaces.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraAttributeNamespace(key, value) - IvySbt.addExtraNamespace(dmd) + for (l <- md.getLicenses) dmd.addLicense(l) + for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) + dmd.addExtraInfo(key, value) + dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again + for ((key, value) <- md.getExtraAttributesNamespaces + .asInstanceOf[java.util.Map[String, String]] + .asScala) dmd.addExtraAttributeNamespace(key, value) + IvySbt.addExtraNamespace(dmd) - val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } - val withVersionRangeMod: Seq[DependencyDescriptor] = - if (versionRangeFlag) withExtra map { stripVersionRange } - else withExtra - val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) - unique foreach dmd.addDependency - - for (ed <- md.getInheritedDescriptors) dmd.addInheritedDescriptor(new DefaultExtendsDescriptor(md, ed.getLocation, ed.getExtendsTypes)) - for (conf <- md.getConfigurations) { - dmd.addConfiguration(conf) - for (art <- md.getArtifacts(conf.getName)) { - val ext = art.getExt - val newExt = if (JarPackagings(ext)) "jar" else ext - val nart = new DefaultArtifact(mrid, art.getPublicationDate, art.getName, art.getType, newExt, art.getUrl, art.getQualifiedExtraAttributes) - dmd.addArtifact(conf.getName, nart) - } - } - dmd + val withExtra = md.getDependencies map { dd => + addExtra(dd, dependencyExtra) } + val withVersionRangeMod: Seq[DependencyDescriptor] = + if (versionRangeFlag) withExtra map { stripVersionRange } else withExtra + val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) + unique foreach dmd.addDependency + + for (ed <- md.getInheritedDescriptors) + dmd.addInheritedDescriptor( + new DefaultExtendsDescriptor(md, ed.getLocation, ed.getExtendsTypes) + ) + for (conf <- md.getConfigurations) { + dmd.addConfiguration(conf) + for (art <- md.getArtifacts(conf.getName)) { + val ext = art.getExt + val newExt = if (JarPackagings(ext)) "jar" else ext + val nart = new DefaultArtifact( + mrid, + art.getPublicationDate, + art.getName, + art.getType, + newExt, + art.getUrl, + art.getQualifiedExtraAttributes + ) + dmd.addArtifact(conf.getName, nart) + } + } + dmd + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index d8100ddcf..0498828be 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -6,7 +6,10 @@ package sbt.internal.librarymanagement import java.io.ByteArrayInputStream import java.net.URL -import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor } +import org.apache.ivy.core.module.descriptor.{ + DefaultDependencyDescriptor, + DefaultModuleDescriptor +} import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource @@ -15,21 +18,22 @@ import org.apache.ivy.plugins.repository.url.URLResource /** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { import XmlModuleDescriptorParser.Parser - class CustomParser(settings: IvySettings, defaultConfig: Option[String]) extends Parser(CustomXmlParser, settings) { - def setSource(url: URL) = - { - super.setResource(new URLResource(url)) - super.setInput(url) - } + class CustomParser(settings: IvySettings, defaultConfig: Option[String]) + extends Parser(CustomXmlParser, settings) { + def setSource(url: URL) = { + super.setResource(new URLResource(url)) + super.setInput(url) + } def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes)) + /** Overridden because the super implementation overwrites the module descriptor.*/ override def setResource(res: Resource): Unit = () - override def setMd(md: DefaultModuleDescriptor) = - { - super.setMd(md) - if (defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") - } - override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = super.parseDepsConfs(confs, dd) + override def setMd(md: DefaultModuleDescriptor) = { + super.setMd(md) + if (defaultConfig.isDefined) setDefaultConfMapping("*->default(compile)") + } + override def parseDepsConfs(confs: String, dd: DefaultDependencyDescriptor) = + super.parseDepsConfs(confs, dd) override def getDefaultConf = defaultConfig.getOrElse(super.getDefaultConf) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 58ef9f63d..b8e493ee4 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -5,7 +5,14 @@ import java.net.URL import org.apache.ivy.core.cache.ArtifactOrigin import org.apache.ivy.core.cache.{ DefaultRepositoryCacheManager, RepositoryCacheManager } -import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, DefaultModuleDescriptor, DependencyArtifactDescriptor, DependencyDescriptor } +import org.apache.ivy.core.module.descriptor.{ + Artifact => IvyArtifact, + DefaultArtifact, + DefaultDependencyArtifactDescriptor, + DefaultModuleDescriptor, + DependencyArtifactDescriptor, + DependencyDescriptor +} import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.report.ArtifactDownloadReport import org.apache.ivy.core.report.{ DownloadReport, DownloadStatus } @@ -22,7 +29,8 @@ import FakeResolver._ /** * A fake `DependencyResolver` that statically serves predefined artifacts. */ -private[sbt] class FakeResolver(private var name: String, cacheDir: File, modules: ModulesMap) extends DependencyResolver { +private[sbt] class FakeResolver(private var name: String, cacheDir: File, modules: ModulesMap) + extends DependencyResolver { private object Artifact { def unapply(art: IvyArtifact): Some[(String, String, String)] = { @@ -55,7 +63,10 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module override def commitPublishTransaction(): Unit = throw new UnsupportedOperationException("This resolver doesn't support publishing.") - override def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = { + override def download( + artifact: ArtifactOrigin, + options: DownloadOptions + ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) val path = new URL(artifact.getLocation).toURI.getPath @@ -99,12 +110,12 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val mrid = dd.getDependencyRevisionId() val artifact = modules get ((organisation, name, revision)) map { arts => - val artifacts: Array[DependencyArtifactDescriptor] = arts.toArray map (_ artifactOf dd) val moduleDescriptor = DefaultModuleDescriptor.newDefaultInstance(mrid, artifacts) val defaultArtifact = arts.headOption match { - case Some(FakeArtifact(name, tpe, ext, _)) => new DefaultArtifact(mrid, new java.util.Date, name, tpe, ext) - case None => null + case Some(FakeArtifact(name, tpe, ext, _)) => + new DefaultArtifact(mrid, new java.util.Date, name, tpe, ext) + case None => null } val metadataReport = new MetadataArtifactDownloadReport(defaultArtifact) metadataReport.setDownloadStatus(DownloadStatus.SUCCESSFUL) @@ -147,10 +158,16 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module new RevisionEntry(module, v) }.toArray - override def listTokenValues(tokens: Array[String], criteria: java.util.Map[_, _]): Array[java.util.Map[_, _]] = + override def listTokenValues( + tokens: Array[String], + criteria: java.util.Map[_, _] + ): Array[java.util.Map[_, _]] = Array.empty - override def listTokenValues(token: String, otherTokenValues: java.util.Map[_, _]): Array[String] = + override def listTokenValues( + token: String, + otherTokenValues: java.util.Map[_, _] + ): Array[String] = Array.empty override def locate(art: IvyArtifact): ArtifactOrigin = { @@ -158,7 +175,8 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val artifact = for { artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) - artifact <- artifacts find (a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt) + artifact <- artifacts find (a => + a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt) } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) artifact.orNull @@ -183,6 +201,13 @@ private[sbt] object FakeResolver { final case class FakeArtifact(name: String, tpe: String, ext: String, file: File) { def artifactOf(dd: DependencyDescriptor): DependencyArtifactDescriptor = - new DefaultDependencyArtifactDescriptor(dd, name, tpe, ext, file.toURI.toURL, new java.util.HashMap) + new DefaultDependencyArtifactDescriptor( + dd, + name, + tpe, + ext, + file.toURI.toURL, + new java.util.HashMap + ) } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 44c53d826..b5084ffb6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -11,8 +11,19 @@ import org.apache.ivy.Ivy import org.apache.ivy.core.IvyPatternHelper import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } import org.apache.ivy.core.event.EventManager -import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, MDArtifact } -import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, ModuleDescriptor, License } +import org.apache.ivy.core.module.descriptor.{ + Artifact => IArtifact, + DefaultArtifact, + DefaultDependencyArtifactDescriptor, + MDArtifact +} +import org.apache.ivy.core.module.descriptor.{ + DefaultDependencyDescriptor, + DefaultModuleDescriptor, + DependencyDescriptor, + ModuleDescriptor, + License +} import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId } import org.apache.ivy.core.resolve._ @@ -29,7 +40,11 @@ import scala.collection.mutable import sbt.util.Logger import sbt.librarymanagement._ import Resolver.PluginPattern -import ivyint.{ CachedResolutionResolveEngine, CachedResolutionResolveCache, SbtDefaultDependencyDescriptor } +import ivyint.{ + CachedResolutionResolveEngine, + CachedResolutionResolveCache, + SbtDefaultDependencyDescriptor +} final class IvySbt(val configuration: IvyConfiguration) { self => import configuration.baseDirectory @@ -41,72 +56,82 @@ final class IvySbt(val configuration: IvyConfiguration) { self => * saving some time. This is necessary because Ivy has global state (IvyContext, Message, DocumentBuilder, ...). */ - private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = - { - def action() = - IvySbt.synchronized { - val originalLogger = Message.getDefaultLogger - Message.setDefaultLogger(logger) - try { f } - finally { Message.setDefaultLogger(originalLogger) } + private def withDefaultLogger[T](logger: MessageLogger)(f: => T): T = { + def action() = + IvySbt.synchronized { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(logger) + try { f } finally { Message.setDefaultLogger(originalLogger) } + } + // Ivy is not thread-safe nor can the cache be used concurrently. + // If provided a GlobalLock, we can use that to ensure safe access to the cache. + // Otherwise, we can at least synchronize within the JVM. + // For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe. + configuration.lock match { + case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) + case None => action() + } + } + private lazy val settings: IvySettings = { + val is = new IvySettings + + is.setBaseDir(baseDirectory) + is.setCircularDependencyStrategy( + configuration.updateOptions.circularDependencyLevel.ivyStrategy + ) + CustomPomParser.registerDefault + + configuration match { + case e: ExternalIvyConfiguration => + IvySbt.addResolvers(e.extraResolvers, is, configuration.log) + IvySbt.loadURI(is, e.uri) + case i: InlineIvyConfiguration => + is.setVariable("ivy.checksums", i.checksums mkString ",") + i.paths.ivyHome foreach is.setDefaultIvyUserDir + IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) + IvySbt.setResolvers( + is, + i.resolvers, + i.otherResolvers, + i.localOnly, + configuration.updateOptions, + configuration.log + ) + IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) + } + is + } + private[sbt] def mkIvy: Ivy = { + val i = new Ivy() { + private val loggerEngine = new SbtMessageLoggerEngine + override def getLoggerEngine = loggerEngine + override def bind(): Unit = { + val prOpt = Option(getSettings.getResolver(ProjectResolver.InterProject)) map { + case pr: ProjectResolver => pr } - // Ivy is not thread-safe nor can the cache be used concurrently. - // If provided a GlobalLock, we can use that to ensure safe access to the cache. - // Otherwise, we can at least synchronize within the JVM. - // For thread-safety in particular, Ivy uses a static DocumentBuilder, which is not thread-safe. - configuration.lock match { - case Some(lock) => lock(ivyLockFile, new Callable[T] { def call = action() }) - case None => action() - } - } - private lazy val settings: IvySettings = - { - val is = new IvySettings - - is.setBaseDir(baseDirectory) - is.setCircularDependencyStrategy(configuration.updateOptions.circularDependencyLevel.ivyStrategy) - CustomPomParser.registerDefault - - configuration match { - case e: ExternalIvyConfiguration => - IvySbt.addResolvers(e.extraResolvers, is, configuration.log) - IvySbt.loadURI(is, e.uri) - case i: InlineIvyConfiguration => - is.setVariable("ivy.checksums", i.checksums mkString ",") - i.paths.ivyHome foreach is.setDefaultIvyUserDir - IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) - IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, i.localOnly, configuration.updateOptions, configuration.log) - IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) - } - is - } - private[sbt] def mkIvy: Ivy = - { - val i = new Ivy() { - private val loggerEngine = new SbtMessageLoggerEngine - override def getLoggerEngine = loggerEngine - override def bind(): Unit = { - val prOpt = Option(getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } - // We inject the deps we need before we can hook our resolve engine. - setSortEngine(new SortEngine(getSettings)) - setEventManager(new EventManager()) - if (configuration.updateOptions.cachedResolution) { - setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine) with CachedResolutionResolveEngine { + // We inject the deps we need before we can hook our resolve engine. + setSortEngine(new SortEngine(getSettings)) + setEventManager(new EventManager()) + if (configuration.updateOptions.cachedResolution) { + setResolveEngine( + new ResolveEngine(getSettings, getEventManager, getSortEngine) + with CachedResolutionResolveEngine { val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache val projectResolver = prOpt def makeInstance = mkIvy - }) - } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) - super.bind() - } + } + ) + } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) + super.bind() } - - i.setSettings(settings) - i.bind() - i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) - i } + i.setSettings(settings) + i.bind() + i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) + i + } + private lazy val ivy: Ivy = mkIvy // Must be the same file as is used in Update in the launcher private lazy val ivyLockFile = new File(settings.getDefaultIvyUserDir, ".sbt.ivy.lock") @@ -123,8 +148,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => ivyint.ErrorMessageAuthenticator.install() ivy.pushContext() ivy.getLoggerEngine.pushLogger(log) - try { f(ivy) } - finally { + try { f(ivy) } finally { ivy.getLoggerEngine.popLogger() ivy.popContext() } @@ -137,7 +161,9 @@ final class IvySbt(val configuration: IvyConfiguration) { self => */ private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = withIvy(log) { i => - val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { case pr: ProjectResolver => pr } + val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { + case pr: ProjectResolver => pr + } if (configuration.updateOptions.cachedResolution) { IvySbt.cachedResolutionResolveCache.clean(md, prOpt) } @@ -147,98 +173,124 @@ final class IvySbt(val configuration: IvyConfiguration) { self => val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) def owner = IvySbt.this def withModule[T](log: Logger)(f: (Ivy, DefaultModuleDescriptor, String) => T): T = - withIvy[T](log) { ivy => f(ivy, moduleDescriptor0, defaultConfig0) } + withIvy[T](log) { ivy => + f(ivy, moduleDescriptor0, defaultConfig0) + } def moduleDescriptor(log: Logger): DefaultModuleDescriptor = withModule(log)((_, md, _) => md) - def dependencyMapping(log: Logger): (ModuleRevisionId, ModuleDescriptor) = - { - val md = moduleDescriptor(log) - (md.getModuleRevisionId, md) - } + def dependencyMapping(log: Logger): (ModuleRevisionId, ModuleDescriptor) = { + val md = moduleDescriptor(log) + (md.getModuleRevisionId, md) + } def defaultConfig(log: Logger): String = withModule(log)((_, _, dc) => dc) // these should only be referenced by withModule because lazy vals synchronize on this object // withIvy explicitly locks the IvySbt object, so they have to be done in the right order to avoid deadlock - private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = - { - val (baseModule, baseConfiguration) = - moduleSettings match { - case ic: InlineConfiguration => configureInline(ic, configuration.log) - case pc: PomConfiguration => configurePom(pc) - case ifc: IvyFileConfiguration => configureIvyFile(ifc) - } - - val configs = - moduleSettings match { - case ic: InlineConfiguration => ic.configurations - case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal - case ifc: IvyFileConfiguration => Configurations.default ++ Configurations.defaultInternal - } - moduleSettings.ivyScala match { - case Some(is) => - val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } - IvyScala.checkModule(baseModule, baseConfiguration, svc, configuration.log)(is) - case _ => // do nothing + private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = { + val (baseModule, baseConfiguration) = + moduleSettings match { + case ic: InlineConfiguration => configureInline(ic, configuration.log) + case pc: PomConfiguration => configurePom(pc) + case ifc: IvyFileConfiguration => configureIvyFile(ifc) } - IvySbt.addExtraNamespace(baseModule) - (baseModule, baseConfiguration) - } - private def configureInline(ic: InlineConfiguration, log: Logger) = - { - import ic._ - val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) - IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) - val defaultConf = defaultConfiguration getOrElse Configurations.config(ModuleDescriptor.DEFAULT_CONFIGURATION) - log.debug("Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." else " and XML.")) - val parser = IvySbt.parseIvyXML(ivy.getSettings, IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, validate) - IvySbt.addMainArtifact(moduleID) - IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) - IvySbt.addExcludes(moduleID, excludes, ivyScala) - val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) - IvySbt.addDependencies(moduleID, transformedDeps, parser) - (moduleID, parser.getDefaultConf) + val configs = + moduleSettings match { + case ic: InlineConfiguration => ic.configurations + case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal + case ifc: IvyFileConfiguration => + Configurations.default ++ Configurations.defaultInternal + } + moduleSettings.ivyScala match { + case Some(is) => + val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } + IvyScala.checkModule(baseModule, baseConfiguration, svc, configuration.log)(is) + case _ => // do nothing } - private def newConfiguredModuleID(module: ModuleID, moduleInfo: ModuleInfo, configurations: Iterable[Configuration]) = - { - val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) - mod.setLastModified(System.currentTimeMillis) - mod.setDescription(moduleInfo.description) - moduleInfo.homepage foreach { h => mod.setHomePage(h.toString) } - moduleInfo.licenses foreach { l => mod.addLicense(new License(l._1, l._2.toString)) } - IvySbt.addConfigurations(mod, configurations) - IvySbt.addArtifacts(mod, module.explicitArtifacts) - mod + IvySbt.addExtraNamespace(baseModule) + (baseModule, baseConfiguration) + } + private def configureInline(ic: InlineConfiguration, log: Logger) = { + import ic._ + val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) + IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) + val defaultConf = defaultConfiguration getOrElse Configurations.config( + ModuleDescriptor.DEFAULT_CONFIGURATION + ) + log.debug( + "Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." + else " and XML.") + ) + + val parser = IvySbt.parseIvyXML( + ivy.getSettings, + IvySbt.wrapped(module, ivyXML), + moduleID, + defaultConf.name, + validate + ) + IvySbt.addMainArtifact(moduleID) + IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) + IvySbt.addExcludes(moduleID, excludes, ivyScala) + val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) + IvySbt.addDependencies(moduleID, transformedDeps, parser) + (moduleID, parser.getDefaultConf) + } + private def newConfiguredModuleID( + module: ModuleID, + moduleInfo: ModuleInfo, + configurations: Iterable[Configuration] + ) = { + val mod = new DefaultModuleDescriptor(IvySbt.toID(module), "release", null, false) + mod.setLastModified(System.currentTimeMillis) + mod.setDescription(moduleInfo.description) + moduleInfo.homepage foreach { h => + mod.setHomePage(h.toString) } + moduleInfo.licenses foreach { l => + mod.addLicense(new License(l._1, l._2.toString)) + } + IvySbt.addConfigurations(mod, configurations) + IvySbt.addArtifacts(mod, module.explicitArtifacts) + mod + } /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ - private def configurePom(pc: PomConfiguration) = - { - val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) - val dmd = IvySbt.toDefaultModuleDescriptor(md) - IvySbt.addConfigurations(dmd, Configurations.defaultInternal) - val defaultConf = Configurations.DefaultMavenConfiguration.name - for (is <- pc.ivyScala) if (pc.autoScalaTools) { - val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) - confParser.setMd(dmd) - addScalaToolDependencies(dmd, confParser, is) - } - (dmd, defaultConf) + private def configurePom(pc: PomConfiguration) = { + val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) + val dmd = IvySbt.toDefaultModuleDescriptor(md) + IvySbt.addConfigurations(dmd, Configurations.defaultInternal) + val defaultConf = Configurations.DefaultMavenConfiguration.name + for (is <- pc.ivyScala) if (pc.autoScalaTools) { + val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) + confParser.setMd(dmd) + addScalaToolDependencies(dmd, confParser, is) } + (dmd, defaultConf) + } + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ - private def configureIvyFile(ifc: IvyFileConfiguration) = - { - val parser = new CustomXmlParser.CustomParser(settings, None) - parser.setValidate(ifc.validate) - parser.setSource(toURL(ifc.file)) - parser.parse() - val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) - for (is <- ifc.ivyScala) if (ifc.autoScalaTools) + private def configureIvyFile(ifc: IvyFileConfiguration) = { + val parser = new CustomXmlParser.CustomParser(settings, None) + parser.setValidate(ifc.validate) + parser.setSource(toURL(ifc.file)) + parser.parse() + val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) + for (is <- ifc.ivyScala) + if (ifc.autoScalaTools) addScalaToolDependencies(dmd, parser, is) - (dmd, parser.getDefaultConf) - } - private def addScalaToolDependencies(dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, is: IvyScala): Unit = { + (dmd, parser.getDefaultConf) + } + private def addScalaToolDependencies( + dmd: DefaultModuleDescriptor, + parser: CustomXmlParser.CustomParser, + is: IvyScala + ): Unit = { IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) - IvySbt.addDependencies(dmd, ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), parser) + IvySbt.addDependencies( + dmd, + ScalaArtifacts.toolDependencies(is.scalaOrganization, is.scalaFullVersion), + parser + ) } private def toURL(file: File) = file.toURI.toURL } @@ -249,7 +301,8 @@ private[sbt] object IvySbt { val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" val DefaultChecksums = Vector("sha1", "md5") - private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache + private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache = + new CachedResolutionResolveCache def defaultIvyFile(project: File) = new File(project, DefaultIvyFilename) def defaultIvyConfiguration(project: File) = new File(project, DefaultIvyConfigFilename) @@ -266,7 +319,14 @@ private[sbt] object IvySbt { * Sets the resolvers for 'settings' to 'resolvers'. This is done by creating a new chain and making it the default. * 'other' is for resolvers that should be in a different chain. These are typically used for publishing or other actions. */ - private def setResolvers(settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], localOnly: Boolean, updateOptions: UpdateOptions, log: Logger): Unit = { + private def setResolvers( + settings: IvySettings, + resolvers: Seq[Resolver], + other: Seq[Resolver], + localOnly: Boolean, + updateOptions: UpdateOptions, + log: Logger + ): Unit = { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") val chain = resolverChain(name, rs, localOnly, settings, updateOptions, log) @@ -283,15 +343,36 @@ private[sbt] object IvySbt { module.revision endsWith "-SNAPSHOT" private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean = mrid.getRevision endsWith "-SNAPSHOT" - def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, log: Logger): DependencyResolver = + def resolverChain( + name: String, + resolvers: Seq[Resolver], + localOnly: Boolean, + settings: IvySettings, + log: Logger + ): DependencyResolver = resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) - def resolverChain(name: String, resolvers: Seq[Resolver], localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger): DependencyResolver = { - def mapResolvers(rs: Seq[Resolver]) = rs.map(r => ConvertResolver(r, settings, updateOptions, log)) + def resolverChain( + name: String, + resolvers: Seq[Resolver], + localOnly: Boolean, + settings: IvySettings, + updateOptions: UpdateOptions, + log: Logger + ): DependencyResolver = { + def mapResolvers(rs: Seq[Resolver]) = + rs.map(r => ConvertResolver(r, settings, updateOptions, log)) val (projectResolvers, rest) = resolvers.partition(_.name == "inter-project") - if (projectResolvers.isEmpty) new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) + if (projectResolvers.isEmpty) + new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) else { // Here we set up a "first repo wins" chain resolver - val delegate = new ivyint.SbtChainResolver(name + "-delegate", mapResolvers(rest), settings, updateOptions, log) + val delegate = new ivyint.SbtChainResolver( + name + "-delegate", + mapResolvers(rest), + settings, + updateOptions, + log + ) val prs = mapResolvers(projectResolvers) // Here we construct a chain resolver which will FORCE looking at the project resolver first. new ivyint.SbtChainResolver( @@ -310,17 +391,22 @@ private[sbt] object IvySbt { settings.addResolver(ConvertResolver(r, settings, UpdateOptions(), log)) } } + /** * A hack to detect if the given artifact is an automatically generated request for a classifier, * as opposed to a user-initiated declaration. It relies on Ivy prefixing classifier with m:, while sbt uses e:. * Clearly, it would be better to have an explicit option in Ivy to control this. */ - def hasImplicitClassifier(artifact: IArtifact): Boolean = - { - import scala.collection.JavaConverters._ - artifact.getQualifiedExtraAttributes.asScala.keys.exists(_.asInstanceOf[String] startsWith "m:") - } - private def setModuleConfigurations(settings: IvySettings, moduleConfigurations: Seq[ModuleConfiguration], log: Logger): Unit = { + def hasImplicitClassifier(artifact: IArtifact): Boolean = { + import scala.collection.JavaConverters._ + artifact.getQualifiedExtraAttributes.asScala.keys + .exists(_.asInstanceOf[String] startsWith "m:") + } + private def setModuleConfigurations( + settings: IvySettings, + moduleConfigurations: Seq[ModuleConfiguration], + log: Logger + ): Unit = { val existing = settings.getResolverNames for (moduleConf <- moduleConfigurations) { import moduleConf._ @@ -328,15 +414,32 @@ private[sbt] object IvySbt { import PatternMatcher._ if (!existing.contains(resolver.name)) settings.addResolver(ConvertResolver(resolver, settings, UpdateOptions(), log)) - val attributes = javaMap(Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision)) - settings.addModuleConfiguration(attributes, settings.getMatcher(EXACT_OR_REGEXP), resolver.name, null, null, null) + val attributes = javaMap( + Map(MODULE_KEY -> name, ORGANISATION_KEY -> organization, REVISION_KEY -> revision) + ) + settings.addModuleConfiguration( + attributes, + settings.getMatcher(EXACT_OR_REGEXP), + resolver.name, + null, + null, + null + ) } } - private def configureCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]): Unit = { + private def configureCache( + settings: IvySettings, + localOnly: Boolean, + resCacheDir: Option[File] + ): Unit = { configureResolutionCache(settings, localOnly, resCacheDir) configureRepositoryCache(settings, localOnly) } - private[this] def configureResolutionCache(settings: IvySettings, localOnly: Boolean, resCacheDir: Option[File]): Unit = { + private[this] def configureResolutionCache( + settings: IvySettings, + localOnly: Boolean, + resCacheDir: Option[File] + ): Unit = { val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir settings.setResolutionCacheManager(new ResolutionCache(base, settings)) } @@ -346,19 +449,32 @@ private[sbt] object IvySbt { // if there are problems with this, a less aggressive fix might be to only reset the artifact resolver when it is a ProjectResolver // a possible problem is that fetching artifacts is slower, due to the full chain being the artifact resolver instead of the specific resolver // This also fixes #760, which occurs when metadata exists in a repository, but the artifact doesn't. - private[sbt] def resetArtifactResolver(resolved: ResolvedModuleRevision): ResolvedModuleRevision = + private[sbt] def resetArtifactResolver( + resolved: ResolvedModuleRevision + ): ResolvedModuleRevision = if (resolved eq null) null else { val desc = resolved.getDescriptor val updatedDescriptor = CustomPomParser.defaultTransform(desc.getParser, desc) - new ResolvedModuleRevision(resolved.getResolver, resolved.getResolver, updatedDescriptor, resolved.getReport, resolved.isForce) + new ResolvedModuleRevision( + resolved.getResolver, + resolved.getResolver, + updatedDescriptor, + resolved.getReport, + resolved.isForce + ) } private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean): Unit = { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { - override def findModuleInCache(dd: DependencyDescriptor, revId: ModuleRevisionId, options: CacheMetadataOptions, r: String) = { + override def findModuleInCache( + dd: DependencyDescriptor, + revId: ModuleRevisionId, + options: CacheMetadataOptions, + r: String + ) = { // ignore and reset the resolver- not ideal, but avoids thrashing. val resolved = resetArtifactResolver(super.findModuleInCache(dd, revId, options, null)) // invalidate the cache if the artifact was removed from the local repository @@ -384,7 +500,11 @@ private[sbt] object IvySbt { case _ => false } // ignore the original resolver wherever possible to avoid issues like #704 - override def saveResolvers(descriptor: ModuleDescriptor, metadataResolverName: String, artifactResolverName: String): Unit = () + override def saveResolvers( + descriptor: ModuleDescriptor, + metadataResolverName: String, + artifactResolverName: String + ): Unit = () } manager.setArtifactPattern(PluginPattern + manager.getArtifactPattern) manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) @@ -399,23 +519,36 @@ private[sbt] object IvySbt { settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) } - def toIvyConfiguration(configuration: Configuration) = - { - import org.apache.ivy.core.module.descriptor.{ Configuration => IvyConfig } - import IvyConfig.Visibility._ - import configuration._ - new IvyConfig(name, if (isPublic) PUBLIC else PRIVATE, description, extendsConfigs.map(_.name).toArray, transitive, null) - } + def toIvyConfiguration(configuration: Configuration) = { + import org.apache.ivy.core.module.descriptor.{ Configuration => IvyConfig } + import IvyConfig.Visibility._ + import configuration._ + new IvyConfig( + name, + if (isPublic) PUBLIC else PRIVATE, + description, + extendsConfigs.map(_.name).toArray, + transitive, + null + ) + } def addExtraNamespace(dmd: DefaultModuleDescriptor): Unit = dmd.addExtraAttributeNamespace("e", "http://ant.apache.org/ivy/extra") /** Adds the ivy.xml main artifact. */ private def addMainArtifact(moduleID: DefaultModuleDescriptor): Unit = { - val artifact = DefaultArtifact.newIvyArtifact(moduleID.getResolvedModuleRevisionId, moduleID.getPublicationDate) + val artifact = DefaultArtifact.newIvyArtifact( + moduleID.getResolvedModuleRevisionId, + moduleID.getPublicationDate + ) moduleID.setModuleArtifact(artifact) moduleID.check() } - private def setConflictManager(moduleID: DefaultModuleDescriptor, conflict: ConflictManager, is: IvySettings): Unit = { + private def setConflictManager( + moduleID: DefaultModuleDescriptor, + conflict: ConflictManager, + is: IvySettings + ): Unit = { val mid = ModuleId.newInstance(conflict.organization, conflict.module) val matcher = is.getMatcher(PatternMatcher.EXACT_OR_REGEXP) val manager = is.getConflictManager(conflict.name) @@ -423,143 +556,189 @@ private[sbt] object IvySbt { } /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ - def toID(m: ModuleID) = - { - import m._ - ModuleRevisionId.newInstance(organization, name, branchName.orNull, revision, javaMap(extraAttributes)) - } + def toID(m: ModuleID) = { + import m._ + ModuleRevisionId.newInstance( + organization, + name, + branchName.orNull, + revision, + javaMap(extraAttributes) + ) + } private def substituteCross(m: ModuleSettings): ModuleSettings = m.ivyScala match { case None => m case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) } - private def substituteCross(m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String): ModuleSettings = - { - val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) - m match { - case ic: InlineConfiguration => ic.withModule(sub(ic.module)).withDependencies(ic.dependencies map sub).withOverrides(ic.overrides map sub) - case _ => m - } + private def substituteCross( + m: ModuleSettings, + scalaFullVersion: String, + scalaBinaryVersion: String + ): ModuleSettings = { + val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) + m match { + case ic: InlineConfiguration => + ic.withModule(sub(ic.module)) + .withDependencies(ic.dependencies map sub) + .withOverrides(ic.overrides map sub) + case _ => m } + } - private def toIvyArtifact(moduleID: ModuleDescriptor, a: Artifact, allConfigurations: Iterable[String]): MDArtifact = - { - val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - copyConfigurations(a, artifact.addConfiguration, allConfigurations) - artifact - } - def getExtraAttributes(revID: ExtendableItem): Map[String, String] = - { - import scala.collection.JavaConverters._ - revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap - } - private[sbt] def extra(artifact: Artifact, unqualify: Boolean = false): java.util.Map[String, String] = - { - val ea = artifact.classifier match { case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } - javaMap(ea.extraAttributes, unqualify) - } - private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = - { - import scala.collection.JavaConverters._ - val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m - if (map.isEmpty) null else map.asJava + private def toIvyArtifact( + moduleID: ModuleDescriptor, + a: Artifact, + allConfigurations: Iterable[String] + ): MDArtifact = { + val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) + copyConfigurations(a, artifact.addConfiguration, allConfigurations) + artifact + } + def getExtraAttributes(revID: ExtendableItem): Map[String, String] = { + import scala.collection.JavaConverters._ + revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap + } + private[sbt] def extra( + artifact: Artifact, + unqualify: Boolean = false + ): java.util.Map[String, String] = { + val ea = artifact.classifier match { + case Some(c) => artifact.extra("e:classifier" -> c); case None => artifact } + javaMap(ea.extraAttributes, unqualify) + } + private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { + import scala.collection.JavaConverters._ + val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m + if (map.isEmpty) null else map.asJava + } /** Creates a full ivy file for 'module' using the 'dependencies' XML as the part after the <info>...</info> section. */ - private def wrapped(module: ModuleID, dependencies: NodeSeq) = - { - - { - if (hasInfo(module, dependencies)) - NodeSeq.Empty - else - addExtraAttributes(defaultInfo(module), module.extraAttributes) - } - { dependencies } - { - // this is because Ivy adds a default artifact if none are specified. - if ((dependencies \\ "publications").isEmpty) else NodeSeq.Empty - } - - } + private def wrapped(module: ModuleID, dependencies: NodeSeq) = { + + { + if (hasInfo(module, dependencies)) + NodeSeq.Empty + else + addExtraAttributes(defaultInfo(module), module.extraAttributes) + } + { dependencies } + { + // this is because Ivy adds a default artifact if none are specified. + if ((dependencies \\ "publications").isEmpty) else NodeSeq.Empty + } + + } private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { import module._ val base = - branchName.fold(base) { br => base % new scala.xml.UnprefixedAttribute("branch", br, scala.xml.Null) } + branchName.fold(base) { br => + base % new scala.xml.UnprefixedAttribute("branch", br, scala.xml.Null) + } } - private[this] def addExtraAttributes(elem: scala.xml.Elem, extra: Map[String, String]): scala.xml.Elem = - (elem /: extra) { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } - private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = - { - val info = { x } \ "info" - if (info.nonEmpty) { - def check(found: NodeSeq, expected: String, label: String) = - if (found.isEmpty) - sys.error("Missing " + label + " in inline Ivy XML.") - else { - val str = found.text - if (str != expected) sys.error("Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'") - } - check(info \ "@organisation", module.organization, "organisation") - check(info \ "@module", module.name, "name") - check(info \ "@revision", module.revision, "version") - } - info.nonEmpty + private[this] def addExtraAttributes( + elem: scala.xml.Elem, + extra: Map[String, String] + ): scala.xml.Elem = + (elem /: extra) { + case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } + private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { + val info = { x } \ "info" + if (info.nonEmpty) { + def check(found: NodeSeq, expected: String, label: String) = + if (found.isEmpty) + sys.error("Missing " + label + " in inline Ivy XML.") + else { + val str = found.text + if (str != expected) + sys.error( + "Inconsistent " + label + " in inline Ivy XML. Expected '" + expected + "', got '" + str + "'" + ) + } + check(info \ "@organisation", module.organization, "organisation") + check(info \ "@module", module.name, "name") + check(info \ "@revision", module.revision, "version") + } + info.nonEmpty + } + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ - private def parseIvyXML(settings: IvySettings, xml: scala.xml.NodeSeq, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = + private def parseIvyXML( + settings: IvySettings, + xml: scala.xml.NodeSeq, + moduleID: DefaultModuleDescriptor, + defaultConfiguration: String, + validate: Boolean + ): CustomXmlParser.CustomParser = parseIvyXML(settings, xml.toString, moduleID, defaultConfiguration, validate) + /** Parses the given in-memory Ivy file 'xml', using the existing 'moduleID' and specifying the given 'defaultConfiguration'. */ - private def parseIvyXML(settings: IvySettings, xml: String, moduleID: DefaultModuleDescriptor, defaultConfiguration: String, validate: Boolean): CustomXmlParser.CustomParser = - { - val parser = new CustomXmlParser.CustomParser(settings, Some(defaultConfiguration)) - parser.setMd(moduleID) - parser.setValidate(validate) - parser.setInput(xml.getBytes) - parser.parse() - parser - } + private def parseIvyXML( + settings: IvySettings, + xml: String, + moduleID: DefaultModuleDescriptor, + defaultConfiguration: String, + validate: Boolean + ): CustomXmlParser.CustomParser = { + val parser = new CustomXmlParser.CustomParser(settings, Some(defaultConfiguration)) + parser.setMd(moduleID) + parser.setValidate(validate) + parser.setInput(xml.getBytes) + parser.parse() + parser + } - def inconsistentDuplicateWarning(moduleID: DefaultModuleDescriptor): List[String] = - { - import IvyRetrieve.toModuleID - val dds = moduleID.getDependencies - val deps = dds flatMap { dd => - val module = toModuleID(dd.getDependencyRevisionId) - dd.getModuleConfigurations map (c => module.withConfigurations(Some(c))) - } - inconsistentDuplicateWarning(deps) + def inconsistentDuplicateWarning(moduleID: DefaultModuleDescriptor): List[String] = { + import IvyRetrieve.toModuleID + val dds = moduleID.getDependencies + val deps = dds flatMap { dd => + val module = toModuleID(dd.getDependencyRevisionId) + dd.getModuleConfigurations map (c => module.withConfigurations(Some(c))) } + inconsistentDuplicateWarning(deps) + } - def inconsistentDuplicateWarning(dependencies: Seq[ModuleID]): List[String] = - { - val warningHeader = "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:" - val out: mutable.ListBuffer[String] = mutable.ListBuffer() - (dependencies groupBy { dep => (dep.organization, dep.name, dep.configurations) }) foreach { - case (k, vs) if vs.size > 1 => - val v0 = vs.head - (vs find { _.revision != v0.revision }) foreach { v => - out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }).mkString(", ") + ")" - } - case _ => () - } - if (out.isEmpty) Nil - else warningHeader :: out.toList + def inconsistentDuplicateWarning(dependencies: Seq[ModuleID]): List[String] = { + val warningHeader = + "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:" + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + (dependencies groupBy { dep => + (dep.organization, dep.name, dep.configurations) + }) foreach { + case (k, vs) if vs.size > 1 => + val v0 = vs.head + (vs find { _.revision != v0.revision }) foreach { v => + out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }) + .mkString(", ") + ")" + } + case _ => () } + if (out.isEmpty) Nil + else warningHeader :: out.toList + } /** This method is used to add inline dependencies to the provided module. */ - def addDependencies(moduleID: DefaultModuleDescriptor, dependencies: Seq[ModuleID], parser: CustomXmlParser.CustomParser): Unit = { - val converted = dependencies map { dependency => convertDependency(moduleID, dependency, parser) } - val unique = if (hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted + def addDependencies( + moduleID: DefaultModuleDescriptor, + dependencies: Seq[ModuleID], + parser: CustomXmlParser.CustomParser + ): Unit = { + val converted = dependencies map { dependency => + convertDependency(moduleID, dependency, parser) + } + val unique = + if (hasDuplicateDependencies(converted)) mergeDuplicateDefinitions(converted) else converted unique foreach moduleID.addDependency } + /** Determines if there are multiple dependency definitions for the same dependency ID. */ - def hasDuplicateDependencies(dependencies: Seq[DependencyDescriptor]): Boolean = - { - val ids = dependencies.map(_.getDependencyRevisionId) - ids.toSet.size != ids.size - } + def hasDuplicateDependencies(dependencies: Seq[DependencyDescriptor]): Boolean = { + val ids = dependencies.map(_.getDependencyRevisionId) + ids.toSet.size != ids.size + } /** * Combines the artifacts, includes, and excludes of duplicate dependency definitions. @@ -571,119 +750,170 @@ private[sbt] object IvySbt { * as well as basic multi-classifier handling: #285, #419, #480. * Multiple dependency definitions should otherwise be avoided as much as possible. */ - def mergeDuplicateDefinitions(dependencies: Seq[DependencyDescriptor]): Seq[DependencyDescriptor] = - { - // need to preserve basic order of dependencies: can't use dependencies.groupBy - val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] - for (dd <- dependencies) { - val id = dd.getDependencyRevisionId - val updated = deps get id match { - case null => dd :: Nil - case v => dd :: v - } - deps.put(id, updated) - } - - import scala.collection.JavaConverters._ - deps.values.asScala.toSeq.flatMap { dds => - val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _) - if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds + def mergeDuplicateDefinitions( + dependencies: Seq[DependencyDescriptor] + ): Seq[DependencyDescriptor] = { + // need to preserve basic order of dependencies: can't use dependencies.groupBy + val deps = new java.util.LinkedHashMap[ModuleRevisionId, List[DependencyDescriptor]] + for (dd <- dependencies) { + val id = dd.getDependencyRevisionId + val updated = deps get id match { + case null => dd :: Nil + case v => dd :: v } + deps.put(id, updated) } + import scala.collection.JavaConverters._ + deps.values.asScala.toSeq.flatMap { dds => + val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _) + if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds + } + } + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ - def convertDependency(moduleID: DefaultModuleDescriptor, dependency: ModuleID, parser: CustomXmlParser.CustomParser): DefaultDependencyDescriptor = - { - val dependencyDescriptor = new DefaultDependencyDescriptor(moduleID, toID(dependency), dependency.isForce, dependency.isChanging, dependency.isTransitive) with SbtDefaultDependencyDescriptor { - def dependencyModuleId = dependency - } - dependency.configurations match { - case None => // The configuration for this dependency was not explicitly specified, so use the default - parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency - parser.parseDepsConfs(confs, dependencyDescriptor) - } - for (artifact <- dependency.explicitArtifacts) { - import artifact.{ name, `type`, extension, url } - val extraMap = extra(artifact) - val ivyArtifact = new DefaultDependencyArtifactDescriptor(dependencyDescriptor, name, `type`, extension, url.orNull, extraMap) - copyConfigurations(artifact, ivyArtifact.addConfiguration) - for (conf <- dependencyDescriptor.getModuleConfigurations) - dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) - } - for (excls <- dependency.exclusions) { - for (conf <- dependencyDescriptor.getModuleConfigurations) { - dependencyDescriptor.addExcludeRule(conf, IvyScala.excludeRule(excls.organization, excls.name, excls.configurations, excls.artifact)) - } - } - for (incls <- dependency.inclusions) { - for (conf <- dependencyDescriptor.getModuleConfigurations) { - dependencyDescriptor.addIncludeRule(conf, IvyScala.includeRule(incls.organization, incls.name, incls.configurations, incls.artifact)) - } - } - - dependencyDescriptor + def convertDependency( + moduleID: DefaultModuleDescriptor, + dependency: ModuleID, + parser: CustomXmlParser.CustomParser + ): DefaultDependencyDescriptor = { + val dependencyDescriptor = new DefaultDependencyDescriptor( + moduleID, + toID(dependency), + dependency.isForce, + dependency.isChanging, + dependency.isTransitive + ) with SbtDefaultDependencyDescriptor { + def dependencyModuleId = dependency } + dependency.configurations match { + case None => // The configuration for this dependency was not explicitly specified, so use the default + parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) + case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + parser.parseDepsConfs(confs, dependencyDescriptor) + } + for (artifact <- dependency.explicitArtifacts) { + import artifact.{ name, `type`, extension, url } + val extraMap = extra(artifact) + val ivyArtifact = new DefaultDependencyArtifactDescriptor( + dependencyDescriptor, + name, + `type`, + extension, + url.orNull, + extraMap + ) + copyConfigurations(artifact, ivyArtifact.addConfiguration) + for (conf <- dependencyDescriptor.getModuleConfigurations) + dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) + } + for (excls <- dependency.exclusions) { + for (conf <- dependencyDescriptor.getModuleConfigurations) { + dependencyDescriptor.addExcludeRule( + conf, + IvyScala.excludeRule( + excls.organization, + excls.name, + excls.configurations, + excls.artifact + ) + ) + } + } + for (incls <- dependency.inclusions) { + for (conf <- dependencyDescriptor.getModuleConfigurations) { + dependencyDescriptor.addIncludeRule( + conf, + IvyScala.includeRule( + incls.organization, + incls.name, + incls.configurations, + incls.artifact + ) + ) + } + } + + dependencyDescriptor + } def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = copyConfigurations(artifact, addConfiguration, "*" :: Nil) - private[this] def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit, allConfigurations: Iterable[String]): Unit = - { - val confs = if (artifact.configurations.isEmpty) allConfigurations else artifact.configurations.map(_.name) - confs foreach addConfiguration - } + private[this] def copyConfigurations( + artifact: Artifact, + addConfiguration: String => Unit, + allConfigurations: Iterable[String] + ): Unit = { + val confs = + if (artifact.configurations.isEmpty) allConfigurations + else artifact.configurations.map(_.name) + confs foreach addConfiguration + } - def addExcludes(moduleID: DefaultModuleDescriptor, excludes: Seq[SbtExclusionRule], ivyScala: Option[IvyScala]): Unit = + def addExcludes( + moduleID: DefaultModuleDescriptor, + excludes: Seq[SbtExclusionRule], + ivyScala: Option[IvyScala] + ): Unit = excludes foreach addExclude(moduleID, ivyScala) - def addExclude(moduleID: DefaultModuleDescriptor, ivyScala: Option[IvyScala])(exclude0: SbtExclusionRule): Unit = - { - // this adds _2.11 postfix - val exclude = CrossVersion.substituteCross(exclude0, ivyScala) - val confs = - if (exclude.configurations.isEmpty) moduleID.getConfigurationsNames.toList - else exclude.configurations - val excludeRule = IvyScala.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) - moduleID.addExcludeRule(excludeRule) - } + def addExclude(moduleID: DefaultModuleDescriptor, ivyScala: Option[IvyScala])( + exclude0: SbtExclusionRule + ): Unit = { + // this adds _2.11 postfix + val exclude = CrossVersion.substituteCross(exclude0, ivyScala) + val confs = + if (exclude.configurations.isEmpty) moduleID.getConfigurationsNames.toList + else exclude.configurations + val excludeRule = + IvyScala.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) + moduleID.addExcludeRule(excludeRule) + } - def addOverrides(moduleID: DefaultModuleDescriptor, overrides: Set[ModuleID], matcher: PatternMatcher): Unit = + def addOverrides( + moduleID: DefaultModuleDescriptor, + overrides: Set[ModuleID], + matcher: PatternMatcher + ): Unit = overrides foreach addOverride(moduleID, matcher) - def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)(overrideDef: ModuleID): Unit = - { - val overrideID = new ModuleId(overrideDef.organization, overrideDef.name) - val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) - moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) - } + def addOverride(moduleID: DefaultModuleDescriptor, matcher: PatternMatcher)( + overrideDef: ModuleID + ): Unit = { + val overrideID = new ModuleId(overrideDef.organization, overrideDef.name) + val overrideWith = new OverrideDependencyDescriptorMediator(null, overrideDef.revision) + moduleID.addDependencyDescriptorMediator(overrideID, matcher, overrideWith) + } + /** * It is necessary to explicitly modify direct dependencies because Ivy gives * "IllegalStateException: impossible to get artifacts when data has not been loaded." * when a direct dependency is overridden with a newer version." */ - def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = - { - def key(id: ModuleID) = (id.organization, id.name) - val overridden = overrides.map(id => (key(id), id.revision)).toMap - dependencies map { dep => - overridden get key(dep) match { - case Some(rev) => dep.withRevision(rev) - case None => dep - } + def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = { + def key(id: ModuleID) = (id.organization, id.name) + val overridden = overrides.map(id => (key(id), id.revision)).toMap + dependencies map { dep => + overridden get key(dep) match { + case Some(rev) => dep.withRevision(rev) + case None => dep } } + } /** This method is used to add inline artifacts to the provided module. */ def addArtifacts(moduleID: DefaultModuleDescriptor, artifacts: Iterable[Artifact]): Unit = for (art <- mapArtifacts(moduleID, artifacts.toSeq); c <- art.getConfigurations) moduleID.addArtifact(c, art) - def addConfigurations(mod: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = + def addConfigurations( + mod: DefaultModuleDescriptor, + configurations: Iterable[Configuration] + ): Unit = configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) - def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = - { - lazy val allConfigurations = moduleID.getPublicConfigurationsNames - for (artifact <- artifacts) yield toIvyArtifact(moduleID, artifact, allConfigurations) - } + def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = { + lazy val allConfigurations = moduleID.getPublicConfigurationsNames + for (artifact <- artifacts) yield toIvyArtifact(moduleID, artifact, allConfigurations) + } /** * This code converts the given ModuleDescriptor to a DefaultModuleDescriptor by casting or generating an error. @@ -694,7 +924,10 @@ private[sbt] object IvySbt { case dmd: DefaultModuleDescriptor => dmd case _ => sys.error("Unknown ModuleDescriptor type.") } - def getConfigurations(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]) = + def getConfigurations( + module: ModuleDescriptor, + configurations: Option[Iterable[Configuration]] + ) = configurations match { case Some(confs) => confs.map(_.name).toList.toArray case None => module.getPublicConfigurationsNames diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index cc1a2eda0..aad711ff5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -12,7 +12,12 @@ import org.apache.ivy.Ivy import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.core.deliver.DeliverOptions import org.apache.ivy.core.install.InstallOptions -import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, MDArtifact, ModuleDescriptor, DefaultModuleDescriptor } +import org.apache.ivy.core.module.descriptor.{ + Artifact => IArtifact, + MDArtifact, + ModuleDescriptor, + DefaultModuleDescriptor +} import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } @@ -21,20 +26,59 @@ import sbt.util.{ Logger, ShowLines } import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } import sbt.librarymanagement._, syntax._ -final class DeliverConfiguration(val deliverIvyPattern: String, val status: String, val configurations: Option[Vector[Configuration]], val logging: UpdateLogging) -final class PublishConfiguration(val ivyFile: Option[File], val resolverName: String, val artifacts: Map[Artifact, File], val checksums: Vector[String], val logging: UpdateLogging, - val overwrite: Boolean) { - def this(ivyFile: Option[File], resolverName: String, artifacts: Map[Artifact, File], checksums: Vector[String], logging: UpdateLogging) = +final class DeliverConfiguration( + val deliverIvyPattern: String, + val status: String, + val configurations: Option[Vector[Configuration]], + val logging: UpdateLogging +) +final class PublishConfiguration( + val ivyFile: Option[File], + val resolverName: String, + val artifacts: Map[Artifact, File], + val checksums: Vector[String], + val logging: UpdateLogging, + val overwrite: Boolean +) { + def this( + ivyFile: Option[File], + resolverName: String, + artifacts: Map[Artifact, File], + checksums: Vector[String], + logging: UpdateLogging + ) = this(ivyFile, resolverName, artifacts, checksums, logging, false) } -final case class MakePomConfiguration(file: File, moduleInfo: ModuleInfo, configurations: Option[Vector[Configuration]] = None, extra: NodeSeq = NodeSeq.Empty, process: XNode => XNode = n => n, filterRepositories: MavenRepository => Boolean = _ => true, allRepositories: Boolean, includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType)) +final case class MakePomConfiguration( + file: File, + moduleInfo: ModuleInfo, + configurations: Option[Vector[Configuration]] = None, + extra: NodeSeq = NodeSeq.Empty, + process: XNode => XNode = n => n, + filterRepositories: MavenRepository => Boolean = _ => true, + allRepositories: Boolean, + includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType) +) + /** @param exclude is a map from ModuleID to classifiers that were previously tried and failed, so should now be excluded */ -final case class GetClassifiersConfiguration(module: GetClassifiersModule, exclude: Map[ModuleID, Set[String]], configuration: UpdateConfiguration, ivyScala: Option[IvyScala], sourceArtifactTypes: Set[String], docArtifactTypes: Set[String]) -final case class GetClassifiersModule(id: ModuleID, modules: Vector[ModuleID], configurations: Vector[Configuration], classifiers: Vector[String]) +final case class GetClassifiersConfiguration( + module: GetClassifiersModule, + exclude: Map[ModuleID, Set[String]], + configuration: UpdateConfiguration, + ivyScala: Option[IvyScala], + sourceArtifactTypes: Set[String], + docArtifactTypes: Set[String] +) +final case class GetClassifiersModule( + id: ModuleID, + modules: Vector[ModuleID], + configurations: Vector[Configuration], + classifiers: Vector[String] +) final class UnresolvedWarningConfiguration private[sbt] ( - val modulePositions: Map[ModuleID, SourcePosition] + val modulePositions: Map[ModuleID, SourcePosition] ) object UnresolvedWarningConfiguration { def apply(): UnresolvedWarningConfiguration = apply(Map()) @@ -43,6 +87,7 @@ object UnresolvedWarningConfiguration { } object IvyActions { + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { module.withModule(log) { (ivy, md, default) => @@ -73,27 +118,48 @@ object IvyActions { /** Creates a Maven pom from the given Ivy configuration*/ def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): Unit = { - import configuration.{ allRepositories, moduleInfo, configurations, extra, file, filterRepositories, process, includeTypes } + import configuration.{ + allRepositories, + moduleInfo, + configurations, + extra, + file, + filterRepositories, + process, + includeTypes + } module.withModule(log) { (ivy, md, default) => - (new MakePom(log)).write(ivy, md, moduleInfo, configurations, includeTypes, extra, process, filterRepositories, allRepositories, file) + (new MakePom(log)).write( + ivy, + md, + moduleInfo, + configurations, + includeTypes, + extra, + process, + filterRepositories, + allRepositories, + file + ) log.info("Wrote " + file.getAbsolutePath) } } - def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = - { - import configuration._ - module.withModule(log) { - case (ivy, md, default) => - val revID = md.getModuleRevisionId - val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(IvySbt.getConfigurations(md, configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) - deliveredFile(ivy, deliverIvyPattern, md) - } + def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = { + import configuration._ + module.withModule(log) { + case (ivy, md, default) => + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(IvySbt.getConfigurations(md, configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } + } def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = - ivy.getSettings.resolveFile(IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId)) + ivy.getSettings.resolveFile( + IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId) + ) def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger): Unit = { import configuration._ @@ -101,40 +167,59 @@ object IvyActions { case (ivy, md, default) => val resolver = ivy.getSettings.getResolver(resolverName) if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") - val ivyArtifact = ivyFile map { file => (MDArtifact.newIvyArtifact(md), file) } + val ivyArtifact = ivyFile map { file => + (MDArtifact.newIvyArtifact(md), file) + } val cross = crossVersionMap(module.moduleSettings) val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } } } - private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])(act: => T): T = + private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])( + act: => T + ): T = resolver match { case br: BasicResolver => withChecksums(br, checksums)(act); case _ => act } - private[this] def withChecksums[T](resolver: BasicResolver, checksums: Vector[String])(act: => T): T = - { - val previous = resolver.getChecksumAlgorithms - resolver.setChecksums(checksums mkString ",") - try { act } - finally { resolver.setChecksums(previous mkString ",") } - } + private[this] def withChecksums[T](resolver: BasicResolver, checksums: Vector[String])( + act: => T + ): T = { + val previous = resolver.getChecksumAlgorithms + resolver.setChecksums(checksums mkString ",") + try { act } finally { resolver.setChecksums(previous mkString ",") } + } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) case _ => None } - def mapArtifacts(module: ModuleDescriptor, cross: Option[String => String], artifacts: Map[Artifact, File]): Vector[(IArtifact, File)] = - { - val rawa = artifacts.keys.toVector - val seqa = CrossVersion.substituteCross(rawa, cross) - val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) - zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } - } + def mapArtifacts( + module: ModuleDescriptor, + cross: Option[String => String], + artifacts: Map[Artifact, File] + ): Vector[(IArtifact, File)] = { + val rawa = artifacts.keys.toVector + val seqa = CrossVersion.substituteCross(rawa, cross) + val zipped = rawa zip IvySbt.mapArtifacts(module, seqa) + zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } + } + /** * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ @deprecated("This is no longer public.", "0.13.6") - def update(module: IvySbt#Module, configuration: UpdateConfiguration, log: Logger): UpdateReport = - updateEither(module, configuration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { + def update( + module: IvySbt#Module, + configuration: UpdateConfiguration, + log: Logger + ): UpdateReport = + updateEither( + module, + configuration, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + None, + log + ) match { case Right(r) => r case Left(w) => throw w.resolveException @@ -144,10 +229,17 @@ object IvyActions { * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. */ - private[sbt] def updateEither(module: IvySbt#Module, configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): Either[UnresolvedWarning, UpdateReport] = + private[sbt] def updateEither( + module: IvySbt#Module, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + logicalClock: LogicalClock, + depDir: Option[File], + log: Logger + ): Either[UnresolvedWarning, UpdateReport] = module.withModule(log) { - case (ivy, md, default) if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined => + case (ivy, md, default) + if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined => ivy.getResolveEngine match { case x: CachedResolutionResolveEngine => val iw = IvySbt.inconsistentDuplicateWarning(md) @@ -157,7 +249,16 @@ object IvyActions { resolveOptions.setResolveId(resolveId) resolveOptions.setArtifactFilter(configuration.artifactFilter) resolveOptions.setLog(ivyLogLevel(configuration.logging)) - x.customResolve(md, configuration.missingOk, logicalClock, resolveOptions, depDir getOrElse { sys.error("dependency base directory is not specified") }, log) match { + x.customResolve( + md, + configuration.missingOk, + logicalClock, + resolveOptions, + depDir getOrElse { + sys.error("dependency base directory is not specified") + }, + log + ) match { case Left(x) => Left(UnresolvedWarning(x, uwconfig)) case Right(uReport) => @@ -170,12 +271,14 @@ object IvyActions { case (ivy, md, default) => val iw = IvySbt.inconsistentDuplicateWarning(md) iw foreach { log.warn(_) } - val (report, err) = resolve(configuration.logging)(ivy, md, default, configuration.artifactFilter) + val (report, err) = + resolve(configuration.logging)(ivy, md, default, configuration.artifactFilter) err match { case Some(x) if !configuration.missingOk => Left(UnresolvedWarning(x, uwconfig)) case _ => - val cachedDescriptor = ivy.getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md.getModuleRevisionId) + val cachedDescriptor = ivy.getSettings.getResolutionCacheManager + .getResolvedIvyFileInCache(md.getModuleRevisionId) val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) configuration.retrieve match { case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) @@ -185,11 +288,14 @@ object IvyActions { } @deprecated("No longer used.", "0.13.6") def processUnresolved(err: ResolveException, log: Logger): Unit = () - def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)(report: UpdateReport): Map[T, Set[String]] = + def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)( + report: UpdateReport + ): Map[T, Set[String]] = report.configurations.flatMap { confReport => val evicted = confReport.evicted.filter(moduleFilter) val evictedSet = evicted.map(m => (m.organization, m.name)).toSet - val conflicted = confReport.allModules.filter(mod => evictedSet((mod.organization, mod.name))) + val conflicted = + confReport.allModules.filter(mod => evictedSet((mod.organization, mod.name))) grouped(grouping)(conflicted ++ evicted) }.toMap @@ -197,27 +303,59 @@ object IvyActions { mods groupBy (grouping) mapValues (_.map(_.revision).toSet) @deprecated("This is no longer public.", "0.13.6") - def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - transitiveScratch(ivySbt, label, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) + def transitiveScratch( + ivySbt: IvySbt, + label: String, + config: GetClassifiersConfiguration, + log: Logger + ): UpdateReport = + transitiveScratch( + ivySbt, + label, + config, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + None, + log + ) - private[sbt] def transitiveScratch(ivySbt: IvySbt, label: String, config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], log: Logger): UpdateReport = - { - import config.{ configuration => c, ivyScala, module => mod } - import mod.{ id, modules => deps } - val base = restrictedCopy(id, true).withName(id.name + "$" + label) - val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps)) - val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { - case Right(r) => r - case Left(w) => - throw w.resolveException - } - val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) + private[sbt] def transitiveScratch( + ivySbt: IvySbt, + label: String, + config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, + logicalClock: LogicalClock, + depDir: Option[File], + log: Logger + ): UpdateReport = { + import config.{ configuration => c, ivyScala, module => mod } + import mod.{ id, modules => deps } + val base = restrictedCopy(id, true).withName(id.name + "$" + label) + val module = + new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps)) + val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { + case Right(r) => r + case Left(w) => + throw w.resolveException } + val newConfig = config.copy(module = mod.copy(modules = report.allModules)) + updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) + } @deprecated("This is no longer public.", "0.13.6") - def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, log: Logger): UpdateReport = - updateClassifiers(ivySbt, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) + def updateClassifiers( + ivySbt: IvySbt, + config: GetClassifiersConfiguration, + log: Logger + ): UpdateReport = + updateClassifiers( + ivySbt, + config, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + None, + Vector(), + log + ) /** * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This @@ -228,64 +366,83 @@ object IvyActions { * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to * "classified" artifacts (sources and javadocs). */ - private[sbt] def updateClassifiers(ivySbt: IvySbt, config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, logicalClock: LogicalClock, depDir: Option[File], - artifacts: Vector[(String, ModuleID, Artifact, File)], - log: Logger): UpdateReport = - { - import config.{ configuration => c, module => mod, _ } - import mod.{ configurations => confs, _ } - assert(classifiers.nonEmpty, "classifiers cannot be empty") - assert(c.artifactFilter.types.nonEmpty, "UpdateConfiguration must filter on some types") - val baseModules = modules map { m => restrictedCopy(m, true) } - // Adding list of explicit artifacts here. - val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) - val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", "")) - val module = new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps).withConfigurations(confs)) - // c.copy ensures c.types is preserved too - val upConf = c.withMissingOk(true) - updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { - case Right(r) => - // The artifacts that came from Ivy don't have their classifier set, let's set it according to - // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They - val typeClassifierMap: Map[String, String] = - ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) - :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap - r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { - case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f - } - } - case Left(w) => - throw w.resolveException - } + private[sbt] def updateClassifiers( + ivySbt: IvySbt, + config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, + logicalClock: LogicalClock, + depDir: Option[File], + artifacts: Vector[(String, ModuleID, Artifact, File)], + log: Logger + ): UpdateReport = { + import config.{ configuration => c, module => mod, _ } + import mod.{ configurations => confs, _ } + assert(classifiers.nonEmpty, "classifiers cannot be empty") + assert(c.artifactFilter.types.nonEmpty, "UpdateConfiguration must filter on some types") + val baseModules = modules map { m => + restrictedCopy(m, true) } + // Adding list of explicit artifacts here. + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) + val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", "")) + val module = new ivySbt.Module( + InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps) + .withConfigurations(confs) + ) + // c.copy ensures c.types is preserved too + val upConf = c.withMissingOk(true) + updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { + case Right(r) => + // The artifacts that came from Ivy don't have their classifier set, let's set it according to + // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They + val typeClassifierMap: Map[String, String] = + ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) + :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap + r.substitute { (conf, mid, artFileSeq) => + artFileSeq map { + case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + } + } + case Left(w) => + throw w.resolveException + } + } // This version adds explicit artifact private[sbt] def classifiedArtifacts( - classifiers: Vector[String], - exclude: Map[ModuleID, Set[String]], - artifacts: Vector[(String, ModuleID, Artifact, File)] + classifiers: Vector[String], + exclude: Map[ModuleID, Set[String]], + artifacts: Vector[(String, ModuleID, Artifact, File)] )(m: ModuleID): Option[ModuleID] = { - def sameModule(m1: ModuleID, m2: ModuleID): Boolean = m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision - def explicitArtifacts = - { - val arts = (artifacts collect { case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art }).distinct - if (arts.isEmpty) None - else Some(intransitiveModuleWithExplicitArts(m, arts)) - } + def sameModule(m1: ModuleID, m2: ModuleID): Boolean = + m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision + def explicitArtifacts = { + val arts = (artifacts collect { + case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art + }).distinct + if (arts.isEmpty) None + else Some(intransitiveModuleWithExplicitArts(m, arts)) + } def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) explicitArtifacts orElse hardcodedArtifacts } - private def classifiedArtifacts(classifiers: Vector[String], exclude: Map[ModuleID, Set[String]])(m: ModuleID): Option[ModuleID] = - { - val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) - val included = classifiers filterNot excluded - if (included.isEmpty) None else { - Some(intransitiveModuleWithExplicitArts(module = m, arts = classifiedArtifacts(m.name, included))) - } + private def classifiedArtifacts( + classifiers: Vector[String], + exclude: Map[ModuleID, Set[String]] + )(m: ModuleID): Option[ModuleID] = { + val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) + val included = classifiers filterNot excluded + if (included.isEmpty) None + else { + Some( + intransitiveModuleWithExplicitArts( + module = m, + arts = classifiedArtifacts(m.name, included) + ) + ) } + } /** * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, @@ -300,93 +457,170 @@ object IvyActions { * }}} * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. */ - private def intransitiveModuleWithExplicitArts(module: ModuleID, arts: Vector[Artifact]): ModuleID = - module.withIsTransitive(false).withExplicitArtifacts(arts).withInclusions(Vector(InclExclRule.everything)) + private def intransitiveModuleWithExplicitArts( + module: ModuleID, + arts: Vector[Artifact] + ): ModuleID = + module + .withIsTransitive(false) + .withExplicitArtifacts(arts) + .withInclusions(Vector(InclExclRule.everything)) - def addExcluded(report: UpdateReport, classifiers: Vector[String], exclude: Map[ModuleID, Set[String]]): UpdateReport = - report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } + def addExcluded( + report: UpdateReport, + classifiers: Vector[String], + exclude: Map[ModuleID, Set[String]] + ): UpdateReport = + report.addMissing { id => + classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) + } def classifiedArtifacts(name: String, classifiers: Vector[String]): Vector[Artifact] = - classifiers map { c => Artifact.classified(name, c) } + classifiers map { c => + Artifact.classified(name, c) + } private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { case (_, mod, art) => art.classifier.map { c => (restrictedCopy(mod, false), c) } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } + report.allMissing flatMap { + case (_, mod, art) => + art.classifier.map { c => + (restrictedCopy(mod, false), c) + } + } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision).withCrossVersion(m.crossVersion).withExtraAttributes(m.extraAttributes).withConfigurations(if (confs) m.configurations else None) + ModuleID(m.organization, m.name, m.revision) + .withCrossVersion(m.crossVersion) + .withExtraAttributes(m.extraAttributes) + .withConfigurations(if (confs) m.configurations else None) .branch(m.branchName) - private[this] def resolve(logging: UpdateLogging)(ivy: Ivy, module: DefaultModuleDescriptor, defaultConf: String, filter: ArtifactTypeFilter): (ResolveReport, Option[ResolveException]) = - { - val resolveOptions = new ResolveOptions - val resolveId = ResolveOptions.getDefaultResolveId(module) - resolveOptions.setResolveId(resolveId) - resolveOptions.setArtifactFilter(filter) - resolveOptions.setLog(ivyLogLevel(logging)) - ResolutionCache.cleanModule(module.getModuleRevisionId, resolveId, ivy.getSettings.getResolutionCacheManager) - val resolveReport = ivy.resolve(module, resolveOptions) - val err = - if (resolveReport.hasError) { - val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct - val failedPaths = Map(resolveReport.getUnresolvedDependencies map { node => - val m = IvyRetrieve.toModuleID(node.getId) - val path = IvyRetrieve.findPath(node, module.getModuleRevisionId) map { x => - IvyRetrieve.toModuleID(x.getId) - } - m -> path - }: _*) - val failed = failedPaths.keys.toSeq - Some(new ResolveException(messages, failed, failedPaths)) - } else None - (resolveReport, err) + private[this] def resolve(logging: UpdateLogging)( + ivy: Ivy, + module: DefaultModuleDescriptor, + defaultConf: String, + filter: ArtifactTypeFilter + ): (ResolveReport, Option[ResolveException]) = { + val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(module) + resolveOptions.setResolveId(resolveId) + resolveOptions.setArtifactFilter(filter) + resolveOptions.setLog(ivyLogLevel(logging)) + ResolutionCache.cleanModule( + module.getModuleRevisionId, + resolveId, + ivy.getSettings.getResolutionCacheManager + ) + val resolveReport = ivy.resolve(module, resolveOptions) + val err = + if (resolveReport.hasError) { + val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct + val failedPaths = Map(resolveReport.getUnresolvedDependencies map { node => + val m = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve.findPath(node, module.getModuleRevisionId) map { x => + IvyRetrieve.toModuleID(x.getId) + } + m -> path + }: _*) + val failed = failedPaths.keys.toSeq + Some(new ResolveException(messages, failed, failedPaths)) + } else None + (resolveReport, err) + } + private def retrieve( + log: Logger, + ivy: Ivy, + report: UpdateReport, + config: RetrieveConfiguration + ): UpdateReport = + retrieve( + log, + ivy, + report, + config.retrieveDirectory, + config.outputPattern, + config.sync, + config.configurationsToRetrieve + ) + + private def retrieve( + log: Logger, + ivy: Ivy, + report: UpdateReport, + base: File, + pattern: String, + sync: Boolean, + configurationsToRetrieve: Option[Set[Configuration]] + ): UpdateReport = { + val configurationNames = configurationsToRetrieve match { + case None => None + case Some(configs) => Some(configs.map(_.name)) } - private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration): UpdateReport = - retrieve(log, ivy, report, config.retrieveDirectory, config.outputPattern, config.sync, config.configurationsToRetrieve) - - private def retrieve(log: Logger, ivy: Ivy, report: UpdateReport, base: File, pattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[Configuration]]): UpdateReport = - { - val configurationNames = configurationsToRetrieve match { - case None => None - case Some(configs) => Some(configs.map(_.name)) + val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } + val toCopy = new collection.mutable.HashSet[(File, File)] + val retReport = report retrieve { (conf, mid, art, cached) => + configurationNames match { + case None => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + case Some(names) if names(conf) => + performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + case _ => cached } - val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } - val toCopy = new collection.mutable.HashSet[(File, File)] - val retReport = report retrieve { (conf, mid, art, cached) => - configurationNames match { - case None => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) - case Some(names) if names(conf) => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) - case _ => cached - } + } + IO.copy(toCopy) + val resolvedFiles = toCopy.map(_._2) + if (sync) { + val filesToDelete = existingFiles.filterNot(resolvedFiles.contains) + filesToDelete foreach { f => + log.info(s"Deleting old dependency: ${f.getAbsolutePath}") + f.delete() } - IO.copy(toCopy) - val resolvedFiles = toCopy.map(_._2) - if (sync) { - val filesToDelete = existingFiles.filterNot(resolvedFiles.contains) - filesToDelete foreach { f => - log.info(s"Deleting old dependency: ${f.getAbsolutePath}") - f.delete() - } - } - - retReport } - private def performRetrieve(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String, cached: File, toCopy: collection.mutable.HashSet[(File, File)]): File = { + retReport + } + + private def performRetrieve( + conf: String, + mid: ModuleID, + art: Artifact, + base: File, + pattern: String, + cached: File, + toCopy: collection.mutable.HashSet[(File, File)] + ): File = { val to = retrieveTarget(conf, mid, art, base, pattern) toCopy += ((cached, to)) to } - private def retrieveTarget(conf: String, mid: ModuleID, art: Artifact, base: File, pattern: String): File = + private def retrieveTarget( + conf: String, + mid: ModuleID, + art: Artifact, + base: File, + pattern: String + ): File = new File(base, substitute(conf, mid, art, pattern)) - private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = - { - val mextra = IvySbt.javaMap(mid.extraAttributes, true) - val aextra = IvySbt.extra(art, true) - IvyPatternHelper.substitute(pattern, mid.organization, mid.name, mid.branchName.orNull, mid.revision, art.name, art.`type`, art.extension, conf, null, mextra, aextra) - } + private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = { + val mextra = IvySbt.javaMap(mid.extraAttributes, true) + val aextra = IvySbt.extra(art, true) + IvyPatternHelper.substitute( + pattern, + mid.organization, + mid.name, + mid.branchName.orNull, + mid.revision, + art.name, + art.`type`, + art.extension, + conf, + null, + mextra, + aextra + ) + } import UpdateLogging.{ Quiet, Full, DownloadOnly, Default } import LogOptions.{ LOG_QUIET, LOG_DEFAULT, LOG_DOWNLOAD_ONLY } @@ -398,46 +632,57 @@ object IvyActions { case Default => LOG_DOWNLOAD_ONLY } - def publish(module: ModuleDescriptor, artifacts: Seq[(IArtifact, File)], resolver: DependencyResolver, overwrite: Boolean): Unit = - { - if (artifacts.nonEmpty) { - checkFilesPresent(artifacts) - try { - resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - for ((artifact, file) <- artifacts) - resolver.publish(artifact, file, overwrite) - resolver.commitPublishTransaction() - } catch { - case e: Throwable => - try { resolver.abortPublishTransaction() } - finally { throw e } - } + def publish( + module: ModuleDescriptor, + artifacts: Seq[(IArtifact, File)], + resolver: DependencyResolver, + overwrite: Boolean + ): Unit = { + if (artifacts.nonEmpty) { + checkFilesPresent(artifacts) + try { + resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); + for ((artifact, file) <- artifacts) + resolver.publish(artifact, file, overwrite) + resolver.commitPublishTransaction() + } catch { + case e: Throwable => + try { resolver.abortPublishTransaction() } finally { throw e } } } + } private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]): Unit = { val missing = artifacts filter { case (a, file) => !file.exists } if (missing.nonEmpty) - sys.error("Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t")) + sys.error( + "Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t") + ) } } final class ResolveException( - val messages: Seq[String], - val failed: Seq[ModuleID], - val failedPaths: Map[ModuleID, Seq[ModuleID]] + val messages: Seq[String], + val failed: Seq[ModuleID], + val failedPaths: Map[ModuleID, Seq[ModuleID]] ) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = - this(messages, failed, Map(failed map { m => m -> Nil }: _*)) + this(messages, failed, Map(failed map { m => + m -> Nil + }: _*)) } + /** * Represents unresolved dependency warning, which displays reconstructed dependency tree * along with source position of each node. */ final class UnresolvedWarning private[sbt] ( - val resolveException: ResolveException, - val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] + val resolveException: ResolveException, + val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] ) object UnresolvedWarning { - private[sbt] def apply(err: ResolveException, config: UnresolvedWarningConfiguration): UnresolvedWarning = { + private[sbt] def apply( + err: ResolveException, + config: UnresolvedWarningConfiguration + ): UnresolvedWarning = { def modulePosition(m0: ModuleID): Option[SourcePosition] = config.modulePositions.find { case (m, p) => @@ -454,20 +699,25 @@ object UnresolvedWarning { } apply(err, failedPaths) } - private[sbt] def apply(err: ResolveException, failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]]): UnresolvedWarning = + private[sbt] def apply( + err: ResolveException, + failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] + ): UnresolvedWarning = new UnresolvedWarning(err, failedPaths) private[sbt] def sourcePosStr(posOpt: Option[SourcePosition]): String = posOpt match { - case Some(LinePosition(path, start)) => s" ($path#L$start)" + case Some(LinePosition(path, start)) => s" ($path#L$start)" case Some(RangePosition(path, LineRange(start, end))) => s" ($path#L$start-$end)" - case _ => "" + case _ => "" } implicit val unresolvedWarningLines: ShowLines[UnresolvedWarning] = ShowLines { a => val withExtra = a.resolveException.failed.filter(_.extraDependencyAttributes.nonEmpty) val buffer = mutable.ListBuffer[String]() if (withExtra.nonEmpty) { buffer += "\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes." - withExtra foreach { id => buffer += "\t\t" + id } + withExtra foreach { id => + buffer += "\t\t" + id + } } if (a.failedPaths.nonEmpty) { buffer += "\n\tNote: Unresolved dependencies path:" diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index ae7d01275..c697b639f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -5,7 +5,11 @@ package sbt.internal.librarymanagement import java.io.File -import org.apache.ivy.core.cache.{ ArtifactOrigin, CacheDownloadOptions, DefaultRepositoryCacheManager } +import org.apache.ivy.core.cache.{ + ArtifactOrigin, + CacheDownloadOptions, + DefaultRepositoryCacheManager +} import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact, DefaultArtifact } import org.apache.ivy.plugins.repository.file.{ FileRepository => IvyFileRepository, FileResource } import org.apache.ivy.plugins.repository.{ ArtifactResourceResolver, Resource, ResourceDownloader } @@ -20,36 +24,46 @@ import scala.collection.mutable import jawn.{ SupportParser, MutableFacade } class NotInCache(val id: ModuleID, cause: Throwable) - extends RuntimeException(NotInCache(id, cause), cause) { + extends RuntimeException(NotInCache(id, cause), cause) { def this(id: ModuleID) = this(id, null) } private object NotInCache { - def apply(id: ModuleID, cause: Throwable) = - { - val postfix = if (cause == null) "" else (": " + cause.toString) - "File for " + id + " not in cache" + postfix - } + def apply(id: ModuleID, cause: Throwable) = { + val postfix = if (cause == null) "" else (": " + cause.toString) + "File for " + id + " not in cache" + postfix + } } + /** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { val artifact = defaultArtifact(moduleID) - val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) + val resolved = + new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) withDefaultCache(lock, log) { cache => val resolver = new ArtifactResourceResolver { def resolve(artifact: IvyArtifact) = resolved } cache.download(artifact, resolver, new FileDownloader, new CacheDownloadOptions) () } } + /** Clears the cache of the jar for the given ID.*/ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { - try { withCachedJar(id, lock, log)(_.delete); () } - catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } + try { withCachedJar(id, lock, log)(_.delete); () } catch { + case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) + } } + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ - def retrieveCachedJar(id: ModuleID, toDirectory: File, lock: Option[xsbti.GlobalLock], log: Logger) = + def retrieveCachedJar( + id: ModuleID, + toDirectory: File, + lock: Option[xsbti.GlobalLock], + log: Logger + ) = withCachedJar(id, lock, log) { cachedFile => val copyTo = new File(toDirectory, cachedFile.getName) FileUtil.copy(cachedFile, copyTo, null) @@ -57,41 +71,58 @@ class IvyCache(val ivyHome: Option[File]) { } /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ - def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)(f: File => T): T = - { - val cachedFile = - try { - withDefaultCache(lock, log) { cache => - val artifact = defaultArtifact(id) - cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) - } - } catch { case e: Exception => throw new NotInCache(id, e) } + def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)( + f: File => T + ): T = { + val cachedFile = + try { + withDefaultCache(lock, log) { cache => + val artifact = defaultArtifact(id) + cache.getArchiveFileInCache(artifact, unknownOrigin(artifact)) + } + } catch { case e: Exception => throw new NotInCache(id, e) } + + if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) + } - if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) - } /** Calls the given function with the default Ivy cache.*/ - def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)(f: DefaultRepositoryCacheManager => T): T = - { - val (ivy, _) = basicLocalIvy(lock, log) - ivy.withIvy(log) { ivy => - val cache = ivy.getSettings.getDefaultRepositoryCacheManager.asInstanceOf[DefaultRepositoryCacheManager] - cache.setUseOrigin(false) - f(cache) - } + def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)( + f: DefaultRepositoryCacheManager => T + ): T = { + val (ivy, _) = basicLocalIvy(lock, log) + ivy.withIvy(log) { ivy => + val cache = ivy.getSettings.getDefaultRepositoryCacheManager + .asInstanceOf[DefaultRepositoryCacheManager] + cache.setUseOrigin(false) + f(cache) } + } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ - private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = - { - val local = Resolver.defaultLocal - val paths = IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, lock, IvySbt.DefaultChecksums, None, UpdateOptions(), log) - (new IvySbt(conf), local) - } + private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { + val local = Resolver.defaultLocal + val paths = IvyPaths(new File("."), ivyHome) + val conf = new InlineIvyConfiguration( + paths, + Vector(local), + Vector.empty, + Vector.empty, + false, + lock, + IvySbt.DefaultChecksums, + None, + UpdateOptions(), + log + ) + (new IvySbt(conf), local) + } + /** Creates a default jar artifact based on the given ID.*/ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } + /** Required by Ivy for copying to the cache.*/ private class FileDownloader extends ResourceDownloader { def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 74bdde758..71c527322 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -6,11 +6,15 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ abstract class InlineConfigurationFunctions { - def configurations(explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration]) = + def configurations( + explicitConfigurations: Iterable[Configuration], + defaultConfiguration: Option[Configuration] + ) = if (explicitConfigurations.isEmpty) { defaultConfiguration match { case Some(Configurations.DefaultIvyConfiguration) => Configurations.Default :: Nil - case Some(Configurations.DefaultMavenConfiguration) => Configurations.defaultMavenConfigurations + case Some(Configurations.DefaultMavenConfiguration) => + Configurations.defaultMavenConfigurations case _ => Nil } } else diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index 028306694..f178a95f0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -44,6 +44,7 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def setShowProgress(progress: Boolean): Unit = () } private final class SbtMessageLoggerEngine extends MessageLoggerEngine { + /** This is a hack to filter error messages about 'unknown resolver ...'. */ override def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) super.error(msg) override def sumupProblems(): Unit = clearProblems() diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index fa55c51e3..d76f7556d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -21,39 +21,48 @@ object IvyRetrieve { def moduleReports(confReport: ConfigurationResolveReport): Vector[ModuleReport] = for { - revId <- confReport.getModuleRevisionIds.toArray.toVector collect { case revId: ModuleRevisionId => revId } + revId <- confReport.getModuleRevisionIds.toArray.toVector collect { + case revId: ModuleRevisionId => revId + } } yield moduleRevisionDetail(confReport, confReport.getDependency(revId)) @deprecated("Internal only. No longer in use.", "0.13.6") - def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = - { - val (resolved, missing) = artifacts(mid, artReport) - ModuleReport(mid, resolved, missing) - } + def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = { + val (resolved, missing) = artifacts(mid, artReport) + ModuleReport(mid, resolved, missing) + } - private[sbt] def artifacts(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): (Vector[(Artifact, File)], Vector[Artifact]) = - { - val missing = new mutable.ListBuffer[Artifact] - val resolved = new mutable.ListBuffer[(Artifact, File)] - for (r <- artReport) { - val fileOpt = Option(r.getLocalFile) - val art = toArtifact(r.getArtifact) - fileOpt match { - case Some(file) => resolved += ((art, file)) - case None => missing += art - } + private[sbt] def artifacts( + mid: ModuleID, + artReport: Seq[ArtifactDownloadReport] + ): (Vector[(Artifact, File)], Vector[Artifact]) = { + val missing = new mutable.ListBuffer[Artifact] + val resolved = new mutable.ListBuffer[(Artifact, File)] + for (r <- artReport) { + val fileOpt = Option(r.getLocalFile) + val art = toArtifact(r.getArtifact) + fileOpt match { + case Some(file) => resolved += ((art, file)) + case None => missing += art } - (resolved.toVector, missing.toVector) } + (resolved.toVector, missing.toVector) + } // We need this because current module report used as part of UpdateReport/ConfigurationReport contains // only the revolved modules. // Sometimes the entire module can be excluded via rules etc. - private[sbt] def organizationArtifactReports(confReport: ConfigurationResolveReport): Vector[OrganizationArtifactReport] = { - val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => mId } + private[sbt] def organizationArtifactReports( + confReport: ConfigurationResolveReport + ): Vector[OrganizationArtifactReport] = { + val moduleIds = confReport.getModuleIds.toArray.toVector collect { + case mId: IvyModuleId => mId + } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } - OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { moduleRevisionDetail(confReport, _) }) + OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { + moduleRevisionDetail(confReport, _) + }) } moduleIds map { organizationArtifact } } @@ -65,10 +74,16 @@ object IvyRetrieve { case x => Some(x.trim) } - private[sbt] def moduleRevisionDetail(confReport: ConfigurationResolveReport, dep: IvyNode): ModuleReport = { + private[sbt] def moduleRevisionDetail( + confReport: ConfigurationResolveReport, + dep: IvyNode + ): ModuleReport = { def toExtraAttributes(ea: ju.Map[_, _]): Map[String, String] = Map(ea.entrySet.toArray collect { - case entry: ju.Map.Entry[_, _] if nonEmptyString(entry.getKey.toString).isDefined && nonEmptyString(entry.getValue.toString).isDefined => + case entry: ju.Map.Entry[_, _] + if nonEmptyString(entry.getKey.toString).isDefined && nonEmptyString( + entry.getValue.toString + ).isDefined => (entry.getKey.toString, entry.getValue.toString) }: _*) def toCaller(caller: IvyCaller): Caller = { @@ -80,11 +95,32 @@ object IvyRetrieve { val (extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) = ddOpt match { case Some(dd: SbtDefaultDependencyDescriptor) => val mod = dd.dependencyModuleId - (toExtraAttributes(dd.getExtraAttributes), mod.isForce, mod.isChanging, mod.isTransitive, mod.isForce) - case Some(dd) => (toExtraAttributes(dd.getExtraAttributes), dd.isForce, dd.isChanging, dd.isTransitive, false) - case None => (Map.empty[String, String], false, false, true, false) + ( + toExtraAttributes(dd.getExtraAttributes), + mod.isForce, + mod.isChanging, + mod.isTransitive, + mod.isForce + ) + case Some(dd) => + ( + toExtraAttributes(dd.getExtraAttributes), + dd.isForce, + dd.isChanging, + dd.isTransitive, + false + ) + case None => (Map.empty[String, String], false, false, true, false) } - Caller(m, callerConfigurations, extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) + Caller( + m, + callerConfigurations, + extraAttributes, + isForce, + isChanging, + isTransitive, + isDirectlyForce + ) } val revId = dep.getResolvedId val moduleId = toModuleID(revId) @@ -106,9 +142,9 @@ object IvyRetrieve { val edOpt = Option(dep.getEvictedData(confReport.getConfiguration)) edOpt match { case Some(ed) => - (true, - nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { "transitive" }), - nonEmptyString(ed.getDetail)) + (true, nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { + "transitive" + }), nonEmptyString(ed.getDetail)) case None => (true, None, None) } case _ => (false, None, None) @@ -133,40 +169,74 @@ object IvyRetrieve { val isDefault = Option(dep.getDescriptor) map { _.isDefault } val configurations = dep.getConfigurations(confReport.getConfiguration).toVector val licenses: Vector[(String, Option[String])] = mdOpt match { - case Some(md) => md.getLicenses.toVector collect { - case lic: IvyLicense if Option(lic.getName).isDefined => - val temporaryURL = "http://localhost" - (lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) }) - } + case Some(md) => + md.getLicenses.toVector collect { + case lic: IvyLicense if Option(lic.getName).isDefined => + val temporaryURL = "http://localhost" + (lic.getName, nonEmptyString(lic.getUrl) orElse { Some(temporaryURL) }) + } case _ => Vector.empty } val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) - ModuleReport(moduleId, resolved, missing, status, publicationDate, resolver, artifactResolver, - evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, - configurations, licenses, callers) + ModuleReport( + moduleId, + resolved, + missing, + status, + publicationDate, + resolver, + artifactResolver, + evicted, + evictedData, + evictedReason, + problem, + homepage, + extraAttributes, + isDefault, + branch, + configurations, + licenses, + callers + ) } def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = confReport.getEvictedNodes.map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = - ModuleID(revID.getOrganisation, revID.getName, revID.getRevision).withExtraAttributes(IvySbt.getExtraAttributes(revID)) + ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) + .withExtraAttributes(IvySbt.getExtraAttributes(revID)) .branch(nonEmptyString(revID.getBranch)) - def toArtifact(art: IvyArtifact): Artifact = - { - import art._ - Artifact(getName, getType, getExt, Option(getExtraAttribute("classifier")), getConfigurations.toVector map Configurations.config, Option(getUrl)) - } + def toArtifact(art: IvyArtifact): Artifact = { + import art._ + Artifact( + getName, + getType, + getExt, + Option(getExtraAttribute("classifier")), + getConfigurations.toVector map Configurations.config, + Option(getUrl) + ) + } def updateReport(report: ResolveReport, cachedDescriptor: File): UpdateReport = - UpdateReport(cachedDescriptor, reports(report) map configurationReport, updateStats(report), Map.empty) recomputeStamps () + UpdateReport( + cachedDescriptor, + reports(report) map configurationReport, + updateStats(report), + Map.empty + ) recomputeStamps () def updateStats(report: ResolveReport): UpdateStats = UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = - ConfigurationReport(confReport.getConfiguration, moduleReports(confReport), organizationArtifactReports(confReport)) + ConfigurationReport( + confReport.getConfiguration, + moduleReports(confReport), + organizationArtifactReports(confReport) + ) /** * Tries to find Ivy graph path the from node to target. diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 55d7dbd6a..19c835393 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -11,36 +11,59 @@ private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" def fakeCallerOrganization = "org.scala-sbt.temp-callers" - def parseUpdateReport(md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger): UpdateReport = - { - try { - val lite = CacheStore(path).read[UpdateReportLite] - fromLite(lite, cachedDescriptor) - } catch { - case e: Throwable => - log.error("Unable to parse mini graph: " + path.toString) - throw e - } - } - def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = - { - sbt.io.IO.createDirectory(graphPath.getParentFile) - CacheStore(graphPath).write(toLite(ur)) + def parseUpdateReport( + md: ModuleDescriptor, + path: File, + cachedDescriptor: File, + log: Logger + ): UpdateReport = { + try { + val lite = CacheStore(path).read[UpdateReportLite] + fromLite(lite, cachedDescriptor) + } catch { + case e: Throwable => + log.error("Unable to parse mini graph: " + path.toString) + throw e } + } + def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { + sbt.io.IO.createDirectory(graphPath.getParentFile) + CacheStore(graphPath).write(toLite(ur)) + } def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => - ConfigurationReportLite(cr.configuration, cr.details map { oar => - OrganizationArtifactReport(oar.organization, oar.name, oar.modules map { mr => - ModuleReport( - mr.module, mr.artifacts, mr.missingArtifacts, mr.status, - mr.publicationDate, mr.resolver, mr.artifactResolver, - mr.evicted, mr.evictedData, mr.evictedReason, - mr.problem, mr.homepage, mr.extraAttributes, - mr.isDefault, mr.branch, mr.configurations, mr.licenses, - filterOutArtificialCallers(mr.callers) - ) - }) - }) + ConfigurationReportLite( + cr.configuration, + cr.details map { + oar => + OrganizationArtifactReport( + oar.organization, + oar.name, + oar.modules map { mr => + ModuleReport( + mr.module, + mr.artifacts, + mr.missingArtifacts, + mr.status, + mr.publicationDate, + mr.resolver, + mr.artifactResolver, + mr.evicted, + mr.evictedData, + mr.evictedReason, + mr.problem, + mr.homepage, + mr.extraAttributes, + mr.isDefault, + mr.branch, + mr.configurations, + mr.licenses, + filterOutArtificialCallers(mr.callers) + ) + } + ) + } + ) }) // #1763/#2030. Caller takes up 97% of space, so we need to shrink it down, // but there are semantics associated with some of them. @@ -49,7 +72,7 @@ private[sbt] object JsonUtil { else { val nonArtificial = callers filter { c => (c.caller.organization != sbtOrgTemp) && - (c.caller.organization != fakeCallerOrganization) + (c.caller.organization != fakeCallerOrganization) } val interProj = (callers find { c => c.caller.organization == sbtOrgTemp @@ -57,18 +80,17 @@ private[sbt] object JsonUtil { interProj ++ nonArtificial } - def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = - { - val stats = UpdateStats(0L, 0L, 0L, false) - val configReports = lite.configurations map { cr => - val details = cr.details - val modules = details flatMap { - _.modules filter { mr => - !mr.evicted && mr.problem.isEmpty - } + def fromLite(lite: UpdateReportLite, cachedDescriptor: File): UpdateReport = { + val stats = UpdateStats(0L, 0L, 0L, false) + val configReports = lite.configurations map { cr => + val details = cr.details + val modules = details flatMap { + _.modules filter { mr => + !mr.evicted && mr.problem.isEmpty } - ConfigurationReport(cr.configuration, modules, details) } - UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + ConfigurationReport(cr.configuration, modules, details) } + UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 5544d0d52..3e30bf85b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -19,35 +19,121 @@ import Configurations.Optional import org.apache.ivy.Ivy import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor, DependencyDescriptor, License, ModuleDescriptor, ExcludeRule } +import org.apache.ivy.core.module.descriptor.{ + DependencyArtifactDescriptor, + DependencyDescriptor, + License, + ModuleDescriptor, + ExcludeRule +} import org.apache.ivy.plugins.resolver.{ ChainResolver, DependencyResolver, IBiblioResolver } import ivyint.CustomRemoteMavenResolver import sbt.io.IO object MakePom { + /** True if the revision is an ivy-range, not a complete revision. */ def isDependencyVersionRange(revision: String): Boolean = VersionRange.isVersionRange(revision) /** Converts Ivy revision ranges to that of Maven POM */ - def makeDependencyVersion(revision: String): String = VersionRange.fromIvyToMavenVersion(revision) + def makeDependencyVersion(revision: String): String = + VersionRange.fromIvyToMavenVersion(revision) } class MakePom(val log: Logger) { import MakePom._ - @deprecated("Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", "0.11.2") - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(ivy, module, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], Set(Artifact.DefaultType), extra, process, filterRepositories, allRepositories, output) - def write(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, process: XNode => XNode, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean, output: File): Unit = - write(process(toPom(ivy, module, moduleInfo, configurations, includeTypes, extra, filterRepositories, allRepositories)), output) + @deprecated( + "Use `write(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, XNode => XNode, MavenRepository => Boolean, Boolean, File)` instead", + "0.11.2" + ) + def write( + ivy: Ivy, + module: ModuleDescriptor, + moduleInfo: ModuleInfo, + configurations: Option[Iterable[Configuration]], + extra: NodeSeq, + process: XNode => XNode, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean, + output: File + ): Unit = + write( + ivy, + module, + moduleInfo: ModuleInfo, + configurations: Option[Iterable[Configuration]], + Set(Artifact.DefaultType), + extra, + process, + filterRepositories, + allRepositories, + output + ) + def write( + ivy: Ivy, + module: ModuleDescriptor, + moduleInfo: ModuleInfo, + configurations: Option[Iterable[Configuration]], + includeTypes: Set[String], + extra: NodeSeq, + process: XNode => XNode, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean, + output: File + ): Unit = + write( + process( + toPom( + ivy, + module, + moduleInfo, + configurations, + includeTypes, + extra, + filterRepositories, + allRepositories + ) + ), + output + ) // use \n as newline because toString uses PrettyPrinter, which hard codes line endings to be \n def write(node: XNode, output: File): Unit = write(toString(node), output, "\n") def write(xmlString: String, output: File, newline: String): Unit = IO.write(output, "" + newline + xmlString) def toString(node: XNode): String = new PrettyPrinter(1000, 4).format(node) - @deprecated("Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", "0.11.2") - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = - toPom(ivy, module, moduleInfo, configurations, Set(Artifact.DefaultType), extra, filterRepositories, allRepositories) - def toPom(ivy: Ivy, module: ModuleDescriptor, moduleInfo: ModuleInfo, configurations: Option[Iterable[Configuration]], includeTypes: Set[String], extra: NodeSeq, filterRepositories: MavenRepository => Boolean, allRepositories: Boolean): XNode = + @deprecated( + "Use `toPom(Ivy, ModuleDescriptor, ModuleInfo, Option[Iterable[Configuration]], Set[String], NodeSeq, MavenRepository => Boolean, Boolean)` instead", + "0.11.2" + ) + def toPom( + ivy: Ivy, + module: ModuleDescriptor, + moduleInfo: ModuleInfo, + configurations: Option[Iterable[Configuration]], + extra: NodeSeq, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean + ): XNode = + toPom( + ivy, + module, + moduleInfo, + configurations, + Set(Artifact.DefaultType), + extra, + filterRepositories, + allRepositories + ) + def toPom( + ivy: Ivy, + module: ModuleDescriptor, + moduleInfo: ModuleInfo, + configurations: Option[Iterable[Configuration]], + includeTypes: Set[String], + extra: NodeSeq, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean + ): XNode = ( 4.0.0 { makeModuleID(module) } @@ -65,81 +151,80 @@ class MakePom(val log: Logger) { { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } ) - def makeModuleID(module: ModuleDescriptor): NodeSeq = - { - val mrid = moduleDescriptor(module) - val a: NodeSeq = - ({ mrid.getOrganisation } - { mrid.getName } - { packaging(module) }) - val b: NodeSeq = - ((description(module.getDescription) ++ - homePage(module.getHomePage) ++ - revision(mrid.getRevision) ++ - licenses(module.getLicenses)): NodeSeq) - a ++ b - } + def makeModuleID(module: ModuleDescriptor): NodeSeq = { + val mrid = moduleDescriptor(module) + val a: NodeSeq = + ({ mrid.getOrganisation } + { mrid.getName } + { packaging(module) }) + val b: NodeSeq = + ((description(module.getDescription) ++ + homePage(module.getHomePage) ++ + revision(mrid.getRevision) ++ + licenses(module.getLicenses)): NodeSeq) + a ++ b + } def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = moduleInfo.startYear match { case Some(y) => { y } case _ => NodeSeq.Empty } - def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = - { - - { moduleInfo.organizationName } + def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = { + + { moduleInfo.organizationName } + { + moduleInfo.organizationHomepage match { + case Some(h)=> { h } + case _ => NodeSeq.Empty + } + } + + } + def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = { + moduleInfo.scmInfo match { + case Some(s) => + + { s.browseUrl } + { s.connection } + { + s.devConnection match { + case Some(d)=> { d } + case _=> NodeSeq.Empty + } + } + + case _ => NodeSeq.Empty + } + } + def makeDeveloperInfo(moduleInfo: ModuleInfo): NodeSeq = { + if (moduleInfo.developers.nonEmpty) { + { - moduleInfo.organizationHomepage match { - case Some(h)=> { h } - case _ => NodeSeq.Empty + moduleInfo.developers.map { developer: Developer => + + { developer.id } + { developer.name } + { developer.email } + { developer.url } + } } - - } - def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = - { - moduleInfo.scmInfo match { - case Some(s) => - - { s.browseUrl } - { s.connection } - { - s.devConnection match { - case Some(d)=> { d } - case _=> NodeSeq.Empty - } - } - - case _ => NodeSeq.Empty - } - } - def makeDeveloperInfo(moduleInfo: ModuleInfo): NodeSeq = - { - if (moduleInfo.developers.nonEmpty) { - - { - moduleInfo.developers.map { developer: Developer => - - { developer.id } - { developer.name } - { developer.email } - { developer.url } - - } - } - - } else NodeSeq.Empty - } - def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = - { - val extra = IvySbt.getExtraAttributes(module) - val depExtra = PomExtraDependencyAttributes.writeDependencyExtra(dependencies).mkString("\n") - val allExtra = if (depExtra.isEmpty) extra else extra.updated(PomExtraDependencyAttributes.ExtraAttributesKey, depExtra) - if (allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) - } + + } else NodeSeq.Empty + } + def makeProperties(module: ModuleDescriptor, dependencies: Seq[DependencyDescriptor]): NodeSeq = { + val extra = IvySbt.getExtraAttributes(module) + val depExtra = PomExtraDependencyAttributes.writeDependencyExtra(dependencies).mkString("\n") + val allExtra = + if (depExtra.isEmpty) extra + else extra.updated(PomExtraDependencyAttributes.ExtraAttributesKey, depExtra) + if (allExtra.isEmpty) NodeSeq.Empty else makeProperties(allExtra) + } def makeProperties(extra: Map[String, String]): NodeSeq = { - def _extraAttributes(k: String) = if (k == PomExtraDependencyAttributes.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null + def _extraAttributes(k: String) = + if (k == PomExtraDependencyAttributes.ExtraAttributesKey) xmlSpacePreserve + else scala.xml.Null { for ((key, value) <- extra) yield ({ value }).copy(label = key, attributes = _extraAttributes(key)) } @@ -152,8 +237,10 @@ class MakePom(val log: Logger) { */ def xmlSpacePreserve = new PrefixedAttribute("xml", "space", "preserve", scala.xml.Null) - def description(d: String) = if ((d eq null) || d.isEmpty) NodeSeq.Empty else { d } - def licenses(ls: Array[License]) = if (ls == null || ls.isEmpty) NodeSeq.Empty else { ls.map(license) } + def description(d: String) = + if ((d eq null) || d.isEmpty) NodeSeq.Empty else { d } + def licenses(ls: Array[License]) = + if (ls == null || ls.isEmpty) NodeSeq.Empty else { ls.map(license) } def license(l: License) = { l.getName } @@ -161,7 +248,8 @@ class MakePom(val log: Logger) { repo def homePage(homePage: String) = if (homePage eq null) NodeSeq.Empty else { homePage } - def revision(version: String) = if (version ne null) { version } else NodeSeq.Empty + def revision(version: String) = + if (version ne null) { version } else NodeSeq.Empty def packaging(module: ModuleDescriptor) = module.getAllArtifacts match { case Array() => "pom" @@ -177,10 +265,17 @@ class MakePom(val log: Logger) { val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) @deprecated("Use `makeDependencies` variant which takes excludes", "0.13.9") - def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String]): NodeSeq = + def makeDependencies( + dependencies: Seq[DependencyDescriptor], + includeTypes: Set[String] + ): NodeSeq = makeDependencies(dependencies, includeTypes, Nil) - def makeDependencies(dependencies: Seq[DependencyDescriptor], includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = + def makeDependencies( + dependencies: Seq[DependencyDescriptor], + includeTypes: Set[String], + excludes: Seq[ExcludeRule] + ): NodeSeq = if (dependencies.isEmpty) NodeSeq.Empty else @@ -192,74 +287,96 @@ class MakePom(val log: Logger) { def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = makeDependency(dependency, includeTypes, Nil) - def makeDependency(dependency: DependencyDescriptor, includeTypes: Set[String], excludes: Seq[ExcludeRule]): NodeSeq = - { - val artifacts = dependency.getAllDependencyArtifacts - val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) - if (artifacts.isEmpty) { - val configs = dependency.getModuleConfigurations - if (configs.filterNot(Set("sources", "docs")).nonEmpty) { - val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) - makeDependencyElem(dependency, scope, optional, None, None, excludes) - } else NodeSeq.Empty - } else if (includeArtifacts.isEmpty) - NodeSeq.Empty - else - NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) - } + def makeDependency( + dependency: DependencyDescriptor, + includeTypes: Set[String], + excludes: Seq[ExcludeRule] + ): NodeSeq = { + val artifacts = dependency.getAllDependencyArtifacts + val includeArtifacts = artifacts.filter(d => includeTypes(d.getType)) + if (artifacts.isEmpty) { + val configs = dependency.getModuleConfigurations + if (configs.filterNot(Set("sources", "docs")).nonEmpty) { + val (scope, optional) = getScopeAndOptional(dependency.getModuleConfigurations) + makeDependencyElem(dependency, scope, optional, None, None, excludes) + } else NodeSeq.Empty + } else if (includeArtifacts.isEmpty) + NodeSeq.Empty + else + NodeSeq.fromSeq(artifacts.flatMap(a => makeDependencyElem(dependency, a, excludes))) + } @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") - def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor): Option[Elem] = + def makeDependencyElem( + dependency: DependencyDescriptor, + artifact: DependencyArtifactDescriptor + ): Option[Elem] = makeDependencyElem(dependency, artifact, Nil) - def makeDependencyElem(dependency: DependencyDescriptor, artifact: DependencyArtifactDescriptor, excludes: Seq[ExcludeRule]): Option[Elem] = - { - val configs = artifact.getConfigurations.toList match { - case Nil | "*" :: Nil => dependency.getModuleConfigurations - case x => x.toArray - } - if (!configs.forall(Set("sources", "docs"))) { - val (scope, optional) = getScopeAndOptional(configs) - val classifier = artifactClassifier(artifact) - val baseType = artifactType(artifact) - val tpe = (classifier, baseType) match { - case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None - case _ => baseType - } - Some(makeDependencyElem(dependency, scope, optional, classifier, tpe, excludes)) - } else None + def makeDependencyElem( + dependency: DependencyDescriptor, + artifact: DependencyArtifactDescriptor, + excludes: Seq[ExcludeRule] + ): Option[Elem] = { + val configs = artifact.getConfigurations.toList match { + case Nil | "*" :: Nil => dependency.getModuleConfigurations + case x => x.toArray } + if (!configs.forall(Set("sources", "docs"))) { + val (scope, optional) = getScopeAndOptional(configs) + val classifier = artifactClassifier(artifact) + val baseType = artifactType(artifact) + val tpe = (classifier, baseType) match { + case (Some(c), Some(tpe)) if Artifact.classifierType(c) == tpe => None + case _ => baseType + } + Some(makeDependencyElem(dependency, scope, optional, classifier, tpe, excludes)) + } else None + } @deprecated("Use `makeDependencyElem` variant which takes excludes", "0.13.9") - def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String]): Elem = + def makeDependencyElem( + dependency: DependencyDescriptor, + scope: Option[String], + optional: Boolean, + classifier: Option[String], + tpe: Option[String] + ): Elem = makeDependencyElem(dependency, scope, optional, classifier, tpe, Nil) - def makeDependencyElem(dependency: DependencyDescriptor, scope: Option[String], optional: Boolean, classifier: Option[String], tpe: Option[String], excludes: Seq[ExcludeRule]): Elem = - { - val mrid = dependency.getDependencyRevisionId - - { mrid.getOrganisation } - { mrid.getName } - { makeDependencyVersion(mrid.getRevision) } - { scopeElem(scope) } - { optionalElem(optional) } - { classifierElem(classifier) } - { typeElem(tpe) } - { exclusions(dependency, excludes) } - - } + def makeDependencyElem( + dependency: DependencyDescriptor, + scope: Option[String], + optional: Boolean, + classifier: Option[String], + tpe: Option[String], + excludes: Seq[ExcludeRule] + ): Elem = { + val mrid = dependency.getDependencyRevisionId + + { mrid.getOrganisation } + { mrid.getName } + { makeDependencyVersion(mrid.getRevision) } + { scopeElem(scope) } + { optionalElem(optional) } + { classifierElem(classifier) } + { typeElem(tpe) } + { exclusions(dependency, excludes) } + + } @deprecated("No longer used and will be removed.", "0.12.1") - def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = - { - val jarDep = dependency.getAllDependencyArtifacts.find(d => includeTypes(d.getType)) - jarDep match { - case Some(a) => classifierElem(artifactClassifier(a)) - case None => NodeSeq.Empty - } + def classifier(dependency: DependencyDescriptor, includeTypes: Set[String]): NodeSeq = { + val jarDep = dependency.getAllDependencyArtifacts.find(d => includeTypes(d.getType)) + jarDep match { + case Some(a) => classifierElem(artifactClassifier(a)) + case None => NodeSeq.Empty } + } def artifactType(artifact: DependencyArtifactDescriptor): Option[String] = - Option(artifact.getType).flatMap { tpe => if (tpe == "jar") None else Some(tpe) } + Option(artifact.getType).flatMap { tpe => + if (tpe == "jar") None else Some(tpe) + } def typeElem(tpe: Option[String]): NodeSeq = tpe match { case Some(t) => { t } @@ -275,11 +392,10 @@ class MakePom(val log: Logger) { } @deprecated("No longer used and will be removed.", "0.12.1") - def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = - { - val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) - scopeElem(scope) ++ optionalElem(opt) - } + def scopeAndOptional(dependency: DependencyDescriptor): NodeSeq = { + val (scope, opt) = getScopeAndOptional(dependency.getModuleConfigurations) + scopeElem(scope) ++ optionalElem(opt) + } def scopeElem(scope: Option[String]): NodeSeq = scope match { case None | Some(Configurations.Compile.name) => NodeSeq.Empty case Some(s) => { s } @@ -287,59 +403,67 @@ class MakePom(val log: Logger) { def optionalElem(opt: Boolean) = if (opt) true else NodeSeq.Empty def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId - def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = - { - val (opt, notOptional) = confs.partition(_ == Optional.name) - val defaultNotOptional = Configurations.defaultMavenConfigurations.find(notOptional contains _.name) - val scope = defaultNotOptional.map(_.name) - (scope, opt.nonEmpty) - } + def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = { + val (opt, notOptional) = confs.partition(_ == Optional.name) + val defaultNotOptional = + Configurations.defaultMavenConfigurations.find(notOptional contains _.name) + val scope = defaultNotOptional.map(_.name) + (scope, opt.nonEmpty) + } @deprecated("Use `exclusions` variant which takes excludes", "0.13.9") def exclusions(dependency: DependencyDescriptor): NodeSeq = exclusions(dependency, Nil) - def exclusions(dependency: DependencyDescriptor, excludes: Seq[ExcludeRule]): NodeSeq = - { - val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes - val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) - if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) - if (excls.nonEmpty) { excls } - else NodeSeq.Empty - } - def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = - { - val m = exclRule.getId.getModuleId - val (g, a) = (m.getOrganisation, m.getName) - if (g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") - Left("Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema.".format(m)) - else - Right( - - { g } - { a } - - ) - } + def exclusions(dependency: DependencyDescriptor, excludes: Seq[ExcludeRule]): NodeSeq = { + val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes + val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) + if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) + if (excls.nonEmpty) { excls } + else NodeSeq.Empty + } + def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = { + val m = exclRule.getId.getModuleId + val (g, a) = (m.getOrganisation, m.getName) + if (g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") + Left( + "Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema." + .format(m) + ) + else + Right( + + { g } + { a } + + ) + } - def makeRepositories(settings: IvySettings, includeAll: Boolean, filterRepositories: MavenRepository => Boolean) = - { - val repositories = if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) - val mavenRepositories = - repositories.flatMap { - // TODO - Would it be ok if bintray were in the pom? We should avoid it for now. - case m: CustomRemoteMavenResolver if m.repo.root == JCenterRepository.root => Nil - case m: IBiblioResolver if m.isM2compatible && m.getRoot == JCenterRepository.root => Nil - case m: CustomRemoteMavenResolver if m.repo.root != DefaultMavenRepository.root => - MavenRepository(m.repo.name, m.repo.root) :: Nil - case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => - MavenRepository(m.getName, m.getRoot) :: Nil - case _ => Nil - } - val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) - if (repositoryElements.isEmpty) repositoryElements else { repositoryElements } - } - def allResolvers(settings: IvySettings): Seq[DependencyResolver] = flatten(castResolvers(settings.getResolvers)).distinct - def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = if (rs eq null) Nil else rs.flatMap(resolvers) + def makeRepositories( + settings: IvySettings, + includeAll: Boolean, + filterRepositories: MavenRepository => Boolean + ) = { + val repositories = + if (includeAll) allResolvers(settings) else resolvers(settings.getDefaultResolver) + val mavenRepositories = + repositories.flatMap { + // TODO - Would it be ok if bintray were in the pom? We should avoid it for now. + case m: CustomRemoteMavenResolver if m.repo.root == JCenterRepository.root => Nil + case m: IBiblioResolver if m.isM2compatible && m.getRoot == JCenterRepository.root => Nil + case m: CustomRemoteMavenResolver if m.repo.root != DefaultMavenRepository.root => + MavenRepository(m.repo.name, m.repo.root) :: Nil + case m: IBiblioResolver if m.isM2compatible && m.getRoot != DefaultMavenRepository.root => + MavenRepository(m.getName, m.getRoot) :: Nil + case _ => Nil + } + val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) + if (repositoryElements.isEmpty) repositoryElements + else { repositoryElements } + } + def allResolvers(settings: IvySettings): Seq[DependencyResolver] = + flatten(castResolvers(settings.getResolvers)).distinct + def flatten(rs: Seq[DependencyResolver]): Seq[DependencyResolver] = + if (rs eq null) Nil else rs.flatMap(resolvers) def resolvers(r: DependencyResolver): Seq[DependencyResolver] = r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } @@ -349,7 +473,8 @@ class MakePom(val log: Logger) { def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = c.isLetterOrDigit - private def checkID(id: String, name: String) = if (id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id + private def checkID(id: String, name: String) = + if (id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id def mavenRepository(repo: MavenRepository): XNode = mavenRepository(toID(repo.name), repo.name, repo.root) def mavenRepository(id: String, name: String, root: String): XNode = @@ -364,18 +489,19 @@ class MakePom(val log: Logger) { * Retain dependencies only with the configurations given, or all public configurations of `module` if `configurations` is None. * This currently only preserves the information required by makePom */ - private def depsInConfs(module: ModuleDescriptor, configurations: Option[Iterable[Configuration]]): Seq[DependencyDescriptor] = - { - val keepConfigurations = IvySbt.getConfigurations(module, configurations) - val keepSet = Set(keepConfigurations.toSeq: _*) - def translate(dependency: DependencyDescriptor) = - { - val keep = dependency.getModuleConfigurations.filter(keepSet.contains) - if (keep.isEmpty) - None - else // TODO: translate the dependency to contain only configurations to keep - Some(dependency) - } - module.getDependencies flatMap translate + private def depsInConfs( + module: ModuleDescriptor, + configurations: Option[Iterable[Configuration]] + ): Seq[DependencyDescriptor] = { + val keepConfigurations = IvySbt.getConfigurations(module, configurations) + val keepSet = Set(keepConfigurations.toSeq: _*) + def translate(dependency: DependencyDescriptor) = { + val keep = dependency.getModuleConfigurations.filter(keepSet.contains) + if (keep.isEmpty) + None + else // TODO: translate the dependency to contain only configurations to keep + Some(dependency) } + module.getDependencies flatMap translate + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala index caca5a9ed..912f77bd0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala @@ -10,17 +10,28 @@ import org.apache.ivy.core.{ cache, module, report, resolve, search } import cache.ArtifactOrigin import search.{ ModuleEntry, OrganisationEntry, RevisionEntry } import module.id.ModuleRevisionId -import module.descriptor.{ Artifact => IArtifact, DefaultArtifact, DependencyDescriptor, ModuleDescriptor } +import module.descriptor.{ + Artifact => IArtifact, + DefaultArtifact, + DependencyDescriptor, + ModuleDescriptor +} import org.apache.ivy.plugins.namespace.Namespace import org.apache.ivy.plugins.resolver.ResolverSettings -import report.{ ArtifactDownloadReport, DownloadReport, DownloadStatus, MetadataArtifactDownloadReport } +import report.{ + ArtifactDownloadReport, + DownloadReport, + DownloadStatus, + MetadataArtifactDownloadReport +} import resolve.{ DownloadOptions, ResolveData, ResolvedModuleRevision } /** * A Resolver that uses a predefined mapping from module ids to in-memory descriptors. * It does not handle artifacts. */ -class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) extends ResolverAdapter { +class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor]) + extends ResolverAdapter { def getName = name def setName(name: String) = sys.error("Setting name not supported by ProjectResolver") override def toString = "ProjectResolver(" + name + ", mapped: " + map.keys.mkString(", ") + ")" @@ -28,48 +39,47 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = getDependency(dd.getDependencyRevisionId).orNull - private[this] def getDependency(revisionId: ModuleRevisionId): Option[ResolvedModuleRevision] = - { - def constructResult(descriptor: ModuleDescriptor) = new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) - map get revisionId map constructResult - } + private[this] def getDependency(revisionId: ModuleRevisionId): Option[ResolvedModuleRevision] = { + def constructResult(descriptor: ModuleDescriptor) = + new ResolvedModuleRevision(this, this, descriptor, report(revisionId), true) + map get revisionId map constructResult + } - private[sbt] def getModuleDescriptor(revisionId: ModuleRevisionId): Option[ModuleDescriptor] = map.get(revisionId) + private[sbt] def getModuleDescriptor(revisionId: ModuleRevisionId): Option[ModuleDescriptor] = + map.get(revisionId) - def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = - { - val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) - val r = new MetadataArtifactDownloadReport(artifact) - r.setSearched(false) - r.setDownloadStatus(DownloadStatus.FAILED) - r - } + def report(revisionId: ModuleRevisionId): MetadataArtifactDownloadReport = { + val artifact = DefaultArtifact.newIvyArtifact(revisionId, new Date) + val r = new MetadataArtifactDownloadReport(artifact) + r.setSearched(false) + r.setDownloadStatus(DownloadStatus.FAILED) + r + } // this resolver nevers locates artifacts, only resolves dependencies def exists(artifact: IArtifact) = false def locate(artifact: IArtifact) = null - def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = - { - val r = new DownloadReport - for (artifact <- artifacts) - if (getDependency(artifact.getModuleRevisionId).isEmpty) - r.addArtifactReport(notDownloaded(artifact)) - r - } + def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = { + val r = new DownloadReport + for (artifact <- artifacts) + if (getDependency(artifact.getModuleRevisionId).isEmpty) + r.addArtifactReport(notDownloaded(artifact)) + r + } def download(artifact: ArtifactOrigin, options: DownloadOptions): ArtifactDownloadReport = notDownloaded(artifact.getArtifact) def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData) = null - def notDownloaded(artifact: IArtifact): ArtifactDownloadReport = - { - val r = new ArtifactDownloadReport(artifact) - r.setDownloadStatus(DownloadStatus.FAILED) - r - } + def notDownloaded(artifact: IArtifact): ArtifactDownloadReport = { + val r = new ArtifactDownloadReport(artifact) + r.setDownloadStatus(DownloadStatus.FAILED) + r + } // doesn't support publishing - def publish(artifact: IArtifact, src: File, overwrite: Boolean) = sys.error("Publish not supported by ProjectResolver") + def publish(artifact: IArtifact, src: File, overwrite: Boolean) = + sys.error("Publish not supported by ProjectResolver") def beginPublishTransaction(module: ModuleRevisionId, overwrite: Boolean): Unit = () def abortPublishTransaction(): Unit = () def commitPublishTransaction(): Unit = () @@ -87,7 +97,10 @@ class ProjectResolver(name: String, map: Map[ModuleRevisionId, ModuleDescriptor] def dumpSettings(): Unit = () def setSettings(settings: ResolverSettings): Unit = { this.settings = Some(settings) } - def getRepositoryCacheManager = settings match { case Some(s) => s.getDefaultRepositoryCacheManager; case None => sys.error("No settings defined for ProjectResolver") } + def getRepositoryCacheManager = settings match { + case Some(s) => s.getDefaultRepositoryCacheManager; + case None => sys.error("No settings defined for ProjectResolver") + } } object ProjectResolver { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala index 1f56dbb6f..a10741b64 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala @@ -12,16 +12,28 @@ import sbt.internal.util.complete.DefaultParsers._ private[sbt] object RepositoriesParser { private case class AfterPattern(artifactPattern: Option[String], flags: Int) - final case class PredefinedRepository(override val id: xsbti.Predefined) extends xsbti.PredefinedRepository - final case class MavenRepository(override val id: String, override val url: URL) extends xsbti.MavenRepository - final case class IvyRepository(override val id: String, override val url: URL, override val ivyPattern: String, - override val artifactPattern: String, override val mavenCompatible: Boolean, override val skipConsistencyCheck: Boolean, - override val descriptorOptional: Boolean, val bootOnly: Boolean) extends xsbti.IvyRepository + final case class PredefinedRepository(override val id: xsbti.Predefined) + extends xsbti.PredefinedRepository + final case class MavenRepository(override val id: String, override val url: URL) + extends xsbti.MavenRepository + final case class IvyRepository( + override val id: String, + override val url: URL, + override val ivyPattern: String, + override val artifactPattern: String, + override val mavenCompatible: Boolean, + override val skipConsistencyCheck: Boolean, + override val descriptorOptional: Boolean, + val bootOnly: Boolean + ) extends xsbti.IvyRepository // Predefined repositories - def local: Parser[xsbti.Repository] = "local" ^^^ new PredefinedRepository(xsbti.Predefined.Local) - def mavenLocal: Parser[xsbti.Repository] = "maven-local" ^^^ new PredefinedRepository(xsbti.Predefined.MavenLocal) - def mavenCentral: Parser[xsbti.Repository] = "maven-central" ^^^ new PredefinedRepository(xsbti.Predefined.MavenCentral) + def local: Parser[xsbti.Repository] = + "local" ^^^ new PredefinedRepository(xsbti.Predefined.Local) + def mavenLocal: Parser[xsbti.Repository] = + "maven-local" ^^^ new PredefinedRepository(xsbti.Predefined.MavenLocal) + def mavenCentral: Parser[xsbti.Repository] = + "maven-central" ^^^ new PredefinedRepository(xsbti.Predefined.MavenCentral) def predefinedResolver: Parser[xsbti.Repository] = local | mavenLocal | mavenCentral // Options @@ -54,7 +66,16 @@ private[sbt] object RepositoriesParser { // scalac complains about the recursion depth if we pattern match over `ap` directly. ap match { case Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) => - new IvyRepository(name, uri.toURL, ivy, artifactPattern getOrElse ivy, mc, sc, dOpt, bo) + new IvyRepository( + name, + uri.toURL, + ivy, + artifactPattern getOrElse ivy, + mc, + sc, + dOpt, + bo + ) case None => new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false) } @@ -69,7 +90,8 @@ private[sbt] object RepositoriesParser { def apply(lines: Iterator[String]): Seq[xsbti.Repository] = if (lines.isEmpty) Nil else { - if (lines.next != "[repositories]") throw new Exception("Repositories file must start with '[repositories]'") + if (lines.next != "[repositories]") + throw new Exception("Repositories file must start with '[repositories]'") lines.flatMap(getResolver(_)(resolver)).toList } def apply(str: String): Seq[xsbti.Repository] = apply(str.lines) @@ -92,4 +114,4 @@ private[sbt] object RepositoriesParser { Some((dOpt, sc, bo, mc)) } } -} \ No newline at end of file +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index 25103ba89..c6d3da447 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -19,10 +19,24 @@ import sbt.librarymanagement._ * 2. Have them per-project for easier cleaning (possible with standard cache, but central to this custom one). * 3. Cache location includes extra attributes so that cross builds of a plugin do not overwrite each other. */ -private[sbt] final class ResolutionCache(base: File, settings: IvySettings) extends ResolutionCacheManager { +private[sbt] final class ResolutionCache(base: File, settings: IvySettings) + extends ResolutionCacheManager { private[this] def resolvedFileInCache(m: ModuleRevisionId, name: String, ext: String): File = { val p = ResolvedPattern - val f = IvyPatternHelper.substitute(p, m.getOrganisation, m.getName, m.getBranch, m.getRevision, name, name, ext, null, null, m.getAttributes, null) + val f = IvyPatternHelper.substitute( + p, + m.getOrganisation, + m.getName, + m.getBranch, + m.getRevision, + name, + name, + ext, + null, + null, + m.getAttributes, + null + ) new File(base, f) } private[this] val reportBase: File = new File(base, ReportDirectory) @@ -62,11 +76,16 @@ private[sbt] final class ResolutionCache(base: File, settings: IvySettings) exte } } private[sbt] object ResolutionCache { + /** * Removes cached files from the resolution cache for the module with ID `mrid` * and the resolveId (as set on `ResolveOptions`). */ - private[sbt] def cleanModule(mrid: ModuleRevisionId, resolveId: String, manager: ResolutionCacheManager): Unit = { + private[sbt] def cleanModule( + mrid: ModuleRevisionId, + resolveId: String, + manager: ResolutionCacheManager + ): Unit = { val files = Option(manager.getResolvedIvyFileInCache(mrid)).toList ::: Option(manager.getResolvedIvyPropertiesInCache(mrid)).toList ::: diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala index ec144cfee..6c5c01245 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala @@ -9,7 +9,8 @@ abstract class SbtExclusionRuleFunctions { def apply(organization: String): SbtExclusionRule = apply(organization, "*") - implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = apply(organization.groupID) + implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = + apply(organization.groupID) implicit def stringToExclusionRule(organization: String): SbtExclusionRule = apply(organization) implicit def groupArtifactIDToExclusionRule(gaid: GroupArtifactID): SbtExclusionRule = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala index 00541d441..37c26418d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala @@ -6,8 +6,12 @@ package sbt.internal.librarymanagement import java.util.Locale object StringUtilities { - @deprecated("Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", "0.13.0") + @deprecated( + "Different use cases require different normalization. Use Project.normalizeModuleID or normalizeProjectID instead.", + "0.13.0" + ) def normalize(s: String) = s.toLowerCase(Locale.ENGLISH).replaceAll("""\W+""", "-") - def nonEmpty(s: String, label: String): Unit = require(s.trim.length > 0, label + " cannot be empty.") + def nonEmpty(s: String, label: String): Unit = + require(s.trim.length > 0, label + " cannot be empty.") def appendable(s: String) = if (s.isEmpty) "" else "_" + s } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index bb73c882a..38c5661b6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -3,13 +3,14 @@ package internal package librarymanagement object VersionRange { + /** True if the revision is an ivy-range, not a complete revision. */ def isVersionRange(revision: String): Boolean = { (revision endsWith "+") || - (revision contains "[") || - (revision contains "]") || - (revision contains "(") || - (revision contains ")") + (revision contains "[") || + (revision contains "]") || + (revision contains "(") || + (revision contains ")") } // Assuming Ivy is used to resolve conflict, this removes the version range @@ -50,13 +51,15 @@ object VersionRange { val maxDigit = 5 try { revision match { - case "+" => "[0,)" - case DotPlusPattern(base) => plusRange(base) + case "+" => "[0,)" + case DotPlusPattern(base) => plusRange(base) // This is a heuristic. Maven just doesn't support Ivy's notions of 1+, so // we assume version ranges never go beyond 5 siginificant digits. - case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") - case DotNumPlusPattern(base, tail) => (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") - case rev if rev endsWith "+" => sys.error(s"dynamic revision '$rev' cannot be translated to POM") + case NumPlusPattern(tail) => (0 until maxDigit).map(plusRange(tail, _)).mkString(",") + case DotNumPlusPattern(base, tail) => + (0 until maxDigit).map(plusRange(base + "." + tail, _)).mkString(",") + case rev if rev endsWith "+" => + sys.error(s"dynamic revision '$rev' cannot be translated to POM") case rev if startSym(rev(0)) && stopSym(rev(rev.length - 1)) => val start = rev(0) val stop = rev(rev.length - 1) @@ -79,5 +82,6 @@ object VersionRange { private[this] val startSym = Set(']', '[', '(') private[this] val stopSym = Set(']', '[', ')') - private[this] val MavenVersionSetPattern = """([\]\[\(])([\w\.\-]+)?(,)?([\w\.\-]+)?([\]\[\)])(,.+)?""".r + private[this] val MavenVersionSetPattern = + """([\]\[\(])([\w\.\-]+)?(,)?([\w\.\-]+)?([\]\[\)])(,.+)?""".r } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 7524f0851..4ebc79ca0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -12,65 +12,73 @@ object CrossVersionUtil { val TransitionSbtVersion = "0.12" def isFull(s: String): Boolean = (s == trueString) || (s == fullString) - def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) + def isDisabled(s: String): Boolean = + (s == falseString) || (s == noneString) || (s == disabledString) def isBinary(s: String): Boolean = (s == binaryString) private lazy val intPattern = """\d{1,10}""" private lazy val basicVersion = """(""" + intPattern + """)\.(""" + intPattern + """)\.(""" + intPattern + """)""" private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined + /** * Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = (basicVersion + """(-\d+)?""").r - val CandidateV = (basicVersion + """(-RC\d+)""").r - val NonReleaseV = (basicVersion + """([-\w+]*)""").r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } + private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = { + val ReleaseV = (basicVersion + """(-\d+)?""").r + val CandidateV = (basicVersion + """(-RC\d+)""").r + val NonReleaseV = (basicVersion + """([-\w+]*)""").r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None } + } private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined + /** * Returns Scala binary interface x.y API compatible with the given version string v. * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = - { - val ReleaseV = (basicVersion + """(-\d+)?""").r - val BinCompatV = (basicVersion + """-bin(-.*)?""").r - val NonReleaseV = (basicVersion + """(-\w+)""").r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } + private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = { + val ReleaseV = (basicVersion + """(-\d+)?""").r + val BinCompatV = (basicVersion + """-bin(-.*)?""").r + val NonReleaseV = (basicVersion + """(-\w+)""").r + v match { + case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) + case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None } - private[sbt] val PartialVersion = ("""(""" + intPattern + """)\.(""" + intPattern + """)(?:\..+)?""").r + } + private[sbt] val PartialVersion = + ("""(""" + intPattern + """)\.(""" + intPattern + """)(?:\..+)?""").r private[sbt] def partialVersion(s: String): Option[(Int, Int)] = s match { case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) case _ => None } - def binaryScalaVersion(full: String): String = binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) - def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) - private[sbt] def binaryVersion(full: String, cutoff: String): String = binaryVersionWithApi(full, cutoff)(scalaApiVersion) + def binaryScalaVersion(full: String): String = + binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binarySbtVersion(full: String): String = + binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + private[sbt] def binaryVersion(full: String, cutoff: String): String = + binaryVersionWithApi(full, cutoff)(scalaApiVersion) private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) - private[this] def binaryVersionWithApi(full: String, cutoff: String)(apiVersion: String => Option[(Int, Int)]): String = - { - def sub(major: Int, minor: Int) = major + "." + minor - (apiVersion(full), partialVersion(cutoff)) match { - case (Some((major, minor)), None) => sub(major, minor) - case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => sub(major, minor) - case _ => full - } + private[this] def binaryVersionWithApi(full: String, cutoff: String)( + apiVersion: String => Option[(Int, Int)] + ): String = { + def sub(major: Int, minor: Int) = major + "." + minor + (apiVersion(full), partialVersion(cutoff)) match { + case (Some((major, minor)), None) => sub(major, minor) + case (Some((major, minor)), Some((minMajor, minMinor))) + if isNewer(major, minor, minMajor, minMinor) => + sub(major, minor) + case _ => full } + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index e5e8b6e63..0770fee85 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -8,15 +8,23 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol => implicit lazy val UpdateOptionsFormat: JsonFormat[UpdateOptions] = project( - (uo: UpdateOptions) => ( - uo.circularDependencyLevel.name, - uo.interProjectFirst, - uo.latestSnapshots, - uo.consolidatedResolution, - uo.cachedResolution + (uo: UpdateOptions) => + ( + uo.circularDependencyLevel.name, + uo.interProjectFirst, + uo.latestSnapshots, + uo.consolidatedResolution, + uo.cachedResolution ), (xs: (String, Boolean, Boolean, Boolean, Boolean)) => - new UpdateOptions(levels(xs._1), xs._2, xs._3, xs._4, xs._5, ConvertResolver.defaultConvert) + new UpdateOptions( + levels(xs._1), + xs._2, + xs._3, + xs._4, + xs._5, + ConvertResolver.defaultConvert + ) ) private val levels: Map[String, CircularDependencyLevel] = Map( diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala index c5e117c72..a37a4f38f 100755 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala @@ -8,58 +8,51 @@ import StringUtilities.nonEmpty import sbt.librarymanagement._ trait DependencyBuilders { - final implicit def toGroupID(groupID: String): GroupID = - { - nonEmpty(groupID, "Group ID") - new GroupID(groupID) - } - final implicit def toRepositoryName(name: String): RepositoryName = - { - nonEmpty(name, "Repository name") - new RepositoryName(name) - } - final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = - { - require(m.configurations.isEmpty, "Configurations already specified for module " + m) - new ModuleIDConfigurable(m) - } + final implicit def toGroupID(groupID: String): GroupID = { + nonEmpty(groupID, "Group ID") + new GroupID(groupID) + } + final implicit def toRepositoryName(name: String): RepositoryName = { + nonEmpty(name, "Repository name") + new RepositoryName(name) + } + final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = { + require(m.configurations.isEmpty, "Configurations already specified for module " + m) + new ModuleIDConfigurable(m) + } } final class GroupID private[sbt] (private[sbt] val groupID: String) { def %(artifactID: String) = groupArtifact(artifactID, Disabled()) def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) - private def groupArtifact(artifactID: String, cross: CrossVersion) = - { - nonEmpty(artifactID, "Artifact ID") - new GroupArtifactID(groupID, artifactID, cross) - } + private def groupArtifact(artifactID: String, cross: CrossVersion) = { + nonEmpty(artifactID, "Artifact ID") + new GroupArtifactID(groupID, artifactID, cross) + } } final class GroupArtifactID private[sbt] ( - private[sbt] val groupID: String, - private[sbt] val artifactID: String, - private[sbt] val crossVersion: CrossVersion + private[sbt] val groupID: String, + private[sbt] val artifactID: String, + private[sbt] val crossVersion: CrossVersion ) { - def %(revision: String): ModuleID = - { - nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(crossVersion) - } + def %(revision: String): ModuleID = { + nonEmpty(revision, "Revision") + ModuleID(groupID, artifactID, revision).cross(crossVersion) + } } final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { def %(configuration: Configuration): ModuleID = %(configuration.name) - def %(configurations: String): ModuleID = - { - nonEmpty(configurations, "Configurations") - val c = configurations - moduleID.withConfigurations(configurations = Some(c)) - } + def %(configurations: String): ModuleID = { + nonEmpty(configurations, "Configurations") + val c = configurations + moduleID.withConfigurations(configurations = Some(c)) + } } final class RepositoryName private[sbt] (name: String) { - def at(location: String) = - { - nonEmpty(location, "Repository location") - MavenRepository(name, location) - } + def at(location: String) = { + nonEmpty(location, "Repository location") + MavenRepository(name, location) + } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 8b9cb5074..0b4e2b92a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -12,8 +12,19 @@ import org.apache.ivy.core import core.resolve._ import core.module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } import core.report.ResolveReport -import core.module.descriptor.{ DefaultModuleDescriptor, ModuleDescriptor, DefaultDependencyDescriptor, DependencyDescriptor, Configuration => IvyConfiguration, ExcludeRule, IncludeRule } -import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor } +import core.module.descriptor.{ + DefaultModuleDescriptor, + ModuleDescriptor, + DefaultDependencyDescriptor, + DependencyDescriptor, + Configuration => IvyConfiguration, + ExcludeRule, + IncludeRule +} +import core.module.descriptor.{ + OverrideDependencyDescriptorMediator, + DependencyArtifactDescriptor +} import core.IvyPatternHelper import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } @@ -39,12 +50,17 @@ private[sbt] object CachedResolutionResolveCache { private[sbt] class CachedResolutionResolveCache { import CachedResolutionResolveCache._ - val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = concurrent.TrieMap() + val updateReportCache: concurrent.Map[ModuleRevisionId, Either[ResolveException, UpdateReport]] = + concurrent.TrieMap() // Used for subproject - val projectReportCache: concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap() + val projectReportCache + : concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = + concurrent.TrieMap() val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() - val conflictCache: concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap() + val conflictCache + : concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = + concurrent.TrieMap() val maxConflictCacheSize: Int = 1024 val maxUpdateReportCacheSize: Int = 1024 @@ -54,191 +70,235 @@ private[sbt] class CachedResolutionResolveCache { def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector // Returns a vector of (module descriptor, changing, dd) - def buildArtificialModuleDescriptors(md0: ModuleDescriptor, data: ResolveData, prOpt: Option[ProjectResolver], log: Logger): Vector[(DefaultModuleDescriptor, Boolean, DependencyDescriptor)] = - { - log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") - // val expanded = expandInternalDependencies(md0, data, prOpt, log) - val rootModuleConfigs = md0.getConfigurations.toVector - directDependencies(md0) map { dd => - val arts = dd.getAllDependencyArtifacts.toVector map { x => s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } - log.debug(s"::: dd: $dd (artifacts: ${arts.mkString(",")})") - buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log) + def buildArtificialModuleDescriptors( + md0: ModuleDescriptor, + data: ResolveData, + prOpt: Option[ProjectResolver], + log: Logger + ): Vector[(DefaultModuleDescriptor, Boolean, DependencyDescriptor)] = { + log.debug(s":: building artificial module descriptors from ${md0.getModuleRevisionId}") + // val expanded = expandInternalDependencies(md0, data, prOpt, log) + val rootModuleConfigs = md0.getConfigurations.toVector + directDependencies(md0) map { dd => + val arts = dd.getAllDependencyArtifacts.toVector map { x => + s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } + log.debug(s"::: dd: $dd (artifacts: ${arts.mkString(",")})") + buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log) } - def internalDependency(dd: DependencyDescriptor, prOpt: Option[ProjectResolver]): Option[ModuleDescriptor] = + } + def internalDependency( + dd: DependencyDescriptor, + prOpt: Option[ProjectResolver] + ): Option[ModuleDescriptor] = prOpt match { case Some(pr) => pr.getModuleDescriptor(dd.getDependencyRevisionId) case _ => None } - def buildArtificialModuleDescriptor(dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], - parent: ModuleDescriptor, prOpt: Option[ProjectResolver], log: Logger): (DefaultModuleDescriptor, Boolean, DependencyDescriptor) = - { - def excludeRuleString(rule: ExcludeRule): String = - s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" - def includeRuleString(rule: IncludeRule): String = - s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" - def artifactString(dad: DependencyArtifactDescriptor): String = - s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations.mkString(",")},${dad.getExtraAttributes})""" - val mrid = dd.getDependencyRevisionId - val confMap = (dd.getModuleConfigurations map { conf => - conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" - }) - val exclusions = (dd.getModuleConfigurations.toVector flatMap { conf => - dd.getExcludeRules(conf).toVector match { - case Vector() => None - case rules => Some(conf + "->(" + (rules map excludeRuleString).mkString(",") + ")") - } - }) - val inclusions = (dd.getModuleConfigurations.toVector flatMap { conf => - dd.getIncludeRules(conf).toVector match { - case Vector() => None - case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") - } - }) - val explicitArtifacts = dd.getAllDependencyArtifacts.toVector map { artifactString } - val mes = parent.getAllExcludeRules.toVector - val mesStr = (mes map excludeRuleString).mkString(",") - val os = extractOverrides(parent) - val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" - val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts.mkString(",")};$moduleLevel;""" - val sha1 = Hash.toHex(Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""")) - val md1 = new DefaultModuleDescriptor(createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), "release", null, false) with ArtificialModuleDescriptor { - def targetModuleRevisionId: ModuleRevisionId = mrid + def buildArtificialModuleDescriptor( + dd: DependencyDescriptor, + rootModuleConfigs: Vector[IvyConfiguration], + parent: ModuleDescriptor, + prOpt: Option[ProjectResolver], + log: Logger + ): (DefaultModuleDescriptor, Boolean, DependencyDescriptor) = { + def excludeRuleString(rule: ExcludeRule): String = + s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" + def includeRuleString(rule: IncludeRule): String = + s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" + def artifactString(dad: DependencyArtifactDescriptor): String = + s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations + .mkString(",")},${dad.getExtraAttributes})""" + val mrid = dd.getDependencyRevisionId + val confMap = (dd.getModuleConfigurations map { conf => + conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" + }) + val exclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getExcludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map excludeRuleString).mkString(",") + ")") } - for { - conf <- rootModuleConfigs - } yield md1.addConfiguration(conf) - md1.addDependency(dd) - os foreach { ovr => - md1.addDependencyDescriptorMediator(ovr.moduleId, ovr.pm, ovr.ddm) + }) + val inclusions = (dd.getModuleConfigurations.toVector flatMap { conf => + dd.getIncludeRules(conf).toVector match { + case Vector() => None + case rules => Some(conf + "->(" + (rules map includeRuleString).mkString(",") + ")") } - mes foreach { exclude => - md1.addExcludeRule(exclude) - } - (md1, IvySbt.isChanging(dd) || internalDependency(dd, prOpt).isDefined, dd) + }) + val explicitArtifacts = dd.getAllDependencyArtifacts.toVector map { artifactString } + val mes = parent.getAllExcludeRules.toVector + val mesStr = (mes map excludeRuleString).mkString(",") + val os = extractOverrides(parent) + val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" + val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts + .mkString(",")};$moduleLevel;""" + val sha1 = Hash.toHex( + Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""") + ) + val md1 = new DefaultModuleDescriptor( + createID(sbtOrgTemp, "temp-resolve-" + sha1, "1.0"), + "release", + null, + false + ) with ArtificialModuleDescriptor { + def targetModuleRevisionId: ModuleRevisionId = mrid } - def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = - { - import scala.collection.JavaConverters._ - md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { - case (k, v) => - k.toString - } collect { - case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => - val attr: Map[Any, Any] = k.getAttributes.asScala.toMap - val module = IvyModuleId.newInstance(attr(IvyPatternHelper.ORGANISATION_KEY).toString, attr(IvyPatternHelper.MODULE_KEY).toString) - val pm = k.getPatternMatcher - IvyOverride(module, pm, v) + for { + conf <- rootModuleConfigs + } yield md1.addConfiguration(conf) + md1.addDependency(dd) + os foreach { ovr => + md1.addDependencyDescriptorMediator(ovr.moduleId, ovr.pm, ovr.ddm) + } + mes foreach { exclude => + md1.addExcludeRule(exclude) + } + (md1, IvySbt.isChanging(dd) || internalDependency(dd, prOpt).isDefined, dd) + } + def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { + import scala.collection.JavaConverters._ + md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { + case (k, v) => + k.toString + } collect { + case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => + val attr: Map[Any, Any] = k.getAttributes.asScala.toMap + val module = IvyModuleId.newInstance( + attr(IvyPatternHelper.ORGANISATION_KEY).toString, + attr(IvyPatternHelper.MODULE_KEY).toString + ) + val pm = k.getPatternMatcher + IvyOverride(module, pm, v) + } + } + def getOrElseUpdateMiniGraph( + md: ModuleDescriptor, + changing0: Boolean, + logicalClock: LogicalClock, + miniGraphPath: File, + cachedDescriptor: File, + log: Logger + )( + f: => Either[ResolveException, UpdateReport] + ): Either[ResolveException, UpdateReport] = { + import sbt.io.syntax._ + val mrid = md.getResolvedModuleRevisionId + val (pathOrg, pathName, pathRevision) = md match { + case x: ArtificialModuleDescriptor => + val tmrid = x.targetModuleRevisionId + (tmrid.getOrganisation, tmrid.getName, tmrid.getRevision + "_" + mrid.getName) + case _ => + (mrid.getOrganisation, mrid.getName, mrid.getRevision) + } + val staticGraphDirectory = miniGraphPath / "static" + val dynamicGraphDirectory = miniGraphPath / "dynamic" + val staticGraphPath = staticGraphDirectory / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + def cleanDynamicGraph(): Unit = { + val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList + list filterNot { d => + (d.getName == todayStr) || (d.getName == tomorrowStr) || (d.getName == yesterdayStr) + } foreach { d => + log.debug(s"deleting old graphs $d...") + IO.delete(d) } } - def getOrElseUpdateMiniGraph(md: ModuleDescriptor, changing0: Boolean, logicalClock: LogicalClock, miniGraphPath: File, cachedDescriptor: File, log: Logger)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = - { - import sbt.io.syntax._ - val mrid = md.getResolvedModuleRevisionId - val (pathOrg, pathName, pathRevision) = md match { - case x: ArtificialModuleDescriptor => - val tmrid = x.targetModuleRevisionId - (tmrid.getOrganisation, tmrid.getName, tmrid.getRevision + "_" + mrid.getName) - case _ => - (mrid.getOrganisation, mrid.getName, mrid.getRevision) + def loadMiniGraphFromFile: Option[Either[ResolveException, UpdateReport]] = + (if (staticGraphPath.exists) Some(staticGraphPath) + else if (dynamicGraphPath.exists) Some(dynamicGraphPath) + else None) match { + case Some(path) => + log.debug(s"parsing ${path.getAbsolutePath.toString}") + val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) + if (ur.allFiles forall { _.exists }) { + updateReportCache(md.getModuleRevisionId) = Right(ur) + Some(Right(ur)) + } else { + log.debug(s"some files are missing from the cache, so invalidating the minigraph") + IO.delete(path) + None + } + case _ => None } - val staticGraphDirectory = miniGraphPath / "static" - val dynamicGraphDirectory = miniGraphPath / "dynamic" - val staticGraphPath = staticGraphDirectory / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - def cleanDynamicGraph(): Unit = - { - val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList - list filterNot { d => - (d.getName == todayStr) || (d.getName == tomorrowStr) || (d.getName == yesterdayStr) - } foreach { d => - log.debug(s"deleting old graphs $d...") - IO.delete(d) - } + (updateReportCache.get(mrid) orElse loadMiniGraphFromFile) match { + case Some(result) => + result match { + case Right(ur) => Right(ur.withStats(ur.stats.withCached(true))) + case x => x } - def loadMiniGraphFromFile: Option[Either[ResolveException, UpdateReport]] = - (if (staticGraphPath.exists) Some(staticGraphPath) - else if (dynamicGraphPath.exists) Some(dynamicGraphPath) - else None) match { - case Some(path) => - log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) - if (ur.allFiles forall { _.exists }) { - updateReportCache(md.getModuleRevisionId) = Right(ur) - Some(Right(ur)) - } else { - log.debug(s"some files are missing from the cache, so invalidating the minigraph") - IO.delete(path) - None - } - case _ => None - } - (updateReportCache.get(mrid) orElse loadMiniGraphFromFile) match { - case Some(result) => - result match { - case Right(ur) => Right(ur.withStats(ur.stats.withCached(true))) - case x => x - } - case None => - f match { - case Right(ur) => - val changing = changing0 || (ur.configurations exists { cr => - cr.details exists { oar => - oar.modules exists { mr => - IvySbt.isChanging(mr.module) || (mr.callers exists { _.isChangingDependency }) - } + case None => + f match { + case Right(ur) => + val changing = changing0 || (ur.configurations exists { cr => + cr.details exists { oar => + oar.modules exists { mr => + IvySbt.isChanging(mr.module) || (mr.callers exists { _.isChangingDependency }) } - }) - IO.createDirectory(miniGraphPath) - val gp = if (changing) dynamicGraphPath + } + }) + IO.createDirectory(miniGraphPath) + val gp = + if (changing) dynamicGraphPath else staticGraphPath - log.debug(s"saving minigraph to $gp") - if (changing) { - cleanDynamicGraph() - } - JsonUtil.writeUpdateReport(ur, gp) - // limit the update cache size - if (updateReportCache.size > maxUpdateReportCacheSize) { - updateReportCache.remove(updateReportCache.head._1) - } - // don't cache dynamic graphs in memory. - if (!changing) { - updateReportCache(md.getModuleRevisionId) = Right(ur) - } - Right(ur) - case Left(re) => - if (!changing0) { - updateReportCache(md.getModuleRevisionId) = Left(re) - } - Left(re) - } - } + log.debug(s"saving minigraph to $gp") + if (changing) { + cleanDynamicGraph() + } + JsonUtil.writeUpdateReport(ur, gp) + // limit the update cache size + if (updateReportCache.size > maxUpdateReportCacheSize) { + updateReportCache.remove(updateReportCache.head._1) + } + // don't cache dynamic graphs in memory. + if (!changing) { + updateReportCache(md.getModuleRevisionId) = Right(ur) + } + Right(ur) + case Left(re) => + if (!changing0) { + updateReportCache(md.getModuleRevisionId) = Left(re) + } + Left(re) + } } + } - def getOrElseUpdateConflict(cf0: ModuleID, cf1: ModuleID, conflicts: Vector[ModuleReport])(f: => (Vector[ModuleReport], Vector[ModuleReport], String)): (Vector[ModuleReport], Vector[ModuleReport]) = - { - def reconstructReports(surviving: Vector[ModuleID], evicted: Vector[ModuleID], mgr: String): (Vector[ModuleReport], Vector[ModuleReport]) = { - val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) - (surviving map moduleIdMap, evicted map moduleIdMap map { _.withEvicted(true).withEvictedReason(Some(mgr.toString)) }) - } - (conflictCache get ((cf0, cf1))) match { - case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) - case _ => - (conflictCache get ((cf1, cf0))) match { - case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) - case _ => - val (surviving, evicted, mgr) = f - if (conflictCache.size > maxConflictCacheSize) { - conflictCache.remove(conflictCache.head._1) - } - conflictCache((cf0, cf1)) = (surviving map { _.module }, evicted map { _.module }, mgr) - (surviving, evicted) - } - } + def getOrElseUpdateConflict(cf0: ModuleID, cf1: ModuleID, conflicts: Vector[ModuleReport])( + f: => (Vector[ModuleReport], Vector[ModuleReport], String) + ): (Vector[ModuleReport], Vector[ModuleReport]) = { + def reconstructReports( + surviving: Vector[ModuleID], + evicted: Vector[ModuleID], + mgr: String + ): (Vector[ModuleReport], Vector[ModuleReport]) = { + val moduleIdMap = Map(conflicts map { x => + x.module -> x + }: _*) + (surviving map moduleIdMap, evicted map moduleIdMap map { + _.withEvicted(true).withEvictedReason(Some(mgr.toString)) + }) } - def getOrElseUpdateProjectReport(mrid: ModuleRevisionId, logicalClock: LogicalClock)(f: => Either[ResolveException, UpdateReport]): Either[ResolveException, UpdateReport] = - if (projectReportCache contains (mrid -> logicalClock)) projectReportCache((mrid, logicalClock)) + (conflictCache get ((cf0, cf1))) match { + case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) + case _ => + (conflictCache get ((cf1, cf0))) match { + case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) + case _ => + val (surviving, evicted, mgr) = f + if (conflictCache.size > maxConflictCacheSize) { + conflictCache.remove(conflictCache.head._1) + } + conflictCache((cf0, cf1)) = (surviving map { _.module }, evicted map { _.module }, mgr) + (surviving, evicted) + } + } + } + def getOrElseUpdateProjectReport(mrid: ModuleRevisionId, logicalClock: LogicalClock)( + f: => Either[ResolveException, UpdateReport] + ): Either[ResolveException, UpdateReport] = + if (projectReportCache contains (mrid -> logicalClock)) + projectReportCache((mrid, logicalClock)) else { val oldKeys = projectReportCache.keys filter { case (x, clk) => clk != logicalClock } projectReportCache --= oldKeys @@ -263,86 +323,107 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val ivy = makeInstance ivy.pushContext() ivy.getLoggerEngine.pushLogger(log) - try { f(ivy) } - finally { + try { f(ivy) } finally { ivy.getLoggerEngine.popLogger() ivy.popContext() } } - def withDefaultLogger[A](log: MessageLogger)(f: => A): A = - { - val originalLogger = Message.getDefaultLogger - Message.setDefaultLogger(log) - try { f } - finally { Message.setDefaultLogger(originalLogger) } - } + def withDefaultLogger[A](log: MessageLogger)(f: => A): A = { + val originalLogger = Message.getDefaultLogger + Message.setDefaultLogger(log) + try { f } finally { Message.setDefaultLogger(originalLogger) } + } /** * This returns sbt's UpdateReport structure. * missingOk allows sbt to call this with classifiers that may or may not exist, and grab the JARs. */ - def customResolve(md0: ModuleDescriptor, missingOk: Boolean, logicalClock: LogicalClock, options0: ResolveOptions, depDir: File, log: Logger): Either[ResolveException, UpdateReport] = - cachedResolutionResolveCache.getOrElseUpdateProjectReport(md0.getModuleRevisionId, logicalClock) { + def customResolve( + md0: ModuleDescriptor, + missingOk: Boolean, + logicalClock: LogicalClock, + options0: ResolveOptions, + depDir: File, + log: Logger + ): Either[ResolveException, UpdateReport] = + cachedResolutionResolveCache.getOrElseUpdateProjectReport( + md0.getModuleRevisionId, + logicalClock + ) { import sbt.io.syntax._ val start = System.currentTimeMillis val miniGraphPath = depDir / "module" - val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) + val cachedDescriptor = + getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) val cache = cachedResolutionResolveCache val os = cache.extractOverrides(md0) val options1 = new ResolveOptions(options0) val data = new ResolveData(this, options1) val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) - def doWork(md: ModuleDescriptor, dd: DependencyDescriptor): Either[ResolveException, UpdateReport] = + def doWork( + md: ModuleDescriptor, + dd: DependencyDescriptor + ): Either[ResolveException, UpdateReport] = cache.internalDependency(dd, projectResolver) match { case Some(md1) => log.debug(s":: call customResolve recursively: $dd") customResolve(md1, missingOk, logicalClock, options0, depDir, log) match { - case Right(ur) => Right(remapInternalProject(new IvyNode(data, md1), ur, md0, dd, os, log)) - case Left(e) => Left(e) + case Right(ur) => + Right(remapInternalProject(new IvyNode(data, md1), ur, md0, dd, os, log)) + case Left(e) => Left(e) } case None => log.debug(s":: call ivy resolution: $dd") doWorkUsingIvy(md) } - def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = - { - val options1 = new ResolveOptions(options0) - val rr = withIvy(log) { ivy => - ivy.resolve(md, options1) - } - if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) - else { - val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct - val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => - val m = IvyRetrieve.toModuleID(node.getId) - val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => - IvyRetrieve.toModuleID(x.getId) - } - log.debug("- Unresolved path " + path.toString) - m -> path - }: _*) - val failed = failedPaths.keys.toSeq - Left(new ResolveException(messages, failed, failedPaths)) - } + def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { + val options1 = new ResolveOptions(options0) + val rr = withIvy(log) { ivy => + ivy.resolve(md, options1) } - val (internal, external) = mds.partition { case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined } + if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) + else { + val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct + val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => + val m = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => + IvyRetrieve.toModuleID(x.getId) + } + log.debug("- Unresolved path " + path.toString) + m -> path + }: _*) + val failed = failedPaths.keys.toSeq + Left(new ResolveException(messages, failed, failedPaths)) + } + } + val (internal, external) = mds.partition { + case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined + } val internalResults = internal map { case (md, changing, dd) => - cache.getOrElseUpdateMiniGraph(md, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + cache.getOrElseUpdateMiniGraph( + md, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { doWork(md, dd) } } val externalResults = external map { case (md0, changing, dd) => val configurationsInInternal = internalResults flatMap { - case Right(ur) => ur.allModules.flatMap { - case md => - val sameName = md.name == dd.getDependencyId.getName - val sameOrg = md.organization == dd.getDependencyId.getOrganisation - if (sameName && sameOrg) md.configurations - else None - } + case Right(ur) => + ur.allModules.flatMap { + case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } case _ => Nil } @@ -359,291 +440,388 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case _ => () } - cache.getOrElseUpdateMiniGraph(md0, changing, logicalClock, miniGraphPath, cachedDescriptor, log) { + cache.getOrElseUpdateMiniGraph( + md0, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { doWork(md0, dd) } } val results = internalResults ++ externalResults - val uReport = mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) + val uReport = + mergeResults(md0, results, missingOk, System.currentTimeMillis - start, os, log) val cacheManager = getSettings.getResolutionCacheManager cacheManager.saveResolvedModuleDescriptor(md0) val prop0 = "" - val ivyPropertiesInCache0 = cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) + val ivyPropertiesInCache0 = + cacheManager.getResolvedIvyPropertiesInCache(md0.getResolvedModuleRevisionId) IO.write(ivyPropertiesInCache0, prop0) uReport } - def mergeResults(md0: ModuleDescriptor, results: Vector[Either[ResolveException, UpdateReport]], missingOk: Boolean, resolveTime: Long, - os: Vector[IvyOverride], log: Logger): Either[ResolveException, UpdateReport] = - if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { case Left(re) => re }, log)) + def mergeResults( + md0: ModuleDescriptor, + results: Vector[Either[ResolveException, UpdateReport]], + missingOk: Boolean, + resolveTime: Long, + os: Vector[IvyOverride], + log: Logger + ): Either[ResolveException, UpdateReport] = + if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { + case Left(re) => re + }, log)) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) - def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException], log: Logger): ResolveException = - { - val messages = errors flatMap { _.messages } - val failed = errors flatMap { _.failed } - val failedPaths = errors flatMap { - _.failedPaths.toList map { - case (failed, paths) => - if (paths.isEmpty) (failed, paths) - else (failed, List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail) - } + def mergeErrors( + md0: ModuleDescriptor, + errors: Vector[ResolveException], + log: Logger + ): ResolveException = { + val messages = errors flatMap { _.messages } + val failed = errors flatMap { _.failed } + val failedPaths = errors flatMap { + _.failedPaths.toList map { + case (failed, paths) => + if (paths.isEmpty) (failed, paths) + else + (failed, + List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail) } - new ResolveException(messages, failed, ListMap(failedPaths: _*)) } - def mergeReports(md0: ModuleDescriptor, reports: Vector[UpdateReport], resolveTime: Long, os: Vector[IvyOverride], log: Logger): UpdateReport = - { - log.debug(s":: merging update reports") - val cachedDescriptor = getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) - val rootModuleConfigs = md0.getConfigurations.toVector - val cachedReports = reports filter { !_.stats.cached } - val stats = UpdateStats(resolveTime, (cachedReports map { _.stats.downloadTime }).sum, (cachedReports map { _.stats.downloadSize }).sum, false) - val configReports = rootModuleConfigs map { conf => - log.debug("::: -----------") - val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } - mergeConfigurationReports(conf.getName, crs, os, log) - } - UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + new ResolveException(messages, failed, ListMap(failedPaths: _*)) + } + def mergeReports( + md0: ModuleDescriptor, + reports: Vector[UpdateReport], + resolveTime: Long, + os: Vector[IvyOverride], + log: Logger + ): UpdateReport = { + log.debug(s":: merging update reports") + val cachedDescriptor = + getSettings.getResolutionCacheManager.getResolvedIvyFileInCache(md0.getModuleRevisionId) + val rootModuleConfigs = md0.getConfigurations.toVector + val cachedReports = reports filter { !_.stats.cached } + val stats = UpdateStats( + resolveTime, + (cachedReports map { _.stats.downloadTime }).sum, + (cachedReports map { _.stats.downloadSize }).sum, + false + ) + val configReports = rootModuleConfigs map { conf => + log.debug("::: -----------") + val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } + mergeConfigurationReports(conf.getName, crs, os, log) } + UpdateReport(cachedDescriptor, configReports, stats, Map.empty) + } // memory usage 62%, of which 58% is in mergeOrganizationArtifactReports - def mergeConfigurationReports(rootModuleConf: String, reports: Vector[ConfigurationReport], os: Vector[IvyOverride], log: Logger): ConfigurationReport = - { - // get the details right, and the rest could be derived - val details = mergeOrganizationArtifactReports(rootModuleConf, reports flatMap { _.details }, os, log) - val modules = details flatMap { - _.modules filter { mr => - !mr.evicted && mr.problem.isEmpty - } + def mergeConfigurationReports( + rootModuleConf: String, + reports: Vector[ConfigurationReport], + os: Vector[IvyOverride], + log: Logger + ): ConfigurationReport = { + // get the details right, and the rest could be derived + val details = + mergeOrganizationArtifactReports(rootModuleConf, reports flatMap { _.details }, os, log) + val modules = details flatMap { + _.modules filter { mr => + !mr.evicted && mr.problem.isEmpty } - ConfigurationReport(rootModuleConf, modules, details) } + ConfigurationReport(rootModuleConf, modules, details) + } + /** * Returns a tuple of (merged org + name combo, newly evicted modules) */ - def mergeOrganizationArtifactReports(rootModuleConf: String, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger): Vector[OrganizationArtifactReport] = - { - // filter out evicted modules from further logic - def filterReports(report0: OrganizationArtifactReport): Option[OrganizationArtifactReport] = - report0.modules.toVector flatMap { mr => - if (mr.evicted || mr.problem.nonEmpty) None - else - // https://github.com/sbt/sbt/issues/1763 - Some(mr.withCallers(JsonUtil.filterOutArtificialCallers(mr.callers))) - } match { - case Vector() => None - case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms)) - } + def mergeOrganizationArtifactReports( + rootModuleConf: String, + reports0: Vector[OrganizationArtifactReport], + os: Vector[IvyOverride], + log: Logger + ): Vector[OrganizationArtifactReport] = { + // filter out evicted modules from further logic + def filterReports(report0: OrganizationArtifactReport): Option[OrganizationArtifactReport] = + report0.modules.toVector flatMap { mr => + if (mr.evicted || mr.problem.nonEmpty) None + else + // https://github.com/sbt/sbt/issues/1763 + Some(mr.withCallers(JsonUtil.filterOutArtificialCallers(mr.callers))) + } match { + case Vector() => None + case ms => Some(OrganizationArtifactReport(report0.organization, report0.name, ms)) + } - // group by takes up too much memory. trading space with time. - val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => (oar.organization, oar.name) }).distinct - // this might take up some memory, but it's limited to a single - val reports1 = reports0 flatMap { filterReports } - val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = - Map(orgNamePairs map { - case (organization, name) => - val xs = reports1 filter { oar => oar.organization == organization && oar.name == name } - ((organization, name), xs) - }: _*) - // this returns a List of Lists of (org, name). should be deterministic - def detectLoops(allModules: Map[(String, String), Vector[OrganizationArtifactReport]]): List[List[(String, String)]] = - { - val loopSets: mutable.Set[Set[(String, String)]] = mutable.Set.empty - val loopLists: mutable.ListBuffer[List[(String, String)]] = mutable.ListBuffer.empty - def testLoop(m: (String, String), current: (String, String), history: List[(String, String)]): Unit = - { - val callers = + // group by takes up too much memory. trading space with time. + val orgNamePairs: Vector[(String, String)] = (reports0 map { oar => + (oar.organization, oar.name) + }).distinct + // this might take up some memory, but it's limited to a single + val reports1 = reports0 flatMap { filterReports } + val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = + Map(orgNamePairs map { + case (organization, name) => + val xs = reports1 filter { oar => + oar.organization == organization && oar.name == name + } + ((organization, name), xs) + }: _*) + // this returns a List of Lists of (org, name). should be deterministic + def detectLoops(allModules: Map[(String, String), Vector[OrganizationArtifactReport]]) + : List[List[(String, String)]] = { + val loopSets: mutable.Set[Set[(String, String)]] = mutable.Set.empty + val loopLists: mutable.ListBuffer[List[(String, String)]] = mutable.ListBuffer.empty + def testLoop( + m: (String, String), + current: (String, String), + history: List[(String, String)] + ): Unit = { + val callers = + (for { + oar <- allModules.getOrElse(current, Vector()) + mr <- oar.modules + c <- mr.callers + } yield (c.caller.organization, c.caller.name)).distinct + callers foreach { c => + if (history contains c) { + val loop = (c :: history.takeWhile(_ != c)) ::: List(c) + if (!loopSets(loop.toSet)) { + loopSets += loop.toSet + loopLists += loop + val loopStr = (loop map { case (o, n) => s"$o:$n" }).mkString("->") + log.warn(s"""avoid circular dependency while using cached resolution: $loopStr""") + } + } else testLoop(m, c, c :: history) + } + } + orgNamePairs map { orgname => + testLoop(orgname, orgname, List(orgname)) + } + loopLists.toList + } + val allModules2: mutable.Map[(String, String), Vector[OrganizationArtifactReport]] = + mutable.Map(allModules0.toSeq: _*) + @tailrec def breakLoops(loops: List[List[(String, String)]]): Unit = + loops match { + case Nil => () + case loop :: rest => + loop match { + case Nil => + breakLoops(rest) + case loop => + val sortedLoop = loop sortBy { x => (for { - oar <- allModules.getOrElse(current, Vector()) + oar <- allModules0(x) mr <- oar.modules c <- mr.callers - } yield (c.caller.organization, c.caller.name)).distinct - callers foreach { c => - if (history contains c) { - val loop = (c :: history.takeWhile(_ != c)) ::: List(c) - if (!loopSets(loop.toSet)) { - loopSets += loop.toSet - loopLists += loop - val loopStr = (loop map { case (o, n) => s"$o:$n" }).mkString("->") - log.warn(s"""avoid circular dependency while using cached resolution: $loopStr""") - } - } else testLoop(m, c, c :: history) + } yield c).size } - } - orgNamePairs map { orgname => - testLoop(orgname, orgname, List(orgname)) - } - loopLists.toList - } - val allModules2: mutable.Map[(String, String), Vector[OrganizationArtifactReport]] = - mutable.Map(allModules0.toSeq: _*) - @tailrec def breakLoops(loops: List[List[(String, String)]]): Unit = - loops match { - case Nil => () - case loop :: rest => - loop match { - case Nil => - breakLoops(rest) - case loop => - val sortedLoop = loop sortBy { x => - (for { - oar <- allModules0(x) - mr <- oar.modules - c <- mr.callers - } yield c).size - } - val moduleWithMostCallers = sortedLoop.reverse.head - val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1) - // remove the module with most callers as the caller of next. - // so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed. - allModules2 foreach { - case (k: (String, String), oars0) if k == next => - val oars: Vector[OrganizationArtifactReport] = oars0 map { oar => - val mrs = oar.modules map { mr => - val callers0 = mr.callers - val callers = callers0 filterNot { c => (c.caller.organization, c.caller.name) == moduleWithMostCallers } - if (callers.size == callers0.size) mr - else { - log.debug(s":: $rootModuleConf: removing caller $moduleWithMostCallers -> $next for sorting") - mr.withCallers(callers) - } + val moduleWithMostCallers = sortedLoop.reverse.head + val next: (String, String) = loop(loop.indexOf(moduleWithMostCallers) + 1) + // remove the module with most callers as the caller of next. + // so, A -> C, B -> C, and C -> A. C has the most callers, and C -> A will be removed. + allModules2 foreach { + case (k: (String, String), oars0) if k == next => + val oars: Vector[OrganizationArtifactReport] = oars0 map { oar => + val mrs = oar.modules map { mr => + val callers0 = mr.callers + val callers = callers0 filterNot { c => + (c.caller.organization, c.caller.name) == moduleWithMostCallers + } + if (callers.size == callers0.size) mr + else { + log.debug( + s":: $rootModuleConf: removing caller $moduleWithMostCallers -> $next for sorting" + ) + mr.withCallers(callers) } - OrganizationArtifactReport(oar.organization, oar.name, mrs) } - allModules2(k) = oars - case (k, v) => // do nothing - } - - breakLoops(rest) - } - } - val loop = detectLoops(allModules0) - log.debug(s":: $rootModuleConf: loop: $loop") - breakLoops(loop) - - // sort the all modules such that less called modules comes earlier - @tailrec def sortModules( - cs: Vector[(String, String)], - acc: Vector[(String, String)], extra: Vector[(String, String)], - n: Int, guard: Int - ): Vector[(String, String)] = - { - // println(s"sortModules: $n / $guard") - val keys = cs.toSet - val (called, notCalled) = cs partition { k => - val reports = allModules2(k) - reports exists { - _.modules.exists { - _.callers exists { caller => - val m = caller.caller - keys((m.organization, m.name)) - } + OrganizationArtifactReport(oar.organization, oar.name, mrs) + } + allModules2(k) = oars + case (k, v) => // do nothing } + + breakLoops(rest) + } + } + val loop = detectLoops(allModules0) + log.debug(s":: $rootModuleConf: loop: $loop") + breakLoops(loop) + + // sort the all modules such that less called modules comes earlier + @tailrec + def sortModules( + cs: Vector[(String, String)], + acc: Vector[(String, String)], + extra: Vector[(String, String)], + n: Int, + guard: Int + ): Vector[(String, String)] = { + // println(s"sortModules: $n / $guard") + val keys = cs.toSet + val (called, notCalled) = cs partition { k => + val reports = allModules2(k) + reports exists { + _.modules.exists { + _.callers exists { caller => + val m = caller.caller + keys((m.organization, m.name)) } } - lazy val result0 = acc ++ notCalled ++ called ++ extra - def warnCircular(): Unit = { - log.warn(s"""unexpected circular dependency while using cached resolution: ${cs.mkString(",")}""") - } - (if (n > guard) { - warnCircular - result0 - } else if (called.isEmpty) result0 - else if (notCalled.isEmpty) { - warnCircular - sortModules(cs.tail, acc, extra :+ cs.head, n + 1, guard) - } else sortModules(called, acc ++ notCalled, extra, 0, called.size * called.size + 1)) } - def resolveConflicts( + } + lazy val result0 = acc ++ notCalled ++ called ++ extra + def warnCircular(): Unit = { + log.warn( + s"""unexpected circular dependency while using cached resolution: ${cs.mkString(",")}""" + ) + } + (if (n > guard) { + warnCircular + result0 + } else if (called.isEmpty) result0 + else if (notCalled.isEmpty) { + warnCircular + sortModules(cs.tail, acc, extra :+ cs.head, n + 1, guard) + } else sortModules(called, acc ++ notCalled, extra, 0, called.size * called.size + 1)) + } + def resolveConflicts( cs: List[(String, String)], allModules: Map[(String, String), Vector[OrganizationArtifactReport]] - ): List[OrganizationArtifactReport] = - cs match { - case Nil => Nil - case (organization, name) :: rest => - val reports = allModules((organization, name)) - reports match { - case Vector() => resolveConflicts(rest, allModules) - case Vector(oa) if (oa.modules.isEmpty) => resolveConflicts(rest, allModules) - case Vector(oa) if (oa.modules.size == 1 && !oa.modules.head.evicted) => - log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") - oa :: resolveConflicts(rest, allModules) - case oas => - (mergeModuleReports(rootModuleConf, oas flatMap { _.modules }, os, log) match { - case (survivor, newlyEvicted) => - val evicted = (survivor ++ newlyEvicted) filter { m => m.evicted } - val notEvicted = (survivor ++ newlyEvicted) filter { m => !m.evicted } - log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) - log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) - val x = OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) - val nextModules = transitivelyEvict(rootModuleConf, rest, allModules, evicted, log) - x :: resolveConflicts(rest, nextModules) - }) - } - } - val guard0 = (orgNamePairs.size * orgNamePairs.size) + 1 - val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), Vector(), 0, guard0) - val sortedStr = (sorted map { case (o, n) => s"$o:$n" }).mkString(", ") - log.debug(s":: sort result: $sortedStr") - val result = resolveConflicts(sorted.toList, allModules0) - result.toVector - } + ): List[OrganizationArtifactReport] = + cs match { + case Nil => Nil + case (organization, name) :: rest => + val reports = allModules((organization, name)) + reports match { + case Vector() => resolveConflicts(rest, allModules) + case Vector(oa) if (oa.modules.isEmpty) => resolveConflicts(rest, allModules) + case Vector(oa) if (oa.modules.size == 1 && !oa.modules.head.evicted) => + log.debug(s":: no conflict $rootModuleConf: ${oa.organization}:${oa.name}") + oa :: resolveConflicts(rest, allModules) + case oas => + (mergeModuleReports(rootModuleConf, oas flatMap { _.modules }, os, log) match { + case (survivor, newlyEvicted) => + val evicted = (survivor ++ newlyEvicted) filter { m => + m.evicted + } + val notEvicted = (survivor ++ newlyEvicted) filter { m => + !m.evicted + } + log.debug("::: adds " + (notEvicted map { _.module }).mkString(", ")) + log.debug("::: evicted " + (evicted map { _.module }).mkString(", ")) + val x = OrganizationArtifactReport(organization, name, survivor ++ newlyEvicted) + val nextModules = + transitivelyEvict(rootModuleConf, rest, allModules, evicted, log) + x :: resolveConflicts(rest, nextModules) + }) + } + } + val guard0 = (orgNamePairs.size * orgNamePairs.size) + 1 + val sorted: Vector[(String, String)] = sortModules(orgNamePairs, Vector(), Vector(), 0, guard0) + val sortedStr = (sorted map { case (o, n) => s"$o:$n" }).mkString(", ") + log.debug(s":: sort result: $sortedStr") + val result = resolveConflicts(sorted.toList, allModules0) + result.toVector + } + /** * Merges ModuleReports, which represents orgnization, name, and version. * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). */ - def mergeModuleReports(rootModuleConf: String, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = - { - if (modules.nonEmpty) { - log.debug(s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}") - } - def mergeModuleReports(org: String, name: String, version: String, xs: Vector[ModuleReport]): ModuleReport = { - val completelyEvicted = xs forall { _.evicted } - val allCallers = xs flatMap { _.callers } - // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. - val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (k, xs) => xs.head } - val allArtifacts = (xs flatMap { _.artifacts }).distinct - xs.head.withArtifacts(allArtifacts).withEvicted(completelyEvicted).withCallers(distinctByModuleId) - } - val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { - case ((org, name, version), xs) => - if (xs.size < 2) xs - else Vector(mergeModuleReports(org, name, version, xs)) - } - val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty } - if (conflicts.size < 2) (merged, Vector()) - else resolveConflict(rootModuleConf, conflicts, os, log) match { - case (survivor, evicted) => - (survivor ++ (merged filter { m => m.evicted || m.problem.isDefined }), evicted) - } + def mergeModuleReports( + rootModuleConf: String, + modules: Vector[ModuleReport], + os: Vector[IvyOverride], + log: Logger + ): (Vector[ModuleReport], Vector[ModuleReport]) = { + if (modules.nonEmpty) { + log.debug( + s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}" + ) } + def mergeModuleReports( + org: String, + name: String, + version: String, + xs: Vector[ModuleReport] + ): ModuleReport = { + val completelyEvicted = xs forall { _.evicted } + val allCallers = xs flatMap { _.callers } + // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. + val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { + case (k, xs) => xs.head + } + val allArtifacts = (xs flatMap { _.artifacts }).distinct + xs.head + .withArtifacts(allArtifacts) + .withEvicted(completelyEvicted) + .withCallers(distinctByModuleId) + } + val merged = (modules groupBy { m => + (m.module.organization, m.module.name, m.module.revision) + }).toSeq.toVector flatMap { + case ((org, name, version), xs) => + if (xs.size < 2) xs + else Vector(mergeModuleReports(org, name, version, xs)) + } + val conflicts = merged filter { m => + !m.evicted && m.problem.isEmpty + } + if (conflicts.size < 2) (merged, Vector()) + else + resolveConflict(rootModuleConf, conflicts, os, log) match { + case (survivor, evicted) => + (survivor ++ (merged filter { m => + m.evicted || m.problem.isDefined + }), evicted) + } + } + /** * This transitively evicts any non-evicted modules whose only callers are newly evicted. */ - def transitivelyEvict(rootModuleConf: String, pairs: List[(String, String)], - reports0: Map[(String, String), Vector[OrganizationArtifactReport]], - evicted0: Vector[ModuleReport], log: Logger): Map[(String, String), Vector[OrganizationArtifactReport]] = - { - val em = (evicted0 map { _.module }).toSet - def isTransitivelyEvicted(mr: ModuleReport): Boolean = - mr.callers forall { c => em(c.caller) } - val reports: Seq[((String, String), Vector[OrganizationArtifactReport])] = reports0.toSeq flatMap { - case (k, v) if !(pairs contains k) => Seq() - case ((organization, name), oars0) => - val oars = oars0 map { oar => - val (affected, unaffected) = oar.modules partition { mr => - val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) - if (x) { - log.debug(s""":::: transitively evicted $rootModuleConf: ${mr.module}""") - } - x - } - val newlyEvicted = affected map { _.withEvicted(true).withEvictedReason(Some("transitive-evict")) } - if (affected.isEmpty) oar - else OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) - } - Seq(((organization, name), oars)) + def transitivelyEvict( + rootModuleConf: String, + pairs: List[(String, String)], + reports0: Map[(String, String), Vector[OrganizationArtifactReport]], + evicted0: Vector[ModuleReport], + log: Logger + ): Map[(String, String), Vector[OrganizationArtifactReport]] = { + val em = (evicted0 map { _.module }).toSet + def isTransitivelyEvicted(mr: ModuleReport): Boolean = + mr.callers forall { c => + em(c.caller) } - Map(reports: _*) + val reports + : Seq[((String, String), Vector[OrganizationArtifactReport])] = reports0.toSeq flatMap { + case (k, v) if !(pairs contains k) => Seq() + case ((organization, name), oars0) => + val oars = oars0 map { oar => + val (affected, unaffected) = oar.modules partition { mr => + val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) + if (x) { + log.debug(s""":::: transitively evicted $rootModuleConf: ${mr.module}""") + } + x + } + val newlyEvicted = affected map { + _.withEvicted(true).withEvictedReason(Some("transitive-evict")) + } + if (affected.isEmpty) oar + else OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) + } + Seq(((organization, name), oars)) } + Map(reports: _*) + } + /** * resolves dependency resolution conflicts in which multiple candidates are found for organization+name combos. * The main input is conflicts, which is a Vector of ModuleReport, which contains full info on the modulerevision, including its callers. @@ -655,116 +833,162 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * Note transitively forced dependencies are not respected. This seems to be the case for stock Ivy's behavior as well, * which may be because Ivy makes all Maven dependencies as forced="true". */ - def resolveConflict(rootModuleConf: String, conflicts: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger): (Vector[ModuleReport], Vector[ModuleReport]) = - { - import org.apache.ivy.plugins.conflict.{ NoConflictManager, StrictConflictManager, LatestConflictManager } - val head = conflicts.head - val organization = head.module.organization - val name = head.module.name - log.debug(s"::: resolving conflict in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")")) - def useLatest(lcm: LatestConflictManager): (Vector[ModuleReport], Vector[ModuleReport], String) = - (conflicts find { m => - m.callers.exists { _.isDirectlyForceDependency } - }) match { - case Some(m) => - log.debug(s"- directly forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("direct-force")) }, "direct-force") - case None => - (conflicts find { m => - m.callers.exists { _.isForceDependency } - }) match { - // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. - case Some(m) if !ignoreTransitiveForce => - log.debug(s"- transitively forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("transitive-force")) }, "transitive-force") - case _ => - val strategy = lcm.getStrategy - val infos = conflicts map { ModuleReportArtifactInfo(_) } - log.debug(s"- Using $strategy with $infos") - Option(strategy.findLatest(infos.toArray, None.orNull)) match { - case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some(lcm.toString)) }, lcm.toString) - case _ => (conflicts, Vector(), lcm.toString) - } - } - } - def doResolveConflict: (Vector[ModuleReport], Vector[ModuleReport], String) = - os find { ovr => ovr.moduleId.getOrganisation == organization && ovr.moduleId.getName == name } match { - case Some(ovr) if Option(ovr.ddm.getVersion).isDefined => - val ovrVersion = ovr.ddm.getVersion - conflicts find { mr => - mr.module.revision == ovrVersion - } match { - case Some(m) => - (Vector(m), conflicts filterNot { _ == m } map { _.withEvicted(true).withEvictedReason(Some("override")) }, "override") - case None => - sys.error(s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { _.module }).mkString("(", ", ", ")")) - } - case None => - getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { - case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) - case _: StrictConflictManager => sys.error((s"conflict was found in $rootModuleConf:$organization:$name " + (conflicts map { _.module }).mkString("(", ", ", ")"))) - case lcm: LatestConflictManager => useLatest(lcm) - case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") - } - } - if (conflicts.size == 2 && os.isEmpty) { - val (cf0, cf1) = (conflicts(0).module, conflicts(1).module) - val cache = cachedResolutionResolveCache - val (surviving, evicted) = cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { doResolveConflict } - (surviving, evicted) - } else { - val (surviving, evicted, _) = doResolveConflict - (surviving, evicted) - } + def resolveConflict( + rootModuleConf: String, + conflicts: Vector[ModuleReport], + os: Vector[IvyOverride], + log: Logger + ): (Vector[ModuleReport], Vector[ModuleReport]) = { + import org.apache.ivy.plugins.conflict.{ + NoConflictManager, + StrictConflictManager, + LatestConflictManager } - def remapInternalProject(node: IvyNode, ur: UpdateReport, - md0: ModuleDescriptor, dd: DependencyDescriptor, - os: Vector[IvyOverride], log: Logger): UpdateReport = - { - def parentConfigs(c: String): Vector[String] = - Option(md0.getConfiguration(c)) match { - case Some(config) => - config.getExtends.toVector ++ - (config.getExtends.toVector flatMap parentConfigs) - case None => Vector() - } - // These are the configurations from the original project we want to resolve. - val rootModuleConfs = md0.getConfigurations.toVector - val configurations0 = ur.configurations.toVector - // This is how md looks from md0 via dd's mapping. - val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => - val remapped: Vector[String] = dd.getDependencyConfigurations(conf0.getName).toVector flatMap { conf => - node.getRealConfs(conf).toVector - } - conf0.getName -> remapped - }: _*) - // This emulates test-internal extending test configuration etc. - val remappedConfigs: Map[String, Vector[String]] = - (remappedConfigs0 /: rootModuleConfs) { (acc0, c) => - val ps = parentConfigs(c.getName) - (acc0 /: ps) { (acc, parent) => - val vs0 = acc.getOrElse(c.getName, Vector()) - val vs = acc.getOrElse(parent, Vector()) - acc.updated(c.getName, (vs0 ++ vs).distinct) + val head = conflicts.head + val organization = head.module.organization + val name = head.module.name + log.debug(s"::: resolving conflict in $rootModuleConf:$organization:$name " + (conflicts map { + _.module + }).mkString("(", ", ", ")")) + def useLatest( + lcm: LatestConflictManager + ): (Vector[ModuleReport], Vector[ModuleReport], String) = + (conflicts find { m => + m.callers.exists { _.isDirectlyForceDependency } + }) match { + case Some(m) => + log.debug(s"- directly forced dependency: $m ${m.callers}") + (Vector(m), conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("direct-force")) + }, "direct-force") + case None => + (conflicts find { m => + m.callers.exists { _.isForceDependency } + }) match { + // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. + case Some(m) if !ignoreTransitiveForce => + log.debug(s"- transitively forced dependency: $m ${m.callers}") + (Vector(m), conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("transitive-force")) + }, "transitive-force") + case _ => + val strategy = lcm.getStrategy + val infos = conflicts map { ModuleReportArtifactInfo(_) } + log.debug(s"- Using $strategy with $infos") + Option(strategy.findLatest(infos.toArray, None.orNull)) match { + case Some(ModuleReportArtifactInfo(m)) => + (Vector(m), conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some(lcm.toString)) + }, lcm.toString) + case _ => (conflicts, Vector(), lcm.toString) + } } - } - log.debug(s"::: remapped configs $remappedConfigs") - val configurations = rootModuleConfs map { conf0 => - val remappedCRs = configurations0 filter { cr => - remappedConfigs(conf0.getName) contains cr.configuration - } - mergeConfigurationReports(conf0.getName, remappedCRs, os, log) } - UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) + def doResolveConflict: (Vector[ModuleReport], Vector[ModuleReport], String) = + os find { ovr => + ovr.moduleId.getOrganisation == organization && ovr.moduleId.getName == name + } match { + case Some(ovr) if Option(ovr.ddm.getVersion).isDefined => + val ovrVersion = ovr.ddm.getVersion + conflicts find { mr => + mr.module.revision == ovrVersion + } match { + case Some(m) => + (Vector(m), conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("override")) + }, "override") + case None => + sys.error( + s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { + _.module + }).mkString("(", ", ", ")") + ) + } + case None => + getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { + case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) + case _: StrictConflictManager => + sys.error( + (s"conflict was found in $rootModuleConf:$organization:$name " + (conflicts map { + _.module + }).mkString("(", ", ", ")")) + ) + case lcm: LatestConflictManager => useLatest(lcm) + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + } + } + if (conflicts.size == 2 && os.isEmpty) { + val (cf0, cf1) = (conflicts(0).module, conflicts(1).module) + val cache = cachedResolutionResolveCache + val (surviving, evicted) = cache.getOrElseUpdateConflict(cf0, cf1, conflicts) { + doResolveConflict + } + (surviving, evicted) + } else { + val (surviving, evicted, _) = doResolveConflict + (surviving, evicted) } + } + def remapInternalProject( + node: IvyNode, + ur: UpdateReport, + md0: ModuleDescriptor, + dd: DependencyDescriptor, + os: Vector[IvyOverride], + log: Logger + ): UpdateReport = { + def parentConfigs(c: String): Vector[String] = + Option(md0.getConfiguration(c)) match { + case Some(config) => + config.getExtends.toVector ++ + (config.getExtends.toVector flatMap parentConfigs) + case None => Vector() + } + // These are the configurations from the original project we want to resolve. + val rootModuleConfs = md0.getConfigurations.toVector + val configurations0 = ur.configurations.toVector + // This is how md looks from md0 via dd's mapping. + val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => + val remapped + : Vector[String] = dd.getDependencyConfigurations(conf0.getName).toVector flatMap { conf => + node.getRealConfs(conf).toVector + } + conf0.getName -> remapped + }: _*) + // This emulates test-internal extending test configuration etc. + val remappedConfigs: Map[String, Vector[String]] = + (remappedConfigs0 /: rootModuleConfs) { (acc0, c) => + val ps = parentConfigs(c.getName) + (acc0 /: ps) { (acc, parent) => + val vs0 = acc.getOrElse(c.getName, Vector()) + val vs = acc.getOrElse(parent, Vector()) + acc.updated(c.getName, (vs0 ++ vs).distinct) + } + } + log.debug(s"::: remapped configs $remappedConfigs") + val configurations = rootModuleConfs map { conf0 => + val remappedCRs = configurations0 filter { cr => + remappedConfigs(conf0.getName) contains cr.configuration + } + mergeConfigurationReports(conf0.getName, remappedCRs, os, log) + } + UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) + } } -private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) extends IvyArtifactInfo { - override def getLastModified: Long = moduleReport.publicationDate map { _.getTimeInMillis } getOrElse 0L +private[sbt] case class ModuleReportArtifactInfo(moduleReport: ModuleReport) + extends IvyArtifactInfo { + override def getLastModified: Long = + moduleReport.publicationDate map { _.getTimeInMillis } getOrElse 0L override def getRevision: String = moduleReport.module.revision - override def toString: String = s"ModuleReportArtifactInfo(${moduleReport.module}, $getRevision, $getLastModified)" + override def toString: String = + s"ModuleReportArtifactInfo(${moduleReport.module}, $getRevision, $getLastModified)" } -private[sbt] case class IvyOverride(moduleId: IvyModuleId, pm: PatternMatcher, ddm: OverrideDependencyDescriptorMediator) { - override def toString: String = s"""IvyOverride($moduleId,$pm,${ddm.getVersion},${ddm.getBranch})""" +private[sbt] case class IvyOverride( + moduleId: IvyModuleId, + pm: PatternMatcher, + ddm: OverrideDependencyDescriptorMediator +) { + override def toString: String = + s"""IvyOverride($moduleId,$pm,${ddm.getVersion},${ddm.getBranch})""" } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala index 3fc19aed9..788b8f1e8 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala @@ -5,8 +5,7 @@ import org.apache.ivy.plugins.resolver.DependencyResolver import sbt.librarymanagement._ // These are placeholder traits for sbt-aether-resolver -trait CustomMavenResolver extends DependencyResolver { -} +trait CustomMavenResolver extends DependencyResolver {} trait CustomRemoteMavenResolver extends CustomMavenResolver { def repo: MavenRepository } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 48cb3bb83..9a19ac6c1 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -44,7 +44,9 @@ object ErrorMessageAuthenticator { case originalOpt => installIntoIvyImpl(originalOpt) } catch { case t: Throwable => - Message.debug("Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage) + Message.debug( + "Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage + ) } Some(ivy) } @@ -57,8 +59,10 @@ object ErrorMessageAuthenticator { catch { case e: SecurityException if !securityWarningLogged => securityWarningLogged = true - Message.warn("Not enough permissions to set the ErrorMessageAuthenticator. " - + "Helpful debug messages disabled!"); + Message.warn( + "Not enough permissions to set the ErrorMessageAuthenticator. " + + "Helpful debug messages disabled!" + ); } // We will try to use the original authenticator as backup authenticator. // Since there is no getter available, so try to use some reflection to @@ -73,6 +77,7 @@ object ErrorMessageAuthenticator { doInstallIfIvy(originalAuthenticator) } } + /** * An authenticator which just delegates to a previous authenticator and issues *nice* * error messages on failure to find credentials. @@ -80,7 +85,8 @@ object ErrorMessageAuthenticator { * Since ivy installs its own credentials handler EVERY TIME it resolves or publishes, we want to * install this one at some point and eventually ivy will capture it and use it. */ -private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticator]) extends Authenticator { +private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticator]) + extends Authenticator { protected override def getPasswordAuthentication(): PasswordAuthentication = { // We're guaranteed to only get here if Ivy's authentication fails @@ -104,14 +110,16 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato // Grabs the authentication that would have been provided had we not been installed... def originalAuthentication: Option[PasswordAuthentication] = { Authenticator.setDefault(original.orNull) - try Option(Authenticator.requestPasswordAuthentication( - getRequestingHost, - getRequestingSite, - getRequestingPort, - getRequestingProtocol, - getRequestingPrompt, - getRequestingScheme - )) + try Option( + Authenticator.requestPasswordAuthentication( + getRequestingHost, + getRequestingSite, + getRequestingPort, + getRequestingProtocol, + getRequestingPrompt, + getRequestingScheme + ) + ) finally Authenticator.setDefault(this) } originalAuthentication.orNull diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index 88a237910..e2e119123 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -6,8 +6,10 @@ import collection.JavaConverters._ /** A key used to store credentials in the ivy credentials store. */ private[sbt] sealed trait CredentialKey + /** Represents a key in the ivy credentials store that is only specific to a host. */ private[sbt] case class Host(name: String) extends CredentialKey + /** Represents a key in the ivy credentials store that is keyed to both a host and a "realm". */ private[sbt] case class Realm(host: String, realm: String) extends CredentialKey @@ -61,4 +63,4 @@ private[sbt] object IvyCredentialsLookup { } mapValues { realms => realms map (_.realm) } -} \ No newline at end of file +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 1f9cfa152..5f361ea5f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -13,25 +13,25 @@ private[sbt] object MergeDescriptors { a.isTransitive == b.isTransitive && a.getParentRevisionId == b.getParentRevisionId && a.getNamespace == b.getNamespace && { - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - amrid == bmrid - } && { - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - adyn == bdyn - } - - def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = - { - assert(mergeable(a, b)) - new MergedDescriptors(a, b) + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn } + + def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { + assert(mergeable(a, b)) + new MergedDescriptors(a, b) + } } // combines the artifacts, configurations, includes, and excludes for DependencyDescriptors `a` and `b` // that otherwise have equal IDs -private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) extends DependencyDescriptor { +private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: DependencyDescriptor) + extends DependencyDescriptor { def getDependencyId = a.getDependencyId def isForce = a.isForce def isChanging = a.isChanging @@ -44,21 +44,41 @@ private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: Depe def getModuleConfigurations = concat(a.getModuleConfigurations, b.getModuleConfigurations) def getDependencyConfigurations(moduleConfiguration: String, requestedConfiguration: String) = - concat(a.getDependencyConfigurations(moduleConfiguration, requestedConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + concat( + a.getDependencyConfigurations(moduleConfiguration, requestedConfiguration), + b.getDependencyConfigurations(moduleConfiguration) + ) def getDependencyConfigurations(moduleConfiguration: String) = - concat(a.getDependencyConfigurations(moduleConfiguration), b.getDependencyConfigurations(moduleConfiguration)) + concat( + a.getDependencyConfigurations(moduleConfiguration), + b.getDependencyConfigurations(moduleConfiguration) + ) def getDependencyConfigurations(moduleConfigurations: Array[String]) = - concat(a.getDependencyConfigurations(moduleConfigurations), b.getDependencyConfigurations(moduleConfigurations)) + concat( + a.getDependencyConfigurations(moduleConfigurations), + b.getDependencyConfigurations(moduleConfigurations) + ) - def getAllDependencyArtifacts = concatArtifacts(a, a.getAllDependencyArtifacts, b, b.getAllDependencyArtifacts) + def getAllDependencyArtifacts = + concatArtifacts(a, a.getAllDependencyArtifacts, b, b.getAllDependencyArtifacts) def getDependencyArtifacts(moduleConfigurations: String) = - concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + concatArtifacts( + a, + a.getDependencyArtifacts(moduleConfigurations), + b, + b.getDependencyArtifacts(moduleConfigurations) + ) def getDependencyArtifacts(moduleConfigurations: Array[String]) = - concatArtifacts(a, a.getDependencyArtifacts(moduleConfigurations), b, b.getDependencyArtifacts(moduleConfigurations)) + concatArtifacts( + a, + a.getDependencyArtifacts(moduleConfigurations), + b, + b.getDependencyArtifacts(moduleConfigurations) + ) def getAllIncludeRules = concat(a.getAllIncludeRules, b.getAllIncludeRules) @@ -68,61 +88,99 @@ private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: Depe def getIncludeRules(moduleConfigurations: Array[String]) = concat(a.getIncludeRules(moduleConfigurations), b.getIncludeRules(moduleConfigurations)) - private[this] def concatArtifacts(a: DependencyDescriptor, as: Array[DependencyArtifactDescriptor], b: DependencyDescriptor, bs: Array[DependencyArtifactDescriptor]) = - { - if (as.isEmpty) - if (bs.isEmpty) as - else defaultArtifact(a) ++ explicitConfigurations(b, bs) - else if (bs.isEmpty) explicitConfigurations(a, as) ++ defaultArtifact(b) - else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) + private[this] def concatArtifacts( + a: DependencyDescriptor, + as: Array[DependencyArtifactDescriptor], + b: DependencyDescriptor, + bs: Array[DependencyArtifactDescriptor] + ) = { + if (as.isEmpty) + if (bs.isEmpty) as + else defaultArtifact(a) ++ explicitConfigurations(b, bs) + else if (bs.isEmpty) explicitConfigurations(a, as) ++ defaultArtifact(b) + else concat(explicitConfigurations(a, as), explicitConfigurations(b, bs)) + } + private[this] def explicitConfigurations( + base: DependencyDescriptor, + arts: Array[DependencyArtifactDescriptor] + ): Array[DependencyArtifactDescriptor] = + arts map { art => + explicitConfigurations(base, art) } - private[this] def explicitConfigurations(base: DependencyDescriptor, arts: Array[DependencyArtifactDescriptor]): Array[DependencyArtifactDescriptor] = - arts map { art => explicitConfigurations(base, art) } - private[this] def explicitConfigurations(base: DependencyDescriptor, art: DependencyArtifactDescriptor): DependencyArtifactDescriptor = - { - val aConfs = Option(art.getConfigurations) map { _.toList } - // In case configuration list is "*", we should still specify the module configuration of the DependencyDescriptor - // otherwise the explicit specified artifacts from one dd can leak over to the other. - // See gh-1500, gh-2002 - aConfs match { - case None | Some(Nil) | Some(List("*")) => copyWithConfigurations(art, base.getModuleConfigurations) - case _ => art - } + private[this] def explicitConfigurations( + base: DependencyDescriptor, + art: DependencyArtifactDescriptor + ): DependencyArtifactDescriptor = { + val aConfs = Option(art.getConfigurations) map { _.toList } + // In case configuration list is "*", we should still specify the module configuration of the DependencyDescriptor + // otherwise the explicit specified artifacts from one dd can leak over to the other. + // See gh-1500, gh-2002 + aConfs match { + case None | Some(Nil) | Some(List("*")) => + copyWithConfigurations(art, base.getModuleConfigurations) + case _ => art } - private[this] def defaultArtifact(a: DependencyDescriptor): Array[DependencyArtifactDescriptor] = - { - val dd = new DefaultDependencyArtifactDescriptor(a, a.getDependencyRevisionId.getName, "jar", "jar", null, null) - addConfigurations(dd, a.getModuleConfigurations) - // If the dependency descriptor is empty, then it means that it has been created from a POM file. In this case, - // it is correct to create a seemingly non-existent dependency artifact. - if (a.getAllDependencyArtifacts.isEmpty) Array(dd) - else a.getAllDependencyArtifacts filter (_ == dd) - } - private[this] def copyWithConfigurations(dd: DependencyArtifactDescriptor, confs: Seq[String]): DependencyArtifactDescriptor = - { - val dextra = dd.getQualifiedExtraAttributes - val newd = new DefaultDependencyArtifactDescriptor(dd.getDependencyDescriptor, dd.getName, dd.getType, dd.getExt, dd.getUrl, dextra) - addConfigurations(newd, confs) - newd - } - private[this] def addConfigurations(dd: DefaultDependencyArtifactDescriptor, confs: Seq[String]): Unit = + } + private[this] def defaultArtifact(a: DependencyDescriptor): Array[DependencyArtifactDescriptor] = { + val dd = new DefaultDependencyArtifactDescriptor( + a, + a.getDependencyRevisionId.getName, + "jar", + "jar", + null, + null + ) + addConfigurations(dd, a.getModuleConfigurations) + // If the dependency descriptor is empty, then it means that it has been created from a POM file. In this case, + // it is correct to create a seemingly non-existent dependency artifact. + if (a.getAllDependencyArtifacts.isEmpty) Array(dd) + else a.getAllDependencyArtifacts filter (_ == dd) + } + private[this] def copyWithConfigurations( + dd: DependencyArtifactDescriptor, + confs: Seq[String] + ): DependencyArtifactDescriptor = { + val dextra = dd.getQualifiedExtraAttributes + val newd = new DefaultDependencyArtifactDescriptor( + dd.getDependencyDescriptor, + dd.getName, + dd.getType, + dd.getExt, + dd.getUrl, + dextra + ) + addConfigurations(newd, confs) + newd + } + private[this] def addConfigurations( + dd: DefaultDependencyArtifactDescriptor, + confs: Seq[String] + ): Unit = confs foreach dd.addConfiguration - private[this] def concat[T: reflect.ClassTag](a: Array[T], b: Array[T]): Array[T] = (a ++ b).distinct + private[this] def concat[T: reflect.ClassTag](a: Array[T], b: Array[T]): Array[T] = + (a ++ b).distinct def getAllExcludeRules = concat(a.getAllExcludeRules, b.getAllExcludeRules) - def getExcludeRules(moduleConfigurations: String) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + def getExcludeRules(moduleConfigurations: String) = + concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) - def getExcludeRules(moduleConfigurations: Array[String]) = concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) + def getExcludeRules(moduleConfigurations: Array[String]) = + concat(a.getExcludeRules(moduleConfigurations), b.getExcludeRules(moduleConfigurations)) - def doesExclude(moduleConfigurations: Array[String], artifactId: ArtifactId) = a.doesExclude(moduleConfigurations, artifactId) || b.doesExclude(moduleConfigurations, artifactId) + def doesExclude(moduleConfigurations: Array[String], artifactId: ArtifactId) = + a.doesExclude(moduleConfigurations, artifactId) || b.doesExclude( + moduleConfigurations, + artifactId + ) def canExclude = a.canExclude || b.canExclude def asSystem = this - def clone(revision: ModuleRevisionId) = new MergedDescriptors(a.clone(revision), b.clone(revision)) + def clone(revision: ModuleRevisionId) = + new MergedDescriptors(a.clone(revision), b.clone(revision)) def getAttribute(name: String): String = a.getAttribute(name) def getAttributes = a.getAttributes diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index afc5bda12..0c7f2c62c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -7,7 +7,12 @@ import java.util.Date import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.{ IvyContext, LogOptions } -import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact, DefaultModuleDescriptor, ModuleDescriptor, DependencyDescriptor } +import org.apache.ivy.core.module.descriptor.{ + Artifact => IArtifact, + DefaultModuleDescriptor, + ModuleDescriptor, + DependencyDescriptor +} import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } import org.apache.ivy.plugins.latest.LatestStrategy import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } @@ -19,11 +24,11 @@ import sbt.util.Logger import sbt.librarymanagement._ private[sbt] case class SbtChainResolver( - name: String, - resolvers: Seq[DependencyResolver], - settings: IvySettings, - updateOptions: UpdateOptions, - log: Logger + name: String, + resolvers: Seq[DependencyResolver], + settings: IvySettings, + updateOptions: UpdateOptions, + log: Logger ) extends ChainResolver { override def equals(o: Any): Boolean = o match { @@ -35,15 +40,14 @@ private[sbt] case class SbtChainResolver( case _ => false } - override def hashCode: Int = - { - var hash = 1 - hash = hash * 31 + this.name.## - hash = hash * 31 + this.resolvers.## - hash = hash * 31 + this.settings.## - hash = hash * 31 + this.updateOptions.## - hash - } + override def hashCode: Int = { + var hash = 1 + hash = hash * 31 + this.name.## + hash = hash * 31 + this.resolvers.## + hash = hash * 31 + this.settings.## + hash = hash * 31 + this.updateOptions.## + hash + } // TODO - We need to special case the project resolver so it always "wins" when resolving with inter-project dependencies. @@ -67,105 +71,119 @@ private[sbt] case class SbtChainResolver( // // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. - override def locate(artifact: IArtifact) = if (IvySbt.hasImplicitClassifier(artifact)) null else super.locate(artifact) + override def locate(artifact: IArtifact) = + if (IvySbt.hasImplicitClassifier(artifact)) null else super.locate(artifact) - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = - { - if (data.getOptions.getLog != LogOptions.LOG_QUIET) - Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") - val gd = doGetDependency(dd, data) - val mod = IvySbt.resetArtifactResolver(gd) - mod - } + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { + if (data.getOptions.getLog != LogOptions.LOG_QUIET) + Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") + val gd = doGetDependency(dd, data) + val mod = IvySbt.resetArtifactResolver(gd) + mod + } // Modified implementation of ChainResolver#getDependency. // When the dependency is changing, it will check all resolvers on the chain // regardless of what the "latest strategy" is set, and look for the published date // or the module descriptor to sort them. // This implementation also skips resolution if "return first" is set to true, // and if a previously resolved or cached revision has been found. - def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = - { - // useLatest - Means we should always download the JARs from the internet, no matter what. - // This will only be true *IF* the depenendency is dynamic/changing *and* latestSnapshots is true. - // If you find multiple candidates, - // - If `isReturnFirst` is true, you return the first value found - // - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and - // leads to undefined behavior. - val useLatest = (dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId)) && updateOptions.latestSnapshots - if (useLatest) { - Message.verbose(s"$getName is changing. Checking all resolvers on the chain") - } - val data = new ResolveData(data0, doValidate(data0)) - // Returns the value if we've already been resolved from some other branch of the resolution tree. - val resolved = Option(data.getCurrentResolvedModuleRevision) - // If we don't have any previously resolved date, we try to pull the value from the cache. - val resolvedOrCached = - resolved orElse { - Message.verbose(getName + ": Checking cache for: " + dd) - Option(findModuleInCache(dd, data, true)) map { mr => - Message.verbose(getName + ": module revision found in cache: " + mr.getId) - forcedRevision(mr) - } + def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { + // useLatest - Means we should always download the JARs from the internet, no matter what. + // This will only be true *IF* the depenendency is dynamic/changing *and* latestSnapshots is true. + // If you find multiple candidates, + // - If `isReturnFirst` is true, you return the first value found + // - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and + // leads to undefined behavior. + val useLatest = (dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId)) && updateOptions.latestSnapshots + if (useLatest) { + Message.verbose(s"$getName is changing. Checking all resolvers on the chain") + } + val data = new ResolveData(data0, doValidate(data0)) + // Returns the value if we've already been resolved from some other branch of the resolution tree. + val resolved = Option(data.getCurrentResolvedModuleRevision) + // If we don't have any previously resolved date, we try to pull the value from the cache. + val resolvedOrCached = + resolved orElse { + Message.verbose(getName + ": Checking cache for: " + dd) + Option(findModuleInCache(dd, data, true)) map { mr => + Message.verbose(getName + ": module revision found in cache: " + mr.getId) + forcedRevision(mr) } + } - // Default value for resolution. We use this while we loop... - // If useLatest is true, we want to try to download from the internet so we DO NOT start with a valid value. - var temp: Option[ResolvedModuleRevision] = - if (useLatest) None - else resolvedOrCached - // Cast resolvers to something useful. TODO - we dropping anything here? - val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } - val interProjResolver = resolvers find { x => x.getName == ProjectResolver.InterProject } + // Default value for resolution. We use this while we loop... + // If useLatest is true, we want to try to download from the internet so we DO NOT start with a valid value. + var temp: Option[ResolvedModuleRevision] = + if (useLatest) None + else resolvedOrCached + // Cast resolvers to something useful. TODO - we dropping anything here? + val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } + val interProjResolver = resolvers find { x => + x.getName == ProjectResolver.InterProject + } - // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. - // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything - // - If we do not, try to resolve. - // RETURNS: Left -> Error - // Right -> Some(resolved module) // Found in this resolver, can use this result. - // Right -> None // Do not use this resolver - lazy val results = resolvers map { x => - // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. - if (isReturnFirst && temp.isDefined && !useLatest) Right(None) - else { - // We actually do resolution. - val resolver = x - val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) - try { - val previouslyResolved = temp - // if the module qualifies as changing, then resolve all resolvers - if (useLatest) data.setCurrentResolvedModuleRevision(null) - else data.setCurrentResolvedModuleRevision(temp.orNull) - temp = Option(resolver.getDependency(dd, data)) - Right( - if (temp eq previouslyResolved) None - else if (useLatest) temp map { x => - (reparseModuleDescriptor(dd, data, resolver, x), resolver) + // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. + // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything + // - If we do not, try to resolve. + // RETURNS: Left -> Error + // Right -> Some(resolved module) // Found in this resolver, can use this result. + // Right -> None // Do not use this resolver + lazy val results = resolvers map { x => + // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. + if (isReturnFirst && temp.isDefined && !useLatest) Right(None) + else { + // We actually do resolution. + val resolver = x + val oldLatest: Option[LatestStrategy] = + setLatestIfRequired(resolver, Option(getLatestStrategy)) + try { + val previouslyResolved = temp + // if the module qualifies as changing, then resolve all resolvers + if (useLatest) data.setCurrentResolvedModuleRevision(null) + else data.setCurrentResolvedModuleRevision(temp.orNull) + temp = Option(resolver.getDependency(dd, data)) + Right( + if (temp eq previouslyResolved) None + else if (useLatest) temp map { x => + (reparseModuleDescriptor(dd, data, resolver, x), resolver) + } else + temp map { x => + (forcedRevision(x), resolver) } - else temp map { x => (forcedRevision(x), resolver) } + ) + } catch { + case ex: Exception => + Message.verbose( + "problem occurred while resolving " + dd + " with " + resolver + + ": " + IvyStringUtils.getStackTrace(ex) ) - } catch { - case ex: Exception => - Message.verbose("problem occurred while resolving " + dd + " with " + resolver - + ": " + IvyStringUtils.getStackTrace(ex)) - Left(ex) - } finally { - oldLatest map { _ => doSetLatestStrategy(resolver, oldLatest) } - checkInterrupted() + Left(ex) + } finally { + oldLatest map { _ => + doSetLatestStrategy(resolver, oldLatest) } + checkInterrupted() } } - lazy val errors = results collect { case Left(e) => e } + } + lazy val errors = results collect { case Left(e) => e } - // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. - val mrOpt: Option[ResolvedModuleRevision] = { - val interProj: Option[ResolvedModuleRevision] = - if (updateOptions.interProjectFirst) interProjResolver flatMap { x => Option(x.getDependency(dd, data)) } - else None - def foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { case Right(Some(x)) => x } - def sorted = - if (useLatest) (foundRevisions.sortBy { + // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. + val mrOpt: Option[ResolvedModuleRevision] = { + val interProj: Option[ResolvedModuleRevision] = + if (updateOptions.interProjectFirst) interProjResolver flatMap { x => + Option(x.getDependency(dd, data)) + } else None + def foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { + case Right(Some(x)) => x + } + def sorted = + if (useLatest)(foundRevisions + .sortBy { case (rmr, resolver) => - Message.warn(s"Sorting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}") + Message.warn( + s"Sorting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}" + ) // Just issue warning about issues with publication date, and fake one on it for now. Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { case None => @@ -173,55 +191,75 @@ private[sbt] case class SbtChainResolver( case (null, _) => // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file if (dd.isChanging) - Message.warn(s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!") + Message.warn( + s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!" + ) 0L case (ivf, dmd: DefaultModuleDescriptor) => val lmd = new java.util.Date(ivf.getLastModified) - Message.debug(s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}") + Message.debug( + s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}" + ) dmd.setPublicationDate(lmd) ivf.getLastModified case _ => - Message.warn(s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!") + Message.warn( + s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!" + ) 0L } case Some(date) => // All other cases ok date.getTime } - }).reverse.headOption map { - case (rmr, resolver) => - Message.warn(s"Choosing $resolver for ${rmr.getId}") - // Now that we know the real latest revision, let's force Ivy to use it - val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) - artifactOpt match { - case Some(artifactRef) => - val systemMd = toSystem(rmr.getDescriptor) - getRepositoryCacheManager.cacheModuleDescriptor(resolver, artifactRef, - toSystem(dd), systemMd.getAllArtifacts.head, None.orNull, getCacheOptions(data)) - case None => // do nothing. There are modules without artifacts - } - rmr - } - else foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + }) + .reverse + .headOption map { + case (rmr, resolver) => + Message.warn(s"Choosing $resolver for ${rmr.getId}") + // Now that we know the real latest revision, let's force Ivy to use it + val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) + artifactOpt match { + case Some(artifactRef) => + val systemMd = toSystem(rmr.getDescriptor) + getRepositoryCacheManager.cacheModuleDescriptor( + resolver, + artifactRef, + toSystem(dd), + systemMd.getAllArtifacts.head, + None.orNull, + getCacheOptions(data) + ) + case None => // do nothing. There are modules without artifacts + } + rmr + } else + foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. - interProj orElse sorted orElse resolvedOrCached - } - mrOpt match { - case None if errors.size == 1 => - errors.head match { - case e: RuntimeException => throw e - case e: ParseException => throw e - case e: Throwable => throw new RuntimeException(e.toString, e) - } - case None if errors.size > 1 => - val err = (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") - throw new RuntimeException(s"several problems occurred while resolving $dd:$err") - case _ => - if (resolved == mrOpt) resolved.orNull - else (mrOpt map { resolvedRevision }).orNull - } + interProj orElse sorted orElse resolvedOrCached } + mrOpt match { + case None if errors.size == 1 => + errors.head match { + case e: RuntimeException => throw e + case e: ParseException => throw e + case e: Throwable => throw new RuntimeException(e.toString, e) + } + case None if errors.size > 1 => + val err = + (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") + throw new RuntimeException(s"several problems occurred while resolving $dd:$err") + case _ => + if (resolved == mrOpt) resolved.orNull + else (mrOpt map { resolvedRevision }).orNull + } + } // Ivy seem to not want to use the module descriptor found at the latest resolver - private[this] def reparseModuleDescriptor(dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, rmr: ResolvedModuleRevision): ResolvedModuleRevision = + private[this] def reparseModuleDescriptor( + dd: DependencyDescriptor, + data: ResolveData, + resolver: DependencyResolver, + rmr: ResolvedModuleRevision + ): ResolvedModuleRevision = // TODO - Redownloading/parsing the ivy file is not really the best way to make this correct. // We should figure out a better alternative, or directly attack the resolvers Ivy uses to // give them correct behavior around -SNAPSHOT. @@ -238,49 +276,76 @@ private[sbt] case class SbtChainResolver( case _ => None } } getOrElse { - Message.warn(s"Unable to reparse ${dd.getDependencyRevisionId} from $resolver, using ${rmr.getPublicationDate}") + Message.warn( + s"Unable to reparse ${dd.getDependencyRevisionId} from $resolver, using ${rmr.getPublicationDate}" + ) rmr } + /** Ported from BasicResolver#findFirstAirfactRef. */ - private[this] def findFirstArtifactRef(md: ModuleDescriptor, dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver): Option[ResolvedResource] = - { - def artifactRef(artifact: IArtifact, date: Date): Option[ResolvedResource] = - resolver match { - case resolver: BasicResolver => - IvyContext.getContext.set(resolver.getName + ".artifact", artifact) - try { - Option(resolver.doFindArtifactRef(artifact, date)) orElse { - Option(artifact.getUrl) map { url => - Message.verbose("\tusing url for " + artifact + ": " + url) - val resource = - if ("file" == url.getProtocol) new FileResource(new IFileRepository(), new File(url.getPath)) - else new URLResource(url) - new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) - } + private[this] def findFirstArtifactRef( + md: ModuleDescriptor, + dd: DependencyDescriptor, + data: ResolveData, + resolver: DependencyResolver + ): Option[ResolvedResource] = { + def artifactRef(artifact: IArtifact, date: Date): Option[ResolvedResource] = + resolver match { + case resolver: BasicResolver => + IvyContext.getContext.set(resolver.getName + ".artifact", artifact) + try { + Option(resolver.doFindArtifactRef(artifact, date)) orElse { + Option(artifact.getUrl) map { url => + Message.verbose("\tusing url for " + artifact + ": " + url) + val resource = + if ("file" == url.getProtocol) + new FileResource(new IFileRepository(), new File(url.getPath)) + else new URLResource(url) + new ResolvedResource(resource, artifact.getModuleRevisionId.getRevision) } - } finally { - IvyContext.getContext.set(resolver.getName + ".artifact", null) } - case _ => - None - } - val artifactRefs = md.getConfigurations.toIterator flatMap { conf => - md.getArtifacts(conf.getName).toIterator flatMap { af => - artifactRef(af, data.getDate).toIterator - } + } finally { + IvyContext.getContext.set(resolver.getName + ".artifact", null) + } + case _ => + None + } + val artifactRefs = md.getConfigurations.toIterator flatMap { conf => + md.getArtifacts(conf.getName).toIterator flatMap { af => + artifactRef(af, data.getDate).toIterator } - if (artifactRefs.hasNext) Some(artifactRefs.next()) - else None } + if (artifactRefs.hasNext) Some(artifactRefs.next()) + else None + } + /** Ported from ChainResolver#forcedRevision. */ private[this] def forcedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = - new ResolvedModuleRevision(rmr.getResolver, rmr.getArtifactResolver, rmr.getDescriptor, rmr.getReport, true) + new ResolvedModuleRevision( + rmr.getResolver, + rmr.getArtifactResolver, + rmr.getDescriptor, + rmr.getReport, + true + ) + /** Ported from ChainResolver#resolvedRevision. */ private[this] def resolvedRevision(rmr: ResolvedModuleRevision): ResolvedModuleRevision = - if (isDual) new ResolvedModuleRevision(rmr.getResolver, this, rmr.getDescriptor, rmr.getReport, rmr.isForce) + if (isDual) + new ResolvedModuleRevision( + rmr.getResolver, + this, + rmr.getDescriptor, + rmr.getReport, + rmr.isForce + ) else rmr + /** Ported from ChainResolver#setLatestIfRequired. */ - private[this] def setLatestIfRequired(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + private[this] def setLatestIfRequired( + resolver: DependencyResolver, + latest: Option[LatestStrategy] + ): Option[LatestStrategy] = latestStrategyName(resolver) match { case Some(latestName) if latestName != "default" => val oldLatest = latestStrategy(resolver) @@ -288,20 +353,26 @@ private[sbt] case class SbtChainResolver( oldLatest case _ => None } + /** Ported from ChainResolver#getLatestStrategyName. */ private[this] def latestStrategyName(resolver: DependencyResolver): Option[String] = resolver match { case r: HasLatestStrategy => Some(r.getLatest) case _ => None } + /** Ported from ChainResolver#getLatest. */ private[this] def latestStrategy(resolver: DependencyResolver): Option[LatestStrategy] = resolver match { case r: HasLatestStrategy => Some(r.getLatestStrategy) case _ => None } + /** Ported from ChainResolver#setLatest. */ - private[this] def doSetLatestStrategy(resolver: DependencyResolver, latest: Option[LatestStrategy]): Option[LatestStrategy] = + private[this] def doSetLatestStrategy( + resolver: DependencyResolver, + latest: Option[LatestStrategy] + ): Option[LatestStrategy] = resolver match { case r: HasLatestStrategy => val oldLatest = latestStrategy(resolver) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index 8ae8b8ef1..c198f046d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -25,13 +25,16 @@ object PomExtraDependencyAttributes { val ExtraAttributesKey = "extraDependencyAttributes" val SbtVersionKey = "sbtVersion" val ScalaVersionKey = "scalaVersion" + /** * Reads the extra dependency attributes out of a maven property. * @param props The properties from an Aether resolution. * @return * A map of module id to extra dependency attributes associated with dependencies on that module. */ - def readFromAether(props: java.util.Map[String, AnyRef]): Map[ModuleRevisionId, Map[String, String]] = { + def readFromAether( + props: java.util.Map[String, AnyRef] + ): Map[ModuleRevisionId, Map[String, String]] = { import scala.collection.JavaConverters._ (props.asScala get ExtraAttributesKey) match { case None => Map.empty @@ -52,7 +55,10 @@ object PomExtraDependencyAttributes { * TODO - maybe we can just parse this directly here. Note the `readFromAether` method uses * whatever we set here. */ - def transferDependencyExtraAttributes(from: Properties, to: java.util.Map[String, AnyRef]): Unit = + def transferDependencyExtraAttributes( + from: Properties, + to: java.util.Map[String, AnyRef] + ): Unit = Option(from.getProperty(ExtraAttributesKey, null)) foreach (to.put(ExtraAttributesKey, _)) /** @@ -72,16 +78,25 @@ object PomExtraDependencyAttributes { item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = - (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include }) + (qualifiedExtra(item) filterKeys { k => + qualifiedIsExtra(k) == include + }) - def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) + def qualifiedIsExtra(k: String): Boolean = + k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) // Reduces the id to exclude custom extra attributes // This makes the id suitable as a key to associate a dependency parsed from a element // with the extra attributes from the section def simplify(id: ModuleRevisionId): ModuleRevisionId = { import scala.collection.JavaConverters._ - ModuleRevisionId.newInstance(id.getOrganisation, id.getName, id.getBranch, id.getRevision, filterCustomExtra(id, include = false).asJava) + ModuleRevisionId.newInstance( + id.getOrganisation, + id.getName, + id.getBranch, + id.getRevision, + filterCustomExtra(id, include = false).asJava + ) } /** parses the sequence of dependencies with extra attribute information, with one dependency per line */ diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index fe662ca78..989ef8ce1 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -16,28 +16,48 @@ abstract class ArtifactExtra { def extraAttributes: Map[String, String] protected[this] def copy( - name: String = name, - `type`: String = `type`, - extension: String = extension, - classifier: Option[String] = classifier, - configurations: Vector[Configuration] = configurations, - url: Option[URL] = url, - extraAttributes: Map[String, String] = extraAttributes + name: String = name, + `type`: String = `type`, + extension: String = extension, + classifier: Option[String] = classifier, + configurations: Vector[Configuration] = configurations, + url: Option[URL] = url, + extraAttributes: Map[String, String] = extraAttributes ): Artifact - def extra(attributes: (String, String)*) = copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) + def extra(attributes: (String, String)*) = + copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) } import Configurations.{ Optional, Pom, Test } abstract class ArtifactFunctions { - def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra) - def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None) - def apply(name: String, `type`: String, extension: String): Artifact = Artifact(name, `type`, extension, None, Vector.empty, None) - def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) - def apply(name: String, url: URL): Artifact = Artifact(name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, Some(url)) + def apply(name: String, extra: Map[String, String]): Artifact = + Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra) + def apply(name: String, classifier: String): Artifact = + Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None) + def apply(name: String, `type`: String, extension: String): Artifact = + Artifact(name, `type`, extension, None, Vector.empty, None) + def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = + Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) + def apply(name: String, url: URL): Artifact = + Artifact( + name, + extract(url, DefaultType), + extract(url, DefaultExtension), + None, + Vector.empty, + Some(url) + ) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[Configuration], url: Option[URL]): Artifact = + def apply( + name: String, + `type`: String, + extension: String, + classifier: Option[String], + configurations: Vector[Configuration], + url: Option[URL] + ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, Map.empty[String, String]) val DefaultExtension = "jar" @@ -66,29 +86,33 @@ abstract class ArtifactFunctions { assert(DefaultSourceTypes contains SourceType) def extract(url: URL, default: String): String = extract(url.toString, default) - def extract(name: String, default: String): String = - { - val i = name.lastIndexOf('.') - if (i >= 0) - name.substring(i + 1) - else - default - } - def defaultArtifact(file: File) = - { - val name = file.getName - val i = name.lastIndexOf('.') - val base = if (i >= 0) name.substring(0, i) else name - Artifact(base, extract(name, DefaultType), extract(name, DefaultExtension), None, Vector.empty, Some(file.toURI.toURL)) - } - def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = - { - import artifact._ - val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } - val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) - val base = CrossVersion.applyCross(artifact.name, cross) - base + "-" + module.revision + classifierStr + "." + artifact.extension - } + def extract(name: String, default: String): String = { + val i = name.lastIndexOf('.') + if (i >= 0) + name.substring(i + 1) + else + default + } + def defaultArtifact(file: File) = { + val name = file.getName + val i = name.lastIndexOf('.') + val base = if (i >= 0) name.substring(0, i) else name + Artifact( + base, + extract(name, DefaultType), + extract(name, DefaultExtension), + None, + Vector.empty, + Some(file.toURI.toURL) + ) + } + def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { + import artifact._ + val classifierStr = classifier match { case None => ""; case Some(c) => "-" + c } + val cross = CrossVersion(module.crossVersion, scalaVersion.full, scalaVersion.binary) + val base = CrossVersion.applyCross(artifact.name, cross) + base + "-" + module.revision + classifierStr + "." + artifact.extension + } val classifierTypeMap = Map(SourceClassifier -> SourceType, DocClassifier -> DocType) @deprecated("Configuration should not be decided from the classifier.", "1.0") @@ -97,7 +121,8 @@ abstract class ArtifactFunctions { Test else Optional - def classifierType(classifier: String): String = classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) + def classifierType(classifier: String): String = + classifierTypeMap.getOrElse(classifier.stripPrefix(TestsClassifier + "-"), DefaultType) /** * Create a classified explicit artifact, to be used when trying to resolve sources|javadocs from Maven. This is @@ -105,5 +130,12 @@ abstract class ArtifactFunctions { * The artifact is created under the default configuration. */ def classified(name: String, classifier: String): Artifact = - Artifact(name, classifierType(classifier), DefaultExtension, Some(classifier), Vector.empty, None) + Artifact( + name, + classifierType(classifier), + DefaultExtension, + Some(classifier), + Vector.empty, + None + ) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala index 0fc32c015..4f1b53200 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala @@ -1,6 +1,11 @@ package sbt.librarymanagement -import org.apache.ivy.plugins.circular.{ CircularDependencyStrategy, WarnCircularDependencyStrategy, IgnoreCircularDependencyStrategy, ErrorCircularDependencyStrategy } +import org.apache.ivy.plugins.circular.{ + CircularDependencyStrategy, + WarnCircularDependencyStrategy, + IgnoreCircularDependencyStrategy, + ErrorCircularDependencyStrategy +} /** * Wrapper around circular dependency strategy. diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 8e30e5c6c..9795ff70a 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -6,7 +6,8 @@ package sbt.librarymanagement object Configurations { def config(name: String) = Configuration(name) def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) + def defaultMavenConfigurations: Seq[Configuration] = + Seq(Compile, Runtime, Test, Provided, Optional) def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) def auxiliary: Seq[Configuration] = Seq(Pom) def names(cs: Seq[Configuration]) = cs.map(_.name) @@ -24,7 +25,8 @@ object Configurations { case _ => c } - def internal(base: Configuration, ext: Configuration*) = config(base.name + "-internal").extend(ext: _*).hide + def internal(base: Configuration, ext: Configuration*) = + config(base.name + "-internal").extend(ext: _*).hide def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) @@ -44,15 +46,24 @@ object Configurations { private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) - private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration - private[sbt] def defaultConfiguration(mavenStyle: Boolean) = if (mavenStyle) Configurations.Compile else Configurations.Default - private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = Set(scala.collection.mutable.Map(configs.map(config => (config.name, config)).toSeq: _*).values.toList: _*) + private[sbt] def DefaultConfiguration(mavenStyle: Boolean) = + if (mavenStyle) DefaultMavenConfiguration else DefaultIvyConfiguration + private[sbt] def defaultConfiguration(mavenStyle: Boolean) = + if (mavenStyle) Configurations.Compile else Configurations.Default + private[sbt] def removeDuplicates(configs: Iterable[Configuration]) = + Set( + scala.collection.mutable + .Map(configs.map(config => (config.name, config)).toSeq: _*) + .values + .toList: _* + ) /** Returns true if the configuration should be under the influence of scalaVersion. */ private[sbt] def underScalaVersion(c: Configuration): Boolean = c match { case Default | Compile | IntegrationTest | Provided | Runtime | Test | Optional | - CompilerPlugin | CompileInternal | RuntimeInternal | TestInternal => true + CompilerPlugin | CompileInternal | RuntimeInternal | TestInternal => + true case config => config.extendsConfigs exists underScalaVersion } @@ -68,8 +79,10 @@ abstract class ConfigurationExtra { require(name != null && !name.isEmpty) require(description != null) - def describedAs(newDescription: String) = Configuration(name, newDescription, isPublic, extendsConfigs, transitive) - def extend(configs: Configuration*) = Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) + def describedAs(newDescription: String) = + Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + def extend(configs: Configuration*) = + Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) def notTransitive = intransitive def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) def hide = Configuration(name, description, false, extendsConfigs, transitive) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index 98d9fe46a..02355408f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -7,8 +7,7 @@ import sbt.util.{ Logger, Level } * A library foo_2.10 and foo_2.11 can potentially be both included on the * library dependency graph by mistake, but it won't be caught by eviction. */ -final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) { -} +final case class ConflictWarning(label: String, level: Level.Value, failOnConflict: Boolean) {} object ConflictWarning { def disable: ConflictWarning = ConflictWarning("", Level.Debug, false) @@ -19,10 +18,15 @@ object ConflictWarning { def apply(config: ConflictWarning, report: UpdateReport, log: Logger): Unit = { processCrossVersioned(config, report, log) } - private[this] def processCrossVersioned(config: ConflictWarning, report: UpdateReport, log: Logger): Unit = { + private[this] def processCrossVersioned( + config: ConflictWarning, + report: UpdateReport, + log: Logger + ): Unit = { val crossMismatches = crossVersionMismatches(report) if (crossMismatches.nonEmpty) { - val pre = s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " + val pre = + s"Modules were resolved with conflicting cross-version suffixes in ${config.label}:\n " val conflictMsgs = for (((org, rawName), fullNames) <- crossMismatches) yield { val suffixes = fullNames.map(getCrossSuffix).mkString(", ") @@ -30,25 +34,26 @@ object ConflictWarning { } log.log(config.level, conflictMsgs.mkString(pre, "\n ", "")) if (config.failOnConflict) { - val summary = crossMismatches.map { case ((org, raw), _) => idString(org, raw) }.mkString(", ") + val summary = + crossMismatches.map { case ((org, raw), _) => idString(org, raw) }.mkString(", ") sys.error("Conflicting cross-version suffixes in: " + summary) } } } /** Map from (organization, rawName) to set of multiple full names. */ - def crossVersionMismatches(report: UpdateReport): Map[(String, String), Set[String]] = - { - val mismatches = report.configurations.flatMap { confReport => - groupByRawName(confReport.allModules).mapValues { modules => - val differentFullNames = modules.map(_.name).toSet - if (differentFullNames.size > 1) differentFullNames else Set.empty[String] - } + def crossVersionMismatches(report: UpdateReport): Map[(String, String), Set[String]] = { + val mismatches = report.configurations.flatMap { confReport => + groupByRawName(confReport.allModules).mapValues { modules => + val differentFullNames = modules.map(_.name).toSet + if (differentFullNames.size > 1) differentFullNames else Set.empty[String] } - (Map.empty[(String, String), Set[String]] /: mismatches)(merge) } + (Map.empty[(String, String), Set[String]] /: mismatches)(merge) + } private[this] def merge[A, B](m: Map[A, Set[B]], b: (A, Set[B])): Map[A, Set[B]] = - if (b._2.isEmpty) m else + if (b._2.isEmpty) m + else m.updated(b._1, m.getOrElse(b._1, Set.empty) ++ b._2) private[this] def groupByRawName(ms: Seq[ModuleID]): Map[(String, String), Seq[ModuleID]] = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala index 55dffa367..4044dfd3e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala @@ -18,6 +18,7 @@ object Credentials { /** Add the provided credentials to Ivy's credentials cache.*/ def add(realm: String, host: String, userName: String, passwd: String): Unit = CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) + /** Load credentials from the given file into Ivy's credentials cache.*/ def add(path: File, log: Logger): Unit = loadCredentials(path) match { @@ -29,20 +30,26 @@ object Credentials { def allDirect(sc: Seq[Credentials]): Seq[DirectCredentials] = sc map toDirect def toDirect(c: Credentials): DirectCredentials = c match { case dc: DirectCredentials => dc - case fc: FileCredentials => loadCredentials(fc.path) match { - case Left(err) => sys.error(err) - case Right(dc) => dc - } + case fc: FileCredentials => + loadCredentials(fc.path) match { + case Left(err) => sys.error(err) + case Right(dc) => dc + } } def loadCredentials(path: File): Either[String, DirectCredentials] = if (path.exists) { val properties = read(path) - def get(keys: List[String]) = keys.flatMap(properties.get).headOption.toRight(keys.head + " not specified in credentials file: " + path) + def get(keys: List[String]) = + keys + .flatMap(properties.get) + .headOption + .toRight(keys.head + " not specified in credentials file: " + path) IvyUtil.separate(List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get)) match { - case (Nil, List(realm, host, user, pass)) => Right(new DirectCredentials(realm, host, user, pass)) - case (errors, _) => Left(errors.mkString("\n")) + case (Nil, List(realm, host, user, pass)) => + Right(new DirectCredentials(realm, host, user, pass)) + case (errors, _) => Left(errors.mkString("\n")) } } else Left("Credentials file " + path + " does not exist") @@ -59,16 +66,20 @@ object Credentials { private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") import collection.JavaConverters._ - private[this] def read(from: File): Map[String, String] = - { - val properties = new java.util.Properties - IO.load(properties, from) - properties.asScala.map { case (k, v) => (k.toString, v.toString.trim) }.toMap - } + private[this] def read(from: File): Map[String, String] = { + val properties = new java.util.Properties + IO.load(properties, from) + properties.asScala.map { case (k, v) => (k.toString, v.toString.trim) }.toMap + } } sealed trait Credentials final class FileCredentials(val path: File) extends Credentials { override def toString = "FileCredentials('" + path + "')" } -final class DirectCredentials(val realm: String, val host: String, val userName: String, val passwd: String) extends Credentials +final class DirectCredentials( + val realm: String, + val host: String, + val userName: String, + val passwd: String +) extends Credentials diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index e4d172b7a..7e90f8c59 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -6,6 +6,7 @@ import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) abstract class CrossVersionFunctions { + /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion @@ -50,7 +51,11 @@ abstract class CrossVersionFunctions { * full version `fullVersion` and binary version `binaryVersion`. The behavior of the * constructed function is as documented for the [[sbt.librarymanagement.CrossVersion]] datatypes. */ - def apply(cross: CrossVersion, fullVersion: String, binaryVersion: String): Option[String => String] = + def apply( + cross: CrossVersion, + fullVersion: String, + binaryVersion: String + ): Option[String => String] = cross match { case _: Disabled => None case b: Binary => append(b.prefix + binaryVersion + b.suffix) @@ -64,10 +69,15 @@ abstract class CrossVersionFunctions { /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = - is flatMap { i => apply(module, i) } + is flatMap { i => + apply(module, i) + } /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ - def substituteCross(artifacts: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] = + def substituteCross( + artifacts: Vector[Artifact], + cross: Option[String => String] + ): Vector[Artifact] = cross match { case None => artifacts case Some(is) => substituteCrossA(artifacts, cross) @@ -83,9 +93,14 @@ abstract class CrossVersionFunctions { name + "_" + cross /** Cross-versions `exclude` according to its `crossVersion`. */ - private[sbt] def substituteCross(exclude: SbtExclusionRule, is: Option[IvyScala]): SbtExclusionRule = { + private[sbt] def substituteCross( + exclude: SbtExclusionRule, + is: Option[IvyScala] + ): SbtExclusionRule = { val fopt: Option[String => String] = - is flatMap { i => CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) } + is flatMap { i => + CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) + } exclude.withName(applyCross(exclude.name, fopt)) } @@ -93,7 +108,10 @@ abstract class CrossVersionFunctions { def substituteCross(a: Artifact, cross: Option[String => String]): Artifact = a.withName(applyCross(a.name, cross)) - private[sbt] def substituteCrossA(as: Vector[Artifact], cross: Option[String => String]): Vector[Artifact] = + private[sbt] def substituteCrossA( + as: Vector[Artifact], + cross: Option[String => String] + ): Vector[Artifact] = as.map(art => substituteCross(art, cross)) /** @@ -101,14 +119,14 @@ abstract class CrossVersionFunctions { * for the given full and binary Scala versions `scalaFullVersion` and `scalaBinaryVersion` * according to the ModuleID's cross-versioning setting. */ - def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => - { - val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) - if (cross.isDefined) - m.withName(applyCross(m.name, cross)).withExplicitArtifacts(substituteCrossA(m.explicitArtifacts, cross)) - else - m - } + def apply(scalaFullVersion: String, scalaBinaryVersion: String): ModuleID => ModuleID = m => { + val cross = apply(m.crossVersion, scalaFullVersion, scalaBinaryVersion) + if (cross.isDefined) + m.withName(applyCross(m.name, cross)) + .withExplicitArtifacts(substituteCrossA(m.explicitArtifacts, cross)) + else + m + } @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") def isStable(v: String): Boolean = isScalaApiCompatible(v) @@ -152,6 +170,7 @@ abstract class CrossVersionFunctions { def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def binaryVersion(full: String, cutoff: String): String = CrossVersionUtil.binaryVersion(full, cutoff) + def binaryVersion(full: String, cutoff: String): String = + CrossVersionUtil.binaryVersion(full, cutoff) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 4dddcab78..43bf8b231 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -6,7 +6,8 @@ import sbt.internal.librarymanagement._ import sbt.util.Logger import sbt.io.Hash -class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) extends LibraryManagement { +class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) + extends LibraryManagement { private[sbt] val ivySbt: IvySbt = new IvySbt(ivyConfiguration) private val sbtOrgTemp = JsonUtil.sbtOrgTemp private val modulePrefixTemp = "temp-module-" @@ -22,12 +23,17 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) def getModule(moduleId: ModuleID, ivyScala: Option[IvyScala]): ivySbt.Module = { val sha1 = Hash.toHex(Hash(moduleId.name)) - val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleId.revision).withConfigurations(moduleId.configurations) + val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleId.revision) + .withConfigurations(moduleId.configurations) getModule(dummyID, Vector(moduleId), UpdateOptions(), ivyScala) } - def getModule(moduleId: ModuleID, deps: Vector[ModuleID], - uo: UpdateOptions = UpdateOptions(), ivyScala: Option[IvyScala]): ivySbt.Module = { + def getModule( + moduleId: ModuleID, + deps: Vector[ModuleID], + uo: UpdateOptions = UpdateOptions(), + ivyScala: Option[IvyScala] + ): ivySbt.Module = { val moduleSetting = InlineConfiguration( validate = false, ivyScala = ivyScala, @@ -51,14 +57,29 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) s"unknown" } - def update(module: ivySbt.Module, retrieveDirectory: File)(predicate: File => Boolean): Option[Seq[File]] = { + def update(module: ivySbt.Module, retrieveDirectory: File)( + predicate: File => Boolean + ): Option[Seq[File]] = { val specialArtifactTypes = Artifact.DefaultSourceTypes union Artifact.DefaultDocTypes val artifactFilter = ArtifactTypeFilter.forbid(specialArtifactTypes) - val retrieveConfiguration = RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern).withSync(false) - val updateConfiguration = UpdateConfiguration(Some(retrieveConfiguration), true, UpdateLogging.DownloadOnly, artifactFilter) + val retrieveConfiguration = + RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern).withSync(false) + val updateConfiguration = UpdateConfiguration( + Some(retrieveConfiguration), + true, + UpdateLogging.DownloadOnly, + artifactFilter + ) log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.") - IvyActions.updateEither(module, updateConfiguration, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, log) match { + IvyActions.updateEither( + module, + updateConfiguration, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + None, + log + ) match { case Left(unresolvedWarning) => log.debug(s"Couldn't retrieve module ${dependenciesNames(module)}.") None diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 644e43579..27900061c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -6,13 +6,25 @@ package sbt.librarymanagement import sbt.io.{ AllPassFilter, NameFilter } trait DependencyFilterExtra { - def moduleFilter(organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, revision: NameFilter = AllPassFilter): ModuleFilter = + def moduleFilter( + organization: NameFilter = AllPassFilter, + name: NameFilter = AllPassFilter, + revision: NameFilter = AllPassFilter + ): ModuleFilter = new ModuleFilter { - def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) + def apply(m: ModuleID): Boolean = + organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) } - def artifactFilter(name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, extension: NameFilter = AllPassFilter, classifier: NameFilter = AllPassFilter): ArtifactFilter = + def artifactFilter( + name: NameFilter = AllPassFilter, + `type`: NameFilter = AllPassFilter, + extension: NameFilter = AllPassFilter, + classifier: NameFilter = AllPassFilter + ): ArtifactFilter = new ArtifactFilter { - def apply(a: Artifact): Boolean = name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier.accept(a.classifier getOrElse "") + def apply(a: Artifact): Boolean = + name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier + .accept(a.classifier getOrElse "") } def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = new ConfigurationFilter { @@ -20,18 +32,32 @@ trait DependencyFilterExtra { } } object DependencyFilter extends DependencyFilterExtra { - def make(configuration: ConfigurationFilter = configurationFilter(), module: ModuleFilter = moduleFilter(), artifact: ArtifactFilter = artifactFilter()): DependencyFilter = + def make( + configuration: ConfigurationFilter = configurationFilter(), + module: ModuleFilter = moduleFilter(), + artifact: ArtifactFilter = artifactFilter() + ): DependencyFilter = new DependencyFilter { - def apply(c: String, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a) + def apply(c: String, m: ModuleID, a: Artifact): Boolean = + configuration(c) && module(m) && artifact(a) } - def apply(x: DependencyFilter, y: DependencyFilter, combine: (Boolean, Boolean) => Boolean): DependencyFilter = + def apply( + x: DependencyFilter, + y: DependencyFilter, + combine: (Boolean, Boolean) => Boolean + ): DependencyFilter = new DependencyFilter { def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) } def allPass: DependencyFilter = configurationFilter() - implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { def apply(m: ModuleID) = f(m) } - implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } - implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = new ConfigurationFilter { def apply(c: String) = f(c) } + implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { + def apply(m: ModuleID) = f(m) + } + implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { + def apply(m: Artifact) = f(m) + } + implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = + new ConfigurationFilter { def apply(c: String) = f(c) } implicit def subDepFilterToFn[Arg](f: SubDepFilter[Arg, _]): Arg => Boolean = f apply _ } trait DependencyFilter { @@ -40,23 +66,34 @@ trait DependencyFilter { final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _) final def --(o: DependencyFilter) = DependencyFilter(this, o, _ && !_) } -sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter { self: Self => +sealed trait SubDepFilter[Arg, Self <: SubDepFilter[Arg, Self]] extends DependencyFilter { + self: Self => def apply(a: Arg): Boolean protected def make(f: Arg => Boolean): Self final def &(o: Self): Self = combine(o, _ && _) final def |(o: Self): Self = combine(o, _ || _) final def -(o: Self): Self = combine(o, _ && !_) - private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = make((m: Arg) => f(this(m), o(m))) + private[this] def combine(o: Self, f: (Boolean, Boolean) => Boolean): Self = + make((m: Arg) => f(this(m), o(m))) } trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter] { - protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(module) + protected final def make(f: ModuleID => Boolean) = new ModuleFilter { + def apply(m: ModuleID) = f(m) + } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + apply(module) } trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] { - protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(artifact) + protected final def make(f: Artifact => Boolean) = new ArtifactFilter { + def apply(m: Artifact) = f(m) + } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + apply(artifact) } trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] { - protected final def make(f: String => Boolean) = new ConfigurationFilter { def apply(m: String) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) + protected final def make(f: String => Boolean) = new ConfigurationFilter { + def apply(m: String) = f(m) + } + final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + apply(configuration) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 853efa332..eff181a25 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -8,13 +8,13 @@ import sbt.util.ShowLines import sbt.internal.librarymanagement.{ InlineConfiguration, IvySbt } final class EvictionWarningOptions private[sbt] ( - val configurations: Seq[Configuration], - val warnScalaVersionEviction: Boolean, - val warnDirectEvictions: Boolean, - val warnTransitiveEvictions: Boolean, - val infoAllEvictions: Boolean, - val showCallers: Boolean, - val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] + val configurations: Seq[Configuration], + val warnScalaVersionEviction: Boolean, + val warnDirectEvictions: Boolean, + val warnTransitiveEvictions: Boolean, + val infoAllEvictions: Boolean, + val showCallers: Boolean, + val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] ) { private[sbt] def configStrings = configurations map { _.name } @@ -30,17 +30,20 @@ final class EvictionWarningOptions private[sbt] ( copy(infoAllEvictions = infoAllEvictions) def withShowCallers(showCallers: Boolean): EvictionWarningOptions = copy(showCallers = showCallers) - def withGuessCompatible(guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean]): EvictionWarningOptions = + def withGuessCompatible( + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] + ): EvictionWarningOptions = copy(guessCompatible = guessCompatible) private[sbt] def copy( - configurations: Seq[Configuration] = configurations, - warnScalaVersionEviction: Boolean = warnScalaVersionEviction, - warnDirectEvictions: Boolean = warnDirectEvictions, - warnTransitiveEvictions: Boolean = warnTransitiveEvictions, - infoAllEvictions: Boolean = infoAllEvictions, - showCallers: Boolean = showCallers, - guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessCompatible + configurations: Seq[Configuration] = configurations, + warnScalaVersionEviction: Boolean = warnScalaVersionEviction, + warnDirectEvictions: Boolean = warnDirectEvictions, + warnTransitiveEvictions: Boolean = warnTransitiveEvictions, + infoAllEvictions: Boolean = infoAllEvictions, + showCallers: Boolean = showCallers, + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = + guessCompatible ): EvictionWarningOptions = new EvictionWarningOptions( configurations = configurations, @@ -63,19 +66,26 @@ object EvictionWarningOptions { lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse - lazy val guessSecondSegment: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { - case (m1, Some(m2), Some(ivyScala)) if m2.name.endsWith("_" + ivyScala.scalaFullVersion) || m2.name.endsWith("_" + ivyScala.scalaBinaryVersion) => + lazy val guessSecondSegment + : PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + case (m1, Some(m2), Some(ivyScala)) + if m2.name.endsWith("_" + ivyScala.scalaFullVersion) || m2.name.endsWith( + "_" + ivyScala.scalaBinaryVersion + ) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => - VersionNumber.SecondSegment.isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + VersionNumber.SecondSegment + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) case _ => false } } - lazy val guessSemVer: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + lazy val guessSemVer + : PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { case (m1, Some(m2), _) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => - VersionNumber.SemVer.isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + VersionNumber.SemVer + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) case _ => false } } @@ -85,12 +95,12 @@ object EvictionWarningOptions { } final class EvictionPair private[sbt] ( - val organization: String, - val name: String, - val winner: Option[ModuleReport], - val evicteds: Vector[ModuleReport], - val includesDirect: Boolean, - val showCallers: Boolean + val organization: String, + val name: String, + val winner: Option[ModuleReport], + val evicteds: Vector[ModuleReport], + val includesDirect: Boolean, + val showCallers: Boolean ) { override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString @@ -118,8 +128,7 @@ object EvictionPair { r.callers match { case Seq() => "" case cs => (cs map { _.caller.toString }).mkString(" (caller: ", ", ", ")") - } - else "" + } else "" r.module.revision + callers }) map { " -> " + _ } getOrElse "" Seq(s"\t* ${a.organization}:${a.name}:${revsStr}$winnerRev") @@ -127,29 +136,42 @@ object EvictionPair { } final class EvictionWarning private[sbt] ( - val options: EvictionWarningOptions, - val scalaEvictions: Seq[EvictionPair], - val directEvictions: Seq[EvictionPair], - val transitiveEvictions: Seq[EvictionPair], - val allEvictions: Seq[EvictionPair] + val options: EvictionWarningOptions, + val scalaEvictions: Seq[EvictionPair], + val directEvictions: Seq[EvictionPair], + val transitiveEvictions: Seq[EvictionPair], + val allEvictions: Seq[EvictionPair] ) { - def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions + def reportedEvictions: Seq[EvictionPair] = + scalaEvictions ++ directEvictions ++ transitiveEvictions private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) } object EvictionWarning { - def apply(module: IvySbt#Module, options: EvictionWarningOptions, report: UpdateReport, log: Logger): EvictionWarning = { + def apply( + module: IvySbt#Module, + options: EvictionWarningOptions, + report: UpdateReport, + log: Logger + ): EvictionWarning = { val evictions = buildEvictions(options, report) processEvictions(module, options, evictions) } - private[sbt] def buildEvictions(options: EvictionWarningOptions, report: UpdateReport): Seq[OrganizationArtifactReport] = { + private[sbt] def buildEvictions( + options: EvictionWarningOptions, + report: UpdateReport + ): Seq[OrganizationArtifactReport] = { val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() - val confs = report.configurations filter { x => options.configStrings contains x.configuration } + val confs = report.configurations filter { x => + options.configStrings contains x.configuration + } confs flatMap { confReport => confReport.details map { detail => if ((detail.modules exists { _.evicted }) && - !(buffer exists { x => (x.organization == detail.organization) && (x.name == detail.name) })) { + !(buffer exists { x => + (x.organization == detail.organization) && (x.name == detail.name) + })) { buffer += detail } } @@ -157,7 +179,11 @@ object EvictionWarning { buffer.toList.toVector } - private[sbt] def isScalaArtifact(module: IvySbt#Module, organization: String, name: String): Boolean = + private[sbt] def isScalaArtifact( + module: IvySbt#Module, + organization: String, + name: String + ): Boolean = module.moduleSettings.ivyScala match { case Some(s) => organization == s.scalaOrganization && @@ -165,7 +191,11 @@ object EvictionWarning { case _ => false } - private[sbt] def processEvictions(module: IvySbt#Module, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport]): EvictionWarning = { + private[sbt] def processEvictions( + module: IvySbt#Module, + options: EvictionWarningOptions, + reports: Seq[OrganizationArtifactReport] + ): EvictionWarning = { val directDependencies = module.moduleSettings match { case x: InlineConfiguration => x.dependencies case _ => Vector.empty @@ -178,19 +208,29 @@ object EvictionWarning { (directDependencies exists { dep => (detail.organization == dep.organization) && (detail.name == dep.name) }) - new EvictionPair(detail.organization, detail.name, winner, evicteds, includesDirect, options.showCallers) + new EvictionPair( + detail.organization, + detail.name, + winner, + evicteds, + includesDirect, + options.showCallers + ) } val scalaEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() val directEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() val transitiveEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => - options.guessCompatible((r.module, p.winner map { _.module }, module.moduleSettings.ivyScala)) + options.guessCompatible( + (r.module, p.winner map { _.module }, module.moduleSettings.ivyScala) + ) } pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => (module.moduleSettings.ivyScala, p.winner) match { - case (Some(s), Some(winner)) if (s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction => + case (Some(s), Some(winner)) + if (s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction => scalaEvictions += p case _ => } @@ -203,8 +243,13 @@ object EvictionWarning { transitiveEvictions += p } } - new EvictionWarning(options, scalaEvictions.toList, - directEvictions.toList, transitiveEvictions.toList, pairs) + new EvictionWarning( + options, + scalaEvictions.toList, + directEvictions.toList, + transitiveEvictions.toList, + pairs + ) } implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 7f7e1dc91..82ddace88 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -14,7 +14,10 @@ abstract class ArtifactTypeFilterExtra { def types: Set[String] def inverted: Boolean - protected[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter + protected[this] def copy( + types: Set[String] = types, + inverted: Boolean = inverted + ): ArtifactTypeFilter def invert = copy(inverted = !inverted) def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted @@ -25,7 +28,9 @@ abstract class ArtifactTypeFilterFunctions { def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { case a: descriptor.Artifact => f.apply(a) } + override def accept(o: Object): Boolean = Option(o) exists { + case a: descriptor.Artifact => f.apply(a) + } } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala index 5a6300430..9d18c9dad 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala @@ -26,10 +26,17 @@ object ScalaArtifacts { def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) - private[sbt] def toolDependencies(org: String, version: String, isDotty: Boolean = false): Seq[ModuleID] = + private[sbt] def toolDependencies( + org: String, + version: String, + isDotty: Boolean = false + ): Seq[ModuleID] = if (isDotty) - Seq(ModuleID(org, DottyIDPrefix, version).withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) - .withCrossVersion(CrossVersion.binary)) + Seq( + ModuleID(org, DottyIDPrefix, version) + .withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) + .withCrossVersion(CrossVersion.binary) + ) else Seq( scalaToolDependency(org, ScalaArtifacts.CompilerID, version), @@ -37,7 +44,9 @@ object ScalaArtifacts { ) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = - ModuleID(org, id, version).withConfigurations(Some(Configurations.ScalaTool.name + "->default,optional(default)")) + ModuleID(org, id, version).withConfigurations( + Some(Configurations.ScalaTool.name + "->default,optional(default)") + ) } object SbtArtifacts { val Organization = "org.scala-sbt" @@ -46,17 +55,39 @@ object SbtArtifacts { import ScalaArtifacts._ private[sbt] abstract class IvyScalaFunctions { + /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ - def checkModule(module: DefaultModuleDescriptor, conf: String, scalaVersionConfigs: Vector[String], log: Logger)(check: IvyScala): Unit = { + def checkModule( + module: DefaultModuleDescriptor, + conf: String, + scalaVersionConfigs: Vector[String], + log: Logger + )(check: IvyScala): Unit = { if (check.checkExplicit) - checkDependencies(module, check.scalaOrganization, check.scalaArtifacts, check.scalaBinaryVersion, scalaVersionConfigs, log) + checkDependencies( + module, + check.scalaOrganization, + check.scalaArtifacts, + check.scalaBinaryVersion, + scalaVersionConfigs, + log + ) if (check.filterImplicit) excludeScalaJars(module, check.configurations) if (check.overrideScalaVersion) - overrideScalaVersion(module, check.scalaOrganization, check.scalaFullVersion, scalaVersionConfigs) + overrideScalaVersion( + module, + check.scalaOrganization, + check.scalaFullVersion, + scalaVersionConfigs + ) } - class OverrideScalaMediator(scalaOrganization: String, scalaVersion: String, scalaVersionConfigs0: Vector[String]) extends DependencyDescriptorMediator { + class OverrideScalaMediator( + scalaOrganization: String, + scalaVersion: String, + scalaVersionConfigs0: Vector[String] + ) extends DependencyDescriptorMediator { private[this] val scalaVersionConfigs = scalaVersionConfigs0.toSet def mediate(dd: DependencyDescriptor): DependencyDescriptor = { // Mediate only for the dependencies in scalaVersion configurations. https://github.com/sbt/sbt/issues/2786 @@ -79,8 +110,15 @@ private[sbt] abstract class IvyScalaFunctions { if (mrid == null) mrid else mrid.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) if configQualifies && dependeeQualifies => - ModuleRevisionId.newInstance(scalaOrganization, name, mrid.getBranch, scalaVersion, mrid.getQualifiedExtraAttributes) + case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) + if configQualifies && dependeeQualifies => + ModuleRevisionId.newInstance( + scalaOrganization, + name, + mrid.getBranch, + scalaVersion, + mrid.getQualifiedExtraAttributes + ) case _ => mrid } } @@ -92,14 +130,32 @@ private[sbt] abstract class IvyScalaFunctions { } } - def overrideScalaVersion(module: DefaultModuleDescriptor, organization: String, version: String, scalaVersionConfigs: Vector[String]): Unit = { + def overrideScalaVersion( + module: DefaultModuleDescriptor, + organization: String, + version: String, + scalaVersionConfigs: Vector[String] + ): Unit = { val mediator = new OverrideScalaMediator(organization, version, scalaVersionConfigs) - module.addDependencyDescriptorMediator(new ModuleId(Organization, "*"), ExactPatternMatcher.INSTANCE, mediator) + module.addDependencyDescriptorMediator( + new ModuleId(Organization, "*"), + ExactPatternMatcher.INSTANCE, + mediator + ) if (organization != Organization) - module.addDependencyDescriptorMediator(new ModuleId(organization, "*"), ExactPatternMatcher.INSTANCE, mediator) + module.addDependencyDescriptorMediator( + new ModuleId(organization, "*"), + ExactPatternMatcher.INSTANCE, + mediator + ) } - def overrideVersion(module: DefaultModuleDescriptor, org: String, name: String, version: String): Unit = { + def overrideVersion( + module: DefaultModuleDescriptor, + org: String, + name: String, + version: String + ): Unit = { val id = new ModuleId(org, name) val over = new OverrideDependencyDescriptorMediator(null, version) module.addDependencyDescriptorMediator(id, ExactPatternMatcher.INSTANCE, over) @@ -109,71 +165,98 @@ private[sbt] abstract class IvyScalaFunctions { * Checks the immediate dependencies of module for dependencies on scala jars and verifies that the version on the * dependencies matches scalaVersion. */ - private def checkDependencies(module: ModuleDescriptor, scalaOrganization: String, scalaArtifacts: Vector[String], scalaBinaryVersion: String, scalaVersionConfigs0: Vector[String], log: Logger): Unit = { - val scalaVersionConfigs: String => Boolean = if (scalaVersionConfigs0.isEmpty) (c: String) => false else scalaVersionConfigs0.toSet - def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = - { - val id = dep.getDependencyRevisionId - val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) - def isScalaLangOrg = id.getOrganisation == scalaOrganization - def isScalaArtifact = scalaArtifacts.contains(id.getName) - def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion - def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } - val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs - if (mismatched) - Some("Binary version (" + depBinaryVersion + ") for dependency " + id + + private def checkDependencies( + module: ModuleDescriptor, + scalaOrganization: String, + scalaArtifacts: Vector[String], + scalaBinaryVersion: String, + scalaVersionConfigs0: Vector[String], + log: Logger + ): Unit = { + val scalaVersionConfigs: String => Boolean = + if (scalaVersionConfigs0.isEmpty) (c: String) => false else scalaVersionConfigs0.toSet + def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { + val id = dep.getDependencyRevisionId + val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) + def isScalaLangOrg = id.getOrganisation == scalaOrganization + def isScalaArtifact = scalaArtifacts.contains(id.getName) + def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion + def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } + val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs + if (mismatched) + Some( + "Binary version (" + depBinaryVersion + ") for dependency " + id + "\n\tin " + module.getModuleRevisionId + - " differs from Scala binary version in project (" + scalaBinaryVersion + ").") - else - None - } - module.getDependencies.toList.flatMap(binaryScalaWarning).toSet foreach { (s: String) => log.warn(s) } + " differs from Scala binary version in project (" + scalaBinaryVersion + ")." + ) + else + None + } + module.getDependencies.toList.flatMap(binaryScalaWarning).toSet foreach { (s: String) => + log.warn(s) + } } - private def configurationSet(configurations: Iterable[Configuration]) = configurations.map(_.toString).toSet + private def configurationSet(configurations: Iterable[Configuration]) = + configurations.map(_.toString).toSet /** * Adds exclusions for the scala library and compiler jars so that they are not downloaded. This is * done because these jars are provided by the ScalaInstance of the project. The version of Scala to use * is done by setting scalaVersion in the project definition. */ - private def excludeScalaJars(module: DefaultModuleDescriptor, configurations: Iterable[Configuration]): Unit = { - val configurationNames = - { - val names = module.getConfigurationsNames - if (configurations.isEmpty) - names - else { - val configSet = configurationSet(configurations) - configSet.intersect(HashSet(names: _*)) - configSet.toArray - } + private def excludeScalaJars( + module: DefaultModuleDescriptor, + configurations: Iterable[Configuration] + ): Unit = { + val configurationNames = { + val names = module.getConfigurationsNames + if (configurations.isEmpty) + names + else { + val configSet = configurationSet(configurations) + configSet.intersect(HashSet(names: _*)) + configSet.toArray } + } def excludeScalaJar(name: String): Unit = module.addExcludeRule(excludeRule(Organization, name, configurationNames, "jar")) excludeScalaJar(LibraryID) excludeScalaJar(CompilerID) } + /** * Creates an ExcludeRule that excludes artifacts with the given module organization and name for * the given configurations. */ - private[sbt] def excludeRule(organization: String, name: String, configurationNames: Iterable[String], excludeTypePattern: String): ExcludeRule = - { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", excludeTypePattern, "*") - val rule = new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) - configurationNames.foreach(rule.addConfiguration) - rule - } + private[sbt] def excludeRule( + organization: String, + name: String, + configurationNames: Iterable[String], + excludeTypePattern: String + ): ExcludeRule = { + val artifact = + new ArtifactId(ModuleId.newInstance(organization, name), "*", excludeTypePattern, "*") + val rule = + new DefaultExcludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } /** * Creates an IncludeRule that includes artifacts with the given module organization and name for * the given configurations. */ - private[sbt] def includeRule(organization: String, name: String, configurationNames: Iterable[String], includeTypePattern: String): IncludeRule = - { - val artifact = new ArtifactId(ModuleId.newInstance(organization, name), "*", includeTypePattern, "*") - val rule = new DefaultIncludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) - configurationNames.foreach(rule.addConfiguration) - rule - } + private[sbt] def includeRule( + organization: String, + name: String, + configurationNames: Iterable[String], + includeTypePattern: String + ): IncludeRule = { + val artifact = + new ArtifactId(ModuleId.newInstance(organization, name), "*", includeTypePattern, "*") + val rule = + new DefaultIncludeRule(artifact, ExactPatternMatcher.INSTANCE, emptyMap[AnyRef, AnyRef]) + configurationNames.foreach(rule.addConfiguration) + rule + } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 572fd194d..7fbb5f348 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -24,53 +24,56 @@ abstract class ModuleIDExtra { def branchName: Option[String] protected[this] def copy( - organization: String = organization, - name: String = name, - revision: String = revision, - configurations: Option[String] = configurations, - isChanging: Boolean = isChanging, - isTransitive: Boolean = isTransitive, - isForce: Boolean = isForce, - explicitArtifacts: Vector[Artifact] = explicitArtifacts, - inclusions: Vector[InclusionRule] = inclusions, - exclusions: Vector[ExclusionRule] = exclusions, - extraAttributes: Map[String, String] = extraAttributes, - crossVersion: CrossVersion = crossVersion, - branchName: Option[String] = branchName + organization: String = organization, + name: String = name, + revision: String = revision, + configurations: Option[String] = configurations, + isChanging: Boolean = isChanging, + isTransitive: Boolean = isTransitive, + isForce: Boolean = isForce, + explicitArtifacts: Vector[Artifact] = explicitArtifacts, + inclusions: Vector[InclusionRule] = inclusions, + exclusions: Vector[ExclusionRule] = exclusions, + extraAttributes: Map[String, String] = extraAttributes, + crossVersion: CrossVersion = crossVersion, + branchName: Option[String] = branchName ): ModuleID protected def toStringImpl: String = s"""$organization:$name:$revision""" + - (configurations match { case Some(s) => ":" + s; case None => "" }) + - { - val attr = attributeString - if (attr == "") "" - else " " + attr - } + + (configurations match { case Some(s) => ":" + s; case None => "" }) + { + val attr = attributeString + if (attr == "") "" + else " " + attr + } + (if (extraAttributes.isEmpty) "" else " " + extraString) - protected def attributeString: String = - { - val buffer = ListBuffer.empty[String] - if (isChanging) { - buffer += "changing" - } - if (!isTransitive) { - buffer += "intransitive" - } - if (isForce) { - buffer += "force" - } - buffer.toList.mkString(";") + protected def attributeString: String = { + val buffer = ListBuffer.empty[String] + if (isChanging) { + buffer += "changing" } + if (!isTransitive) { + buffer += "intransitive" + } + if (isForce) { + buffer += "force" + } + buffer.toList.mkString(";") + } /** String representation of the extra attributes, excluding any information only attributes. */ - def extraString: String = extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") + def extraString: String = + extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ - def extraDependencyAttributes: Map[String, String] = extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)) + def extraDependencyAttributes: Map[String, String] = + extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)) - @deprecated("Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", "0.12.0") + @deprecated( + "Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", + "0.12.0" + ) def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled()) /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ @@ -111,7 +114,8 @@ abstract class ModuleIDExtra { * Declares the explicit artifacts for this module. If this ModuleID represents a dependency, * these artifact definitions override the information in the dependency's published metadata. */ - def artifacts(newArtifacts: Artifact*) = copy(explicitArtifacts = newArtifacts.toVector ++ explicitArtifacts) + def artifacts(newArtifacts: Artifact*) = + copy(explicitArtifacts = newArtifacts.toVector ++ explicitArtifacts) /** * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify @@ -120,13 +124,15 @@ abstract class ModuleIDExtra { def excludeAll(rules: InclExclRule*) = copy(exclusions = this.exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = excludeAll(InclExclRule().withOrganization(org).withName(name)) + def exclude(org: String, name: String) = + excludeAll(InclExclRule().withOrganization(org).withName(name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. * This information will only be published in an ivy.xml and not in a pom.xml. */ - def extra(attributes: (String, String)*) = copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) + def extra(attributes: (String, String)*) = + copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred @@ -175,7 +181,9 @@ abstract class ModuleIDExtra { } abstract class ModuleIDFunctions { + /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = - for ((key, value) <- attributes) yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) + for ((key, value) <- attributes) + yield if (key.startsWith("e:")) (key, value) else ("e:" + key, value) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index b772e0840..077c3ae1f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -18,12 +18,11 @@ final class RawRepository(val resolver: DependencyResolver) extends Resolver(res case _ => false } - override def hashCode: Int = - { - var hash = 1 - hash = hash * 31 + this.name.## - hash - } + override def hashCode: Int = { + var hash = 1 + hash = hash * 31 + this.name.## + hash + } } abstract class MavenRepositoryFunctions { @@ -37,11 +36,15 @@ abstract class PatternsFunctions { def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*) def apply(isMavenCompatible: Boolean, artifactPatterns: String*): Patterns = { val patterns = artifactPatterns.toVector - Patterns().withIvyPatterns(patterns).withArtifactPatterns(patterns).withIsMavenCompatible(isMavenCompatible) + Patterns() + .withIvyPatterns(patterns) + .withArtifactPatterns(patterns) + .withIsMavenCompatible(isMavenCompatible) } } trait SshBasedRepositoryExtra { + /** The object representing the configured ssh connection for this repository. */ def connection: SshConnection @@ -53,11 +56,13 @@ trait SshBasedRepositoryExtra { /** Configures this to use the specified user name and password when connecting to the remote repository. */ def as(user: String, password: String): RepositoryType = as(user, Some(password)) def as(user: String): RepositoryType = as(user, None) - def as(user: String, password: Option[String]): RepositoryType = copy(PasswordAuthentication(user, password)) + def as(user: String, password: Option[String]): RepositoryType = + copy(PasswordAuthentication(user, password)) /** Configures this to use the specified keyfile and password for the keyfile when connecting to the remote repository. */ def as(user: String, keyfile: File): RepositoryType = as(user, keyfile, None) - def as(user: String, keyfile: File, password: String): RepositoryType = as(user, keyfile, Some(password)) + def as(user: String, keyfile: File, password: String): RepositoryType = + as(user, keyfile, Some(password)) def as(user: String, keyfile: File, password: Option[String]): RepositoryType = copy(KeyFileAuthentication(user, keyfile, password)) @@ -80,7 +85,8 @@ trait SftpRepositoryExtra extends SshBasedRepositoryExtra { type RepositoryType = SftpRepository - protected def copy(connection: SshConnection): SftpRepository = SftpRepository(name, connection, patterns) + protected def copy(connection: SshConnection): SftpRepository = + SftpRepository(name, connection, patterns) } /** A repository that conforms to sbt launcher's interface */ @@ -96,7 +102,8 @@ trait ResolversSyntax { } abstract class ResolverFunctions { - private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true + private[sbt] def useSecureResolvers = + sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) val SbtRepositoryRoot = sbtRepositoryRoot(useSecureResolvers) @@ -109,31 +116,49 @@ abstract class ResolverFunctions { val JCenterRepositoryRoot = "https://jcenter.bintray.com/" val DefaultMavenRepositoryRoot = "https://repo1.maven.org/maven2/" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. - private[sbt] def centralRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo1.maven.org/maven2/" + private[sbt] def centralRepositoryRoot(secure: Boolean) = + (if (secure) "https" else "http") + "://repo1.maven.org/maven2/" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def javanet2RepositoryRoot(secure: Boolean) = if (secure) "https://maven.java.net/content/repositories/public/" else "http://download.java.net/maven/2" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. - private[sbt] def typesafeRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" + private[sbt] def typesafeRepositoryRoot(secure: Boolean) = + (if (secure) "https" else "http") + "://repo.typesafe.com/typesafe" // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. - private[sbt] def sbtRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" + private[sbt] def sbtRepositoryRoot(secure: Boolean) = + (if (secure) "https" else "http") + "://repo.scala-sbt.org/scalasbt" // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" - private[sbt] val ScalaToolsReleases = MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) - private[sbt] val ScalaToolsSnapshots = MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) + private[sbt] val ScalaToolsReleases = + MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) + private[sbt] val ScalaToolsSnapshots = + MavenRepository(ScalaToolsSnapshotsName, ScalaToolsSnapshotsRoot) - def typesafeRepo(status: String) = MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) - def typesafeIvyRepo(status: String) = url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))(ivyStylePatterns) - def sbtIvyRepo(status: String) = url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) - def sbtPluginRepo(status: String) = url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))(ivyStylePatterns) - def sonatypeRepo(status: String) = MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) - def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") - def bintrayIvyRepo(owner: String, repo: String) = url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))(Resolver.ivyStylePatterns) + def typesafeRepo(status: String) = + MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) + def typesafeIvyRepo(status: String) = + url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))( + ivyStylePatterns + ) + def sbtIvyRepo(status: String) = + url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) + def sbtPluginRepo(status: String) = + url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( + ivyStylePatterns + ) + def sonatypeRepo(status: String) = + MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + def bintrayRepo(owner: String, repo: String) = + MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") + def bintrayIvyRepo(owner: String, repo: String) = + url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))( + Resolver.ivyStylePatterns + ) def jcenterRepo = JCenterRepository /** Add the local and Maven Central repositories to the user repositories. */ @@ -152,7 +177,11 @@ abstract class ResolverFunctions { * If `jcenter` is true, add the JCenter. * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], jcenter: Boolean, mavenCentral: Boolean): Seq[Resolver] = + def withDefaultResolvers( + userResolvers: Seq[Resolver], + jcenter: Boolean, + mavenCentral: Boolean + ): Seq[Resolver] = Seq(Resolver.defaultLocal) ++ userResolvers ++ single(JCenterRepository, jcenter) ++ @@ -163,7 +192,11 @@ abstract class ResolverFunctions { * If `jcenter` is true, add the JCenter. * If `mavenCentral` is true, add the Maven Central repository. */ - private[sbt] def reorganizeAppResolvers(appResolvers: Seq[Resolver], jcenter: Boolean, mavenCentral: Boolean): Seq[Resolver] = + private[sbt] def reorganizeAppResolvers( + appResolvers: Seq[Resolver], + jcenter: Boolean, + mavenCentral: Boolean + ): Seq[Resolver] = appResolvers.partition(_ == Resolver.defaultLocal) match { case (locals, xs) => locals ++ @@ -181,78 +214,111 @@ abstract class ResolverFunctions { /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ sealed abstract class Define[RepositoryType <: SshBasedRepository] { + /** Subclasses should implement this method to */ - protected def construct(name: String, connection: SshConnection, patterns: Patterns): RepositoryType + protected def construct( + name: String, + connection: SshConnection, + patterns: Patterns + ): RepositoryType + /** * Constructs this repository type with the given `name`. `basePatterns` are the initial patterns to use. A ManagedProject * has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ def apply(name: String)(implicit basePatterns: Patterns): RepositoryType = apply(name, None, None, None) + /** * Constructs this repository type with the given `name` and `hostname`. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ def apply(name: String, hostname: String)(implicit basePatterns: Patterns): RepositoryType = apply(name, Some(hostname), None, None) + /** * Constructs this repository type with the given `name`, `hostname`, and the `basePath` against which the initial * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + def apply(name: String, hostname: String, basePath: String)( + implicit basePatterns: Patterns + ): RepositoryType = apply(name, Some(hostname), None, Some(basePath)) + /** * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int)(implicit basePatterns: Patterns): RepositoryType = + def apply(name: String, hostname: String, port: Int)( + implicit basePatterns: Patterns + ): RepositoryType = apply(name, Some(hostname), Some(port), None) + /** * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int, basePath: String)(implicit basePatterns: Patterns): RepositoryType = + def apply(name: String, hostname: String, port: Int, basePath: String)( + implicit basePatterns: Patterns + ): RepositoryType = apply(name, Some(hostname), Some(port), Some(basePath)) + /** * Constructs this repository type with the given `name`, `hostname`, `port`, and the `basePath` against which the initial * patterns will be resolved. `basePatterns` are the initial patterns to use. All but the `name` are optional (use None). * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])(implicit basePatterns: Patterns): RepositoryType = + def apply(name: String, hostname: Option[String], port: Option[Int], basePath: Option[String])( + implicit basePatterns: Patterns + ): RepositoryType = construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) } + /** A factory to construct an interface to an Ivy SSH resolver.*/ object ssh extends Define[SshRepository] { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = + SshRepository(name, connection, patterns, None) } + /** A factory to construct an interface to an Ivy SFTP resolver.*/ object sftp extends Define[SftpRepository] { - protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) + protected def construct(name: String, connection: SshConnection, patterns: Patterns) = + SftpRepository(name, connection, patterns) } + /** A factory to construct an interface to an Ivy filesystem resolver. */ object file { + /** * Constructs a file resolver with the given name. The patterns to use must be explicitly specified * using the `ivys` or `artifacts` methods on the constructed resolver object. */ - def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) + def apply(name: String): FileRepository = + FileRepository(name, defaultFileConfiguration, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(new File(baseDirectory.toURI.normalize).getAbsolutePath)(FileRepository(name, defaultFileConfiguration, _)) + baseRepository(new File(baseDirectory.toURI.normalize).getAbsolutePath)( + FileRepository(name, defaultFileConfiguration, _) + ) } object url { + /** * Constructs a URL resolver with the given name. The patterns to use must be explicitly specified * using the `ivys` or `artifacts` methods on the constructed resolver object. */ def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) + /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) } - private def baseRepository[T](base: String)(construct: Patterns => T)(implicit basePatterns: Patterns): T = + private def baseRepository[T](base: String)(construct: Patterns => T)( + implicit basePatterns: Patterns + ): T = construct(resolvePatterns(base, basePatterns)) /** @@ -264,41 +330,53 @@ abstract class ResolverFunctions { case Some(path) => resolvePatterns(path, patterns) case None => patterns } + /** Resolves the ivy file and artifact patterns in `patterns` against the given base. */ - private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = - { - def resolveAll(patterns: Vector[String]) = patterns.map(p => resolvePattern(base, p)) - Patterns(resolveAll(basePatterns.ivyPatterns), resolveAll(basePatterns.artifactPatterns), basePatterns.isMavenCompatible, basePatterns.descriptorOptional, basePatterns.skipConsistencyCheck) - } - private[sbt] def resolvePattern(base: String, pattern: String): String = - { - val normBase = base.replace('\\', '/') - if (normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern else normBase + "/" + pattern - } + private def resolvePatterns(base: String, basePatterns: Patterns): Patterns = { + def resolveAll(patterns: Vector[String]) = patterns.map(p => resolvePattern(base, p)) + Patterns( + resolveAll(basePatterns.ivyPatterns), + resolveAll(basePatterns.artifactPatterns), + basePatterns.isMavenCompatible, + basePatterns.descriptorOptional, + basePatterns.skipConsistencyCheck + ) + } + private[sbt] def resolvePattern(base: String, pattern: String): String = { + val normBase = base.replace('\\', '/') + if (normBase.endsWith("/") || pattern.startsWith("/")) normBase + pattern + else normBase + "/" + pattern + } def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern)) def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns - def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" - def localBasePattern = "[organisation]/[module]/" + PluginPattern + "(/[branch])/[revision]/[type]s/[artifact](-[classifier]).[ext]" - def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" + def mavenStyleBasePattern = + "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" + def localBasePattern = + "[organisation]/[module]/" + PluginPattern + "(/[branch])/[revision]/[type]s/[artifact](-[classifier]).[ext]" + def defaultRetrievePattern = + "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { val file = f() if (!file.exists) None - else ((XML.loadFile(file) \ "localRepository").text match { - case "" => None - case e @ _ => Some(new File(e)) - }) + else + ((XML.loadFile(file) \ "localRepository").text match { + case "" => None + case e @ _ => Some(new File(e)) + }) } catch { // Occurs inside File constructor when property or environment variable does not exist case _: NullPointerException => None // Occurs when File does not exist - case _: IOException => None - case e: SAXParseException => System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); None + case _: IOException => None + case e: SAXParseException => + System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); + None } loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse @@ -309,14 +387,16 @@ abstract class ResolverFunctions { def mavenLocal: MavenRepository = new MavenCache("Maven2 Local", mavenLocalDir) def defaultLocal = defaultUserFileRepository("local") def defaultShared = defaultUserFileRepository("shared") - def defaultUserFileRepository(id: String) = - { - val pList = Vector(s"$${ivy.home}/$id/$localBasePattern") - FileRepository(id, defaultFileConfiguration, Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false)) - } - def defaultIvyPatterns = - { - val pList = Vector(localBasePattern) + def defaultUserFileRepository(id: String) = { + val pList = Vector(s"$${ivy.home}/$id/$localBasePattern") + FileRepository( + id, + defaultFileConfiguration, Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) - } + ) + } + def defaultIvyPatterns = { + val pList = Vector(localBasePattern) + Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) + } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 1d6e6c473..6d7e1c581 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -8,12 +8,11 @@ import java.io.File * and for obtaining references to a selected subset of the underlying files. */ final class RichUpdateReport(report: UpdateReport) { - private[sbt] def recomputeStamps(): UpdateReport = - { - val files = report.cachedDescriptor +: allFiles - val stamps = files.map(f => (f, f.lastModified)).toMap - UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) - } + private[sbt] def recomputeStamps(): UpdateReport = { + val files = report.cachedDescriptor +: allFiles + val stamps = files.map(f => (f, f.lastModified)).toMap + UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) + } import DependencyFilter._ @@ -24,12 +23,19 @@ final class RichUpdateReport(report: UpdateReport) { def matching(f: DependencyFilter): Vector[File] = select0(f).distinct /** Obtains all successfully retrieved files matching all provided filters. */ - def select(configuration: ConfigurationFilter, module: ModuleFilter, artifact: ArtifactFilter): Vector[File] = + def select( + configuration: ConfigurationFilter, + module: ModuleFilter, + artifact: ArtifactFilter + ): Vector[File] = matching(DependencyFilter.make(configuration, module, artifact)) - def select(configuration: ConfigurationFilter): Vector[File] = select(configuration, moduleFilter(), artifactFilter()) - def select(module: ModuleFilter): Vector[File] = select(configurationFilter(), module, artifactFilter()) - def select(artifact: ArtifactFilter): Vector[File] = select(configurationFilter(), moduleFilter(), artifact) + def select(configuration: ConfigurationFilter): Vector[File] = + select(configuration, moduleFilter(), artifactFilter()) + def select(module: ModuleFilter): Vector[File] = + select(configurationFilter(), module, artifactFilter()) + def select(artifact: ArtifactFilter): Vector[File] = + select(configurationFilter(), moduleFilter(), artifact) private[this] def select0(f: DependencyFilter): Vector[File] = for { @@ -39,7 +45,9 @@ final class RichUpdateReport(report: UpdateReport) { if f(cReport.configuration, mReport.module, artifact) } yield { if (file == null) { - sys.error(s"Null file: conf=${cReport.configuration}, module=${mReport.module}, art: $artifact") + sys.error( + s"Null file: conf=${cReport.configuration}, module=${mReport.module}, art: $artifact" + ) } file } @@ -49,14 +57,20 @@ final class RichUpdateReport(report: UpdateReport) { moduleReportMap { (configuration, modReport) => modReport .withArtifacts( - modReport.artifacts filter { case (art, file) => f(configuration, modReport.module, art) } + modReport.artifacts filter { + case (art, file) => f(configuration, modReport.module, art) + } ) .withMissingArtifacts( - modReport.missingArtifacts filter { art => f(configuration, modReport.module, art) } + modReport.missingArtifacts filter { art => + f(configuration, modReport.module, art) + } ) } - private[sbt] def substitute(f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)]): UpdateReport = + private[sbt] def substitute( + f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)] + ): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) modReport @@ -85,13 +99,14 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts((modReport.missingArtifacts ++ f(modReport.module)).distinct) } - private[sbt] def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = - { - val newConfigurations = report.configurations.map { confReport => - import confReport._ - val newModules = modules map { modReport => f(configuration, modReport) } - ConfigurationReport(configuration, newModules, details) + private[sbt] def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = { + val newConfigurations = report.configurations.map { confReport => + import confReport._ + val newModules = modules map { modReport => + f(configuration, modReport) } - UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) + ConfigurationReport(configuration, newModules, details) } + UpdateReport(report.cachedDescriptor, newConfigurations, report.stats, report.stamps) + } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 626d31371..0ebcee170 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -12,20 +12,22 @@ import sbt.util.Logger * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( - // If set to CircularDependencyLevel.Error, halt the dependency resolution. - val circularDependencyLevel: CircularDependencyLevel, - // If set to true, prioritize inter-project resolver - val interProjectFirst: Boolean, - // If set to true, check all resolvers for snapshots. - val latestSnapshots: Boolean, - // If set to true, use consolidated resolution. - val consolidatedResolution: Boolean, - // If set to true, use cached resolution. - val cachedResolution: Boolean, - // Extension point for an alternative resolver converter. - val resolverConverter: UpdateOptions.ResolverConverter + // If set to CircularDependencyLevel.Error, halt the dependency resolution. + val circularDependencyLevel: CircularDependencyLevel, + // If set to true, prioritize inter-project resolver + val interProjectFirst: Boolean, + // If set to true, check all resolvers for snapshots. + val latestSnapshots: Boolean, + // If set to true, use consolidated resolution. + val consolidatedResolution: Boolean, + // If set to true, use cached resolution. + val cachedResolution: Boolean, + // Extension point for an alternative resolver converter. + val resolverConverter: UpdateOptions.ResolverConverter ) { - def withCircularDependencyLevel(circularDependencyLevel: CircularDependencyLevel): UpdateOptions = + def withCircularDependencyLevel( + circularDependencyLevel: CircularDependencyLevel + ): UpdateOptions = copy(circularDependencyLevel = circularDependencyLevel) def withInterProjectFirst(interProjectFirst: Boolean): UpdateOptions = copy(interProjectFirst = interProjectFirst) @@ -42,17 +44,18 @@ final class UpdateOptions private[sbt] ( cachedResolution = cachedResoluton, consolidatedResolution = cachedResolution ) + /** Extention point for an alternative resolver converter. */ def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = copy(resolverConverter = resolverConverter) private[sbt] def copy( - circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, - interProjectFirst: Boolean = this.interProjectFirst, - latestSnapshots: Boolean = this.latestSnapshots, - consolidatedResolution: Boolean = this.consolidatedResolution, - cachedResolution: Boolean = this.cachedResolution, - resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter + circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, + interProjectFirst: Boolean = this.interProjectFirst, + latestSnapshots: Boolean = this.latestSnapshots, + consolidatedResolution: Boolean = this.consolidatedResolution, + cachedResolution: Boolean = this.cachedResolution, + resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter ): UpdateOptions = new UpdateOptions( circularDependencyLevel, @@ -73,16 +76,15 @@ final class UpdateOptions private[sbt] ( case _ => false } - override def hashCode: Int = - { - var hash = 1 - hash = hash * 31 + this.circularDependencyLevel.## - hash = hash * 31 + this.interProjectFirst.## - hash = hash * 31 + this.latestSnapshots.## - hash = hash * 31 + this.cachedResolution.## - hash = hash * 31 + this.resolverConverter.## - hash - } + override def hashCode: Int = { + var hash = 1 + hash = hash * 31 + this.circularDependencyLevel.## + hash = hash * 31 + this.interProjectFirst.## + hash = hash * 31 + this.latestSnapshots.## + hash = hash * 31 + this.cachedResolution.## + hash = hash * 31 + this.resolverConverter.## + hash + } } object UpdateOptions { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 594588b44..7f2c39fa6 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -29,7 +29,9 @@ abstract class ConfigurationReportExtra { } def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = - ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) + ConfigurationReport(configuration, modules map { + _.retrieve((mid, art, file) => f(configuration, mid, art, file)) + }, details) } abstract class ModuleReportExtra { @@ -52,7 +54,8 @@ abstract class ModuleReportExtra { def licenses: Vector[(String, Option[String])] def callers: Vector[Caller] - protected[this] def arts: Vector[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) + protected[this] def arts: Vector[String] = + artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) def detailReport: String = s"\t\t- ${module.revision}\n" + @@ -71,48 +74,50 @@ abstract class ModuleReportExtra { if (extraAttributes.isEmpty) None else { Some(extraAttributes.toString) } ) + - reportStr("isDefault", isDefault map { _.toString }) + - reportStr("branch", branch) + - reportStr( - "configurations", - if (configurations.isEmpty) None - else { Some(configurations.mkString(", ")) } - ) + - reportStr( - "licenses", - if (licenses.isEmpty) None - else { Some(licenses.mkString(", ")) } - ) + - reportStr( - "callers", - if (callers.isEmpty) None - else { Some(callers.mkString(", ")) } - ) + reportStr("isDefault", isDefault map { _.toString }) + + reportStr("branch", branch) + + reportStr( + "configurations", + if (configurations.isEmpty) None + else { Some(configurations.mkString(", ")) } + ) + + reportStr( + "licenses", + if (licenses.isEmpty) None + else { Some(licenses.mkString(", ")) } + ) + + reportStr( + "callers", + if (callers.isEmpty) None + else { Some(callers.mkString(", ")) } + ) private[sbt] def reportStr(key: String, value: Option[String]): String = - value map { x => s"\t\t\t$key: $x\n" } getOrElse "" + value map { x => + s"\t\t\t$key: $x\n" + } getOrElse "" def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) protected[this] def copy( - module: ModuleID = module, - artifacts: Vector[(Artifact, File)] = artifacts, - missingArtifacts: Vector[Artifact] = missingArtifacts, - status: Option[String] = status, - publicationDate: Option[ju.Calendar] = publicationDate, - resolver: Option[String] = resolver, - artifactResolver: Option[String] = artifactResolver, - evicted: Boolean = evicted, - evictedData: Option[String] = evictedData, - evictedReason: Option[String] = evictedReason, - problem: Option[String] = problem, - homepage: Option[String] = homepage, - extraAttributes: Map[String, String] = extraAttributes, - isDefault: Option[Boolean] = isDefault, - branch: Option[String] = branch, - configurations: Vector[String] = configurations, - licenses: Vector[(String, Option[String])] = licenses, - callers: Vector[Caller] = callers + module: ModuleID = module, + artifacts: Vector[(Artifact, File)] = artifacts, + missingArtifacts: Vector[Artifact] = missingArtifacts, + status: Option[String] = status, + publicationDate: Option[ju.Calendar] = publicationDate, + resolver: Option[String] = resolver, + artifactResolver: Option[String] = artifactResolver, + evicted: Boolean = evicted, + evictedData: Option[String] = evictedData, + evictedReason: Option[String] = evictedReason, + problem: Option[String] = problem, + homepage: Option[String] = homepage, + extraAttributes: Map[String, String] = extraAttributes, + isDefault: Option[Boolean] = isDefault, + branch: Option[String] = branch, + configurations: Vector[String] = configurations, + licenses: Vector[(String, Option[String])] = licenses, + callers: Vector[Caller] = callers ): ModuleReport } @@ -123,22 +128,21 @@ abstract class UpdateReportExtra { private[sbt] def stamps: Map[File, Long] /** All resolved modules in all configurations. */ - def allModules: Vector[ModuleID] = - { - val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { - case (k, v) => - v reduceLeft { (agg, x) => - agg.withConfigurations( - (agg.configurations, x.configurations) match { - case (None, _) => x.configurations - case (Some(ac), None) => Some(ac) - case (Some(ac), Some(xc)) => Some(s"$ac;$xc") - } - ) - } - } + def allModules: Vector[ModuleID] = { + val key = (m: ModuleID) => (m.organization, m.name, m.revision) + configurations.flatMap(_.allModules).groupBy(key).toVector map { + case (k, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } + ) + } } + } def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 674ffc363..2f82a3612 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -1,9 +1,9 @@ package sbt.librarymanagement final class VersionNumber private[sbt] ( - val numbers: Seq[Long], - val tags: Seq[String], - val extras: Seq[String] + val numbers: Seq[Long], + val tags: Seq[String], + val extras: Seq[String] ) { def _1: Option[Long] = get(0) def _2: Option[Long] = get(1) @@ -33,12 +33,14 @@ final class VersionNumber private[sbt] ( extras.hashCode override def equals(o: Any): Boolean = o match { - case v: VersionNumber => (this.numbers == v.numbers) && (this.tags == v.tags) && (this.extras == v.extras) - case _ => false + case v: VersionNumber => + (this.numbers == v.numbers) && (this.tags == v.tags) && (this.extras == v.extras) + case _ => false } } object VersionNumber { + /** * @param numbers numbers delimited by a dot. * @param tags string prefixed by a dash. @@ -74,10 +76,11 @@ object VersionNumber { val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+)*)((?:\+.+)*)""".r val NonSpaceString = """(\S+)""".r v match { - case TaggedVersion(m, ns, ts, es) => Some((Vector(m.toLong) ++ splitDot(ns), splitDash(ts), splitPlus(es))) - case "" => None - case NonSpaceString(s) => Some((Vector(), Vector(), Vector(s))) - case _ => None + case TaggedVersion(m, ns, ts, es) => + Some((Vector(m.toLong) ++ splitDot(ns), splitDash(ts), splitPlus(es))) + case "" => None + case NonSpaceString(s) => Some((Vector(), Vector(), Vector(s))) + case _ => None } } @@ -98,8 +101,18 @@ object VersionNumber { doIsCompat(v1, v2) || doIsCompat(v2, v1) private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { - case (v1, v2) if (v1.size >= 2) && (v2.size >= 2) => // A normal version number MUST take the form X.Y.Z - (v1._1.get, v1._2.get, v1._3.getOrElse(0L), v1.tags, v2._1.get, v2._2.get, v2._3.getOrElse(0L), v2.tags) match { + case (v1, v2) + if (v1.size >= 2) && (v2.size >= 2) => // A normal version number MUST take the form X.Y.Z + ( + v1._1.get, + v1._2.get, + v1._3.getOrElse(0L), + v1.tags, + v2._1.get, + v2._2.get, + v2._3.getOrElse(0L), + v2.tags + ) match { case (0L, _, _, _, 0L, _, _, _) => // Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable. equalsIgnoreExtra(v1, v2) @@ -107,8 +120,8 @@ object VersionNumber { // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, _, _, _, x2, _, _, _) => - // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. - // Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced + // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. + // Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced x1 == x2 case _ => equalsIgnoreExtra(v1, v2) } @@ -129,13 +142,14 @@ object VersionNumber { doIsCompat(v1, v2) || doIsCompat(v2, v1) private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { - case (v1, v2) if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z + case (v1, v2) + if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { case (x1, y1, 0, ts1, x2, y2, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, y1, _, _, x2, y2, _, _) => - // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible changes are introduced. + // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible changes are introduced. (x1 == x2) && (y1 == y2) case _ => equalsIgnoreExtra(v1, v2) } diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 1400db7ac..50a7f1f95 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -13,13 +13,17 @@ trait BaseIvySpecification extends UnitSpec { def currentTarget: File = currentBase / "target" / "ivyhome" def currentManaged: File = currentBase / "target" / "lib_managed" def currentDependency: File = currentBase / "target" / "dependency" - def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) + def defaultModuleId: ModuleID = + ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) lazy val log = ConsoleLogger() def configurations = Vector(Compile, Test, Runtime) - def module(moduleId: ModuleID, deps: Vector[ModuleID], scalaFullVersion: Option[String], - uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = { + def module(moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String], + uo: UpdateOptions = UpdateOptions(), + overrideScalaVersion: Boolean = true): IvySbt#Module = { val ivyScala = scalaFullVersion map { fv => IvyScala( scalaFullVersion = fv, @@ -53,23 +57,42 @@ trait BaseIvySpecification extends UnitSpec { val off = false val check = Vector.empty val resCacheDir = currentTarget / "resolution-cache" - new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, off, None, check, Some(resCacheDir), uo, log) + new InlineIvyConfiguration(paths, + resolvers, + other, + moduleConfs, + off, + None, + check, + Some(resCacheDir), + uo, + log) } def makeUpdateConfiguration: UpdateConfiguration = { - val retrieveConfig = RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) - UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc"))) + val retrieveConfig = + RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) + UpdateConfiguration(Some(retrieveConfig), + false, + UpdateLogging.Full, + ArtifactTypeFilter.forbid(Set("src", "doc"))) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) val config = makeUpdateConfiguration - IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), LogicalClock.unknown, Some(currentDependency), log) + IvyActions.updateEither(module, + config, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + Some(currentDependency), + log) } def cleanIvyCache(): Unit = IO.delete(currentTarget / "cache") - def cleanCachedResolutionCache(module: IvySbt#Module): Unit = IvyActions.cleanCachedResolutionCache(module, log) + def cleanCachedResolutionCache(module: IvySbt#Module): Unit = + IvyActions.cleanCachedResolutionCache(module, log) def ivyUpdate(module: IvySbt#Module) = ivyUpdateEither(module) match { @@ -78,7 +101,8 @@ trait BaseIvySpecification extends UnitSpec { throw w.resolveException } - def mkPublishConfiguration(resolver: Resolver, artifacts: Map[Artifact, File]): PublishConfiguration = { + def mkPublishConfiguration(resolver: Resolver, + artifacts: Map[Artifact, File]): PublishConfiguration = { new PublishConfiguration( ivyFile = None, resolverName = resolver.name, diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/librarymanagement/src/test/scala/CachedResolutionSpec.scala index 066286f46..f00787fdf 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/librarymanagement/src/test/scala/CachedResolutionSpec.scala @@ -10,7 +10,9 @@ class CachedResolutionSpec extends BaseIvySpecification { cleanIvyCache() val m = module( ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), - Vector(commonsIo13), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + Vector(commonsIo13), + Some("2.10.2"), + UpdateOptions().withCachedResolution(true) ) val report = ivyUpdate(m) cleanCachedResolutionCache(m) @@ -26,7 +28,9 @@ class CachedResolutionSpec extends BaseIvySpecification { // log.setLevel(Level.Debug) val m = module( ModuleID("com.example", "foo", "0.2.0").withConfigurations(Some("compile")), - Vector(mavenCayennePlugin302), Some("2.10.2"), UpdateOptions().withCachedResolution(true) + Vector(mavenCayennePlugin302), + Some("2.10.2"), + UpdateOptions().withCachedResolution(true) ) ivyUpdateEither(m) match { case Right(_) => sys.error("this should've failed") @@ -37,10 +41,10 @@ class CachedResolutionSpec extends BaseIvySpecification { case Right(_) => sys.error("this should've failed 2") case Left(uw) => uw.lines should contain allOf ("\n\tNote: Unresolved dependencies path:", - "\t\tfoundrylogic.vpp:vpp:2.2.1", - "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", - "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", - "\t\t +- com.example:foo:0.2.0") + "\t\tfoundrylogic.vpp:vpp:2.2.1", + "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", + "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", + "\t\t +- com.example:foo:0.2.0") } } @@ -54,7 +58,8 @@ class CachedResolutionSpec extends BaseIvySpecification { val m = module( ModuleID("com.example", "foo", "0.3.0").withConfigurations(Some("compile")), Vector(avro177, dataAvro1940, netty320), - Some("2.10.2"), UpdateOptions().withCachedResolution(true) + Some("2.10.2"), + UpdateOptions().withCachedResolution(true) ) // first resolution creates the minigraph val _ = ivyUpdate(m) @@ -62,15 +67,23 @@ class CachedResolutionSpec extends BaseIvySpecification { // second resolution reads from the minigraph val report = ivyUpdate(m) val modules: Seq[String] = report.configurations.head.modules map { _.toString } - assert(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.0.Final""" }) - assert(!(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.1.Final""" })) + assert(modules exists { x: String => + x contains """org.jboss.netty:netty:3.2.0.Final""" + }) + assert(!(modules exists { x: String => + x contains """org.jboss.netty:netty:3.2.1.Final""" + })) } def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) - def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations(Some("compile")) + def mavenCayennePlugin302 = + ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations( + Some("compile")) def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7").withConfigurations(Some("compile")) - def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile")) - def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile")) + def dataAvro1940 = + ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile")) + def netty320 = + ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile")) def defaultOptions = EvictionWarningOptions.default } diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/librarymanagement/src/test/scala/ComponentManagerTest.scala index ff429aee1..4cc452755 100644 --- a/librarymanagement/src/test/scala/ComponentManagerTest.scala +++ b/librarymanagement/src/test/scala/ComponentManagerTest.scala @@ -73,11 +73,16 @@ class ComponentManagerTest extends UnitSpec { } private def checksum(files: Iterable[File]): Seq[String] = files.map(checksum).toSeq - private def checksum(file: File): String = if (file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" - private def defineFile(manager: ComponentManager, id: String, name: String): String = createFile(manager, id, name)(checksum) - private def defineFiles(manager: ComponentManager, id: String, names: String*): Seq[String] = createFiles(manager, id, names: _*)(checksum) - private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = createFiles(manager, id, name)(files => f(files.toList.head)) - private def createFiles[T](manager: ComponentManager, id: String, names: String*)(f: Seq[File] => T): T = + private def checksum(file: File): String = + if (file.exists) ChecksumHelper.computeAsString(file, "sha1") else "" + private def defineFile(manager: ComponentManager, id: String, name: String): String = + createFile(manager, id, name)(checksum) + private def defineFiles(manager: ComponentManager, id: String, names: String*): Seq[String] = + createFiles(manager, id, names: _*)(checksum) + private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = + createFiles(manager, id, name)(files => f(files.toList.head)) + private def createFiles[T](manager: ComponentManager, id: String, names: String*)( + f: Seq[File] => T): T = withTemporaryDirectory { dir => val files = names.map(name => new File(dir, name)) files.foreach(writeRandomContent) @@ -87,7 +92,9 @@ class ComponentManagerTest extends UnitSpec { private def writeRandomContent(file: File) = IO.write(file, randomString) private def randomString = "asdf" private def withManager[T](f: ComponentManager => T): T = - withTemporaryDirectory { ivyHome => withManagerHome(ivyHome)(f) } + withTemporaryDirectory { ivyHome => + withManagerHome(ivyHome)(f) + } private def withManagerHome[T](ivyHome: File)(f: ComponentManager => T): T = TestLogger { logger => @@ -105,19 +112,26 @@ class ComponentManagerTest extends UnitSpec { override def defineComponent(id: String, files: Array[File]): Unit = { val location = componentLocation(id) if (location.exists) - throw new RuntimeException(s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}") + throw new RuntimeException( + s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}") else { - IO.copy(files.map { f => f -> new java.io.File(location, f.getName) }) + IO.copy(files.map { f => + f -> new java.io.File(location, f.getName) + }) () } } override def addToComponent(id: String, files: Array[File]): Boolean = { val location = componentLocation(id) - IO.copy(files.map { f => f -> new java.io.File(location, f.getName) }) + IO.copy(files.map { f => + f -> new java.io.File(location, f.getName) + }) true } override def component(id: String): Array[File] = - Option(componentLocation(id).listFiles()).map(_.filter(_.isFile)).getOrElse(Array.empty) + Option(componentLocation(id).listFiles()) + .map(_.filter(_.isFile)) + .getOrElse(Array.empty) } // A stubbed locking API. object locks extends xsbti.GlobalLock { diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index fb4dfacf5..d6e245dcd 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -118,22 +118,28 @@ class CrossVersionTest extends UnitSpec { CrossVersion.binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" } it should "return patch Scala version for 2.11.8 as 2.11.8" in { - CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8") + CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some( + "artefact_2.11.8") } it should "return patch Scala version for 2.11.8-M1 as 2.11.8-M1" in { - CrossVersion(CrossVersion.patch, "2.11.8-M1", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") + CrossVersion(CrossVersion.patch, "2.11.8-M1", "dummy").map(_("artefact")) shouldBe Some( + "artefact_2.11.8-M1") } it should "return patch Scala version for 2.11.8-RC1 as 2.11.8-RC1" in { - CrossVersion(CrossVersion.patch, "2.11.8-RC1", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") + CrossVersion(CrossVersion.patch, "2.11.8-RC1", "dummy").map(_("artefact")) shouldBe Some( + "artefact_2.11.8-RC1") } it should "return patch Scala version for 2.11.8-bin-extra as 2.11.8" in { - CrossVersion(CrossVersion.patch, "2.11.8-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8") + CrossVersion(CrossVersion.patch, "2.11.8-bin-extra", "dummy").map(_("artefact")) shouldBe Some( + "artefact_2.11.8") } it should "return patch Scala version for 2.11.8-M1-bin-extra as 2.11.8-M1" in { - CrossVersion(CrossVersion.patch, "2.11.8-M1-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") + CrossVersion(CrossVersion.patch, "2.11.8-M1-bin-extra", "dummy") + .map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") } it should "return patch Scala version for 2.11.8-RC1-bin-extra as 2.11.8-RC1" in { - CrossVersion(CrossVersion.patch, "2.11.8-RC1-bin-extra", "dummy").map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") + CrossVersion(CrossVersion.patch, "2.11.8-RC1-bin-extra", "dummy") + .map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") } it should "return disabled cross version as equal to a copy" in { Disabled() shouldBe Disabled() diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index e40771325..ea0113596 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -15,7 +15,16 @@ class CustomPomParserTest extends UnitSpec { val repoUrl = getClass.getResource("/test-maven-repo") val local = MavenRepository("Test Repo", repoUrl.toExternalForm) val paths = IvyPaths(new File("."), Some(cacheDir)) - val conf = new InlineIvyConfiguration(paths, Vector(local), Vector.empty, Vector.empty, false, None, Vector("sha1", "md5"), None, UpdateOptions(), log) + val conf = new InlineIvyConfiguration(paths, + Vector(local), + Vector.empty, + Vector.empty, + false, + None, + Vector("sha1", "md5"), + None, + UpdateOptions(), + log) val ivySbt = new IvySbt(conf) val resolveOpts = new ResolveOptions().setConfs(Array("default")) val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") @@ -26,7 +35,8 @@ class CustomPomParserTest extends UnitSpec { resolveReport.hasError shouldBe false resolveReport.getArtifacts.size() shouldBe 1 - val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) + val artifact: IvyArtifact = + resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) artifact.getModuleRevisionId shouldBe mrid artifact.getExt shouldBe "jar" } diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index 5c6a89db7..3fb9ae8e2 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -52,11 +52,14 @@ class DMSerializationSpec extends UnitSpec { } lazy val updateReportExample = - UpdateReport(new File("./foo"), Vector(configurationReportExample), - UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) + UpdateReport(new File("./foo"), + Vector(configurationReportExample), + UpdateStats(0, 0, 0, false), + Map(new File("./foo") -> 0)) lazy val configurationReportExample = - ConfigurationReport("compile", Vector(moduleReportExample), - Vector(organizationArtifactReportExample)) + ConfigurationReport("compile", + Vector(moduleReportExample), + Vector(organizationArtifactReportExample)) lazy val organizationArtifactReportExample = OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) lazy val moduleReportExample = @@ -68,13 +71,13 @@ class DMSerializationSpec extends UnitSpec { def roundtripStr[A: JsonReader: JsonWriter](a: A): Assertion = roundtripBuilder(a) { _.toString shouldBe _.toString } - def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Assertion): Assertion = - { - val json = isoString to (Converter toJsonUnsafe a) - println(json) - val obj = Converter fromJsonUnsafe[A] (isoString from json) - f(a, obj) - } + def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Assertion): Assertion = { + val json = isoString to (Converter toJsonUnsafe a) + println(json) + val obj = Converter fromJsonUnsafe [A] (isoString from json) + f(a, obj) + } - implicit val isoString: IsoString[JValue] = IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) + implicit val isoString: IsoString[JValue] = + IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) } diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index ce834ac76..8daf2277a 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -44,19 +44,29 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "be detected if it's enabled" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() - def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary - def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary - def akkaActor234 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary - def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) - def scala2103 = ModuleID("org.scala-lang", "scala-library", "2.10.3").withConfigurations(Some("compile")) - def scala2104 = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) + def akkaActor214 = + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230 = + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor234 = + ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def scala2102 = + ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) + def scala2103 = + ModuleID("org.scala-lang", "scala-library", "2.10.3").withConfigurations(Some("compile")) + def scala2104 = + ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile")) def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile")) - def bnfparser10 = ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 - def unfilteredUploads080 = ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 - def bananaSesame04 = ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 - def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + def bnfparser10 = + ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 + def unfilteredUploads080 = + ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + def bananaSesame04 = + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + def akkaRemote234 = + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 def defaultOptions = EvictionWarningOptions.default @@ -181,7 +191,10 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe + EvictionWarning(m, + defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), + report, + log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", @@ -240,7 +253,10 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), report, log).lines shouldBe + EvictionWarning(m, + defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), + report, + log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala index 4e0866d6c..8ba690221 100644 --- a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala +++ b/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala @@ -20,7 +20,10 @@ class InconsistentDuplicateSpec extends UnitSpec { IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil } - def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary - def akkaActor230 = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary - def akkaActor230Test = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary + def akkaActor214 = + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230 = + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + def akkaActor230Test = + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary } diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/librarymanagement/src/test/scala/MakePomSpec.scala index fb2c55001..eb9c353cb 100644 --- a/librarymanagement/src/test/scala/MakePomSpec.scala +++ b/librarymanagement/src/test/scala/MakePomSpec.scala @@ -75,4 +75,3 @@ class MakePomSpec extends UnitSpec { () } } - diff --git a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala index 65749a28d..dddeadfdd 100644 --- a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala +++ b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala @@ -9,7 +9,9 @@ class MergeDescriptorSpec extends BaseIvySpecification { cleanIvyCache() val m = module( ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), - Vector(guavaTest, guavaTestTests), None, UpdateOptions() + Vector(guavaTest, guavaTestTests), + None, + UpdateOptions() ) m.withModule(log) { case (ivy, md, _) => @@ -27,8 +29,12 @@ class MergeDescriptorSpec extends BaseIvySpecification { } } } - def guavaTest = ModuleID("com.google.guava", "guava-tests", "18.0").withConfigurations(Option("compile")) - def guavaTestTests = ModuleID("com.google.guava", "guava-tests", "18.0").withConfigurations(Option("test")).classifier("tests") + def guavaTest = + ModuleID("com.google.guava", "guava-tests", "18.0").withConfigurations(Option("compile")) + def guavaTestTests = + ModuleID("com.google.guava", "guava-tests", "18.0") + .withConfigurations(Option("test")) + .classifier("tests") def defaultOptions = EvictionWarningOptions.default } diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index d2090c502..2682797fa 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -9,7 +9,14 @@ object ResolverTest extends UnitSpec { "Resolver url" should "propagate pattern descriptorOptional and skipConsistencyCheck." in { val pats = Vector("[orgPath]") val patsExpected = Vector("http://foo.com/test/[orgPath]") - val patterns = Resolver.url("test", new URL("http://foo.com/test"))(Patterns(pats, pats, isMavenCompatible = false, descriptorOptional = true, skipConsistencyCheck = true)).patterns + val patterns = Resolver + .url("test", new URL("http://foo.com/test"))( + Patterns(pats, + pats, + isMavenCompatible = false, + descriptorOptional = true, + skipConsistencyCheck = true)) + .patterns patterns.ivyPatterns shouldBe patsExpected patterns.artifactPatterns shouldBe patsExpected diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala index f14a2d6ca..2417db786 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -12,7 +12,9 @@ class ScalaOverrideTest extends UnitSpec { val OtherOrgID = "other.org" def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { - val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map { _.name } + val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map { + _.name + } val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) val mrid = ModuleRevisionId.newInstance(org1, name1, version1) @@ -24,21 +26,51 @@ class ScalaOverrideTest extends UnitSpec { } """OverrideScalaMediator - """ should "Override compiler version" in check(Organization, "2.11.8")(Organization, CompilerID, "2.11.9") - it should "Override library version" in check(Organization, "2.11.8")(Organization, LibraryID, "2.11.8") - it should "Override reflect version" in check(Organization, "2.11.8")(Organization, ReflectID, "2.11.7") - it should "Override actors version" in check(Organization, "2.11.8")(Organization, ActorsID, "2.11.6") - it should "Override scalap version" in check(Organization, "2.11.8")(Organization, ScalapID, "2.11.5") + """ should "Override compiler version" in check(Organization, "2.11.8")(Organization, + CompilerID, + "2.11.9") + it should "Override library version" in check(Organization, "2.11.8")(Organization, + LibraryID, + "2.11.8") + it should "Override reflect version" in check(Organization, "2.11.8")(Organization, + ReflectID, + "2.11.7") + it should "Override actors version" in check(Organization, "2.11.8")(Organization, + ActorsID, + "2.11.6") + it should "Override scalap version" in check(Organization, "2.11.8")(Organization, + ScalapID, + "2.11.5") - it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")(Organization, CompilerID, "2.11.9") - it should "Override default library organization" in check(OtherOrgID, "2.11.8")(Organization, LibraryID, "2.11.8") - it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")(Organization, ReflectID, "2.11.7") - it should "Override default actors organization" in check(OtherOrgID, "2.11.8")(Organization, ActorsID, "2.11.6") - it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")(Organization, ScalapID, "2.11.5") + it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")(Organization, + CompilerID, + "2.11.9") + it should "Override default library organization" in check(OtherOrgID, "2.11.8")(Organization, + LibraryID, + "2.11.8") + it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")(Organization, + ReflectID, + "2.11.7") + it should "Override default actors organization" in check(OtherOrgID, "2.11.8")(Organization, + ActorsID, + "2.11.6") + it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")(Organization, + ScalapID, + "2.11.5") - it should "Override custom compiler organization" in check(Organization, "2.11.8")(OtherOrgID, CompilerID, "2.11.9") - it should "Override custom library organization" in check(Organization, "2.11.8")(OtherOrgID, LibraryID, "2.11.8") - it should "Override custom reflect organization" in check(Organization, "2.11.8")(OtherOrgID, ReflectID, "2.11.7") - it should "Override custom actors organization" in check(Organization, "2.11.8")(OtherOrgID, ActorsID, "2.11.6") - it should "Override custom scalap organization" in check(Organization, "2.11.8")(OtherOrgID, ScalapID, "2.11.5") + it should "Override custom compiler organization" in check(Organization, "2.11.8")(OtherOrgID, + CompilerID, + "2.11.9") + it should "Override custom library organization" in check(Organization, "2.11.8")(OtherOrgID, + LibraryID, + "2.11.8") + it should "Override custom reflect organization" in check(Organization, "2.11.8")(OtherOrgID, + ReflectID, + "2.11.7") + it should "Override custom actors organization" in check(Organization, "2.11.8")(OtherOrgID, + ActorsID, + "2.11.6") + it should "Override custom scalap organization" in check(Organization, "2.11.8")(OtherOrgID, + ScalapID, + "2.11.5") } diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala index 5e59cada3..66fd96f61 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/librarymanagement/src/test/scala/VersionNumberSpec.scala @@ -38,45 +38,72 @@ class VersionNumberSpec extends UnitSpec { it should "be SecSeg compat with 0.12.1" in beSecSegCompatWith("0.12.0", "0.12.1") it should "be SecSeg compat with 0.12.1-M1" in beSecSegCompatWith("0.12.0", "0.12.1-M1") - "0.1.0-SNAPSHOT" should "be parsed" in beParsedAs("0.1.0-SNAPSHOT", Seq(0, 1, 0), Seq("SNAPSHOT"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) - it should "be SemVer compat with 0.1.0-SNAPSHOT" in beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT") + "0.1.0-SNAPSHOT" should "be parsed" in beParsedAs("0.1.0-SNAPSHOT", + Seq(0, 1, 0), + Seq("SNAPSHOT"), + Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", + Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) + it should "be SemVer compat with 0.1.0-SNAPSHOT" in beSemVerCompatWith("0.1.0-SNAPSHOT", + "0.1.0-SNAPSHOT") it should "not be SemVer compat with 0.1.0" in notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0") - it should "be SemVer compat with 0.1.0-SNAPSHOT+001" in beSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001") - it should "be SecSeg compat with 0.1.0-SNAPSHOT" in beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT") + it should "be SemVer compat with 0.1.0-SNAPSHOT+001" in beSemVerCompatWith("0.1.0-SNAPSHOT", + "0.1.0-SNAPSHOT+001") + it should "be SecSeg compat with 0.1.0-SNAPSHOT" in beSecSegCompatWith("0.1.0-SNAPSHOT", + "0.1.0-SNAPSHOT") it should "be not SecSeg compat with 0.1.0" in notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0") - it should "be SecSeg compat with 0.1.0-SNAPSHOT+001" in beSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0-SNAPSHOT+001") + it should "be SecSeg compat with 0.1.0-SNAPSHOT+001" in beSecSegCompatWith("0.1.0-SNAPSHOT", + "0.1.0-SNAPSHOT+001") "0.1.0-M1" should "be parsed" in beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-M1", Seq("0.1.0-M1", "0.1.0", "0.1")) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-M1", + Seq("0.1.0-M1", "0.1.0", "0.1")) "0.1.0-RC1" should "be parsed" in beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-RC1", Seq("0.1.0-RC1", "0.1.0", "0.1")) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-RC1", + Seq("0.1.0-RC1", "0.1.0", "0.1")) - "0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1", Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1", Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) + "0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1", + Seq(0, 1, 0), + Seq("MSERVER", "1"), + Seq()) + it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1", + Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) "2.10.4-20140115-000117-b3a-sources" should "be parsed" in { - beParsedAs("2.10.4-20140115-000117-b3a-sources", Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) + beParsedAs("2.10.4-20140115-000117-b3a-sources", + Seq(2, 10, 4), + Seq("20140115", "000117", "b3a", "sources"), + Seq()) } - it should "cascade" in generateCorrectCascadingNumbers("2.10.4-20140115-000117-b3a-sources", Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) - it should "be SemVer compat with 2.0.0" in beSemVerCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0") - it should "be not SecSeg compat with 2.0.0" in notBeSecSegCompatWith("2.10.4-20140115-000117-b3a-sources", "2.0.0") + it should "cascade" in generateCorrectCascadingNumbers( + "2.10.4-20140115-000117-b3a-sources", + Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) + it should "be SemVer compat with 2.0.0" in beSemVerCompatWith( + "2.10.4-20140115-000117-b3a-sources", + "2.0.0") + it should "be not SecSeg compat with 2.0.0" in notBeSecSegCompatWith( + "2.10.4-20140115-000117-b3a-sources", + "2.0.0") "20140115000117-b3a-sources" should "be parsed" in { beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq()) } - it should "cascade" in generateCorrectCascadingNumbers("20140115000117-b3a-sources", Seq("20140115000117-b3a-sources")) + it should "cascade" in generateCorrectCascadingNumbers("20140115000117-b3a-sources", + Seq("20140115000117-b3a-sources")) "1.0.0-alpha+001+002" should "be parsed" in { beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) } - it should "cascade" in generateCorrectCascadingNumbers("1.0.0-alpha+001+002", Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) + it should "cascade" in generateCorrectCascadingNumbers( + "1.0.0-alpha+001+002", + Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) "non.space.!?string" should "be parsed" in { beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string")) } - it should "cascade" in generateCorrectCascadingNumbers("non.space.!?string", Seq("non.space.!?string")) + it should "cascade" in generateCorrectCascadingNumbers("non.space.!?string", + Seq("non.space.!?string")) "space !?string" should "be parsed as an error" in beParsedAsError("space !?string") "blank string" should "be parsed as an error" in beParsedAsError("") @@ -89,8 +116,11 @@ class VersionNumberSpec extends UnitSpec { case VersionNumber(ns1, ts1, es1) => sys.error(s"$ns1, $ts1, $es1") } - def breakDownTo(s: String, major: Option[Long], minor: Option[Long] = None, - patch: Option[Long] = None, buildNumber: Option[Long] = None) = + def breakDownTo(s: String, + major: Option[Long], + minor: Option[Long] = None, + patch: Option[Long] = None, + buildNumber: Option[Long] = None) = s match { case VersionNumber(ns, ts, es) => val v = VersionNumber(ns, ts, es) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index 27936225f..07962f60a 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -9,10 +9,13 @@ import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport } class FakeResolverSpecification extends BaseIvySpecification { import FakeResolver._ - val myModule = ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT").withConfigurations(Some("compile")) + val myModule = + ModuleID("org.example", "my-module", "0.0.1-SNAPSHOT").withConfigurations(Some("compile")) val example = ModuleID("com.example", "example", "1.0.0").withConfigurations(Some("compile")) - val anotherExample = ModuleID("com.example", "another-example", "1.0.0").withConfigurations(Some("compile")) - val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile")) + val anotherExample = + ModuleID("com.example", "another-example", "1.0.0").withConfigurations(Some("compile")) + val nonExisting = + ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile")) "The FakeResolver" should "find modules with only one artifact" in { val m = getModule(myModule) @@ -53,12 +56,10 @@ class FakeResolverSpecification extends BaseIvySpecification { ("org.example", "my-module", "0.0.1-SNAPSHOT") -> List( FakeArtifact("artifact1", "jar", "jar", artifact1) ), - ("com.example", "example", "1.0.0") -> List( FakeArtifact("artifact1", "jar", "jar", artifact1), FakeArtifact("artifact2", "txt", "txt", artifact2) ), - ("com.example", "another-example", "1.0.0") -> List( FakeArtifact("artifact1", "jar", "jar", artifact1), FakeArtifact("non-existing", "txt", "txt", new File("non-existing-file")) @@ -67,7 +68,8 @@ class FakeResolverSpecification extends BaseIvySpecification { private def fakeResolver = new FakeResolver("FakeResolver", new File("tmp"), modules) override def resolvers: Vector[Resolver] = Vector(new RawRepository(fakeResolver)) - private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Vector(myModule), None) + private def getModule(myModule: ModuleID): IvySbt#Module = + module(defaultModuleId, Vector(myModule), None) private def getAllFiles(report: UpdateReport) = for { conf <- report.configurations diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index b6238b3d5..61c9aa27c 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -15,7 +15,8 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { module( ourModuleID, - Vector(dep), None //, UpdateOptions().withCachedResolution(true) + Vector(dep), + None //, UpdateOptions().withCachedResolution(true) ) } @@ -59,12 +60,26 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val clMod = { val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) - GetClassifiersModule(ourModuleID, externalModules, Vector(Configurations.Compile), attemptedClassifiers) + GetClassifiersModule(ourModuleID, + externalModules, + Vector(Configurations.Compile), + attemptedClassifiers) } - val gcm = GetClassifiersConfiguration(clMod, Map.empty, c.withArtifactFilter(c.artifactFilter.invert), ivyScala, srcTypes, docTypes) + val gcm = GetClassifiersConfiguration(clMod, + Map.empty, + c.withArtifactFilter(c.artifactFilter.invert), + ivyScala, + srcTypes, + docTypes) - val report2 = IvyActions.updateClassifiers(m.owner, gcm, UnresolvedWarningConfiguration(), LogicalClock.unknown, None, Vector(), log) + val report2 = IvyActions.updateClassifiers(m.owner, + gcm, + UnresolvedWarningConfiguration(), + LogicalClock.unknown, + None, + Vector(), + log) import Inside._ inside(report2.configuration("compile").map(_.modules)) { diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala index 707bbcffa..0aec79d39 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala @@ -54,11 +54,16 @@ class RepositoriesParserSpecification extends UnitSpec { | ivyRepo: https://repo1.maven.org, [orgPath], bootOnly""".stripMargin val repos = RepositoriesParser(file) val expected = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[orgPath]", mavenCompatible = false, skipConsistencyCheck = false, descriptorOptional = false, - bootOnly = true) + bootOnly = true + ) repos.size shouldBe 1 repos(0) shouldBe expected } @@ -68,11 +73,16 @@ class RepositoriesParserSpecification extends UnitSpec { | ivyRepo: https://repo1.maven.org, [orgPath], mavenCompatible""".stripMargin val repos = RepositoriesParser(file) val expected = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[orgPath]", mavenCompatible = true, skipConsistencyCheck = false, descriptorOptional = false, - bootOnly = false) + bootOnly = false + ) repos.size shouldBe 1 repos(0) shouldBe expected } @@ -82,11 +92,16 @@ class RepositoriesParserSpecification extends UnitSpec { | ivyRepo: https://repo1.maven.org, [orgPath], skipConsistencyCheck""".stripMargin val repos = RepositoriesParser(file) val expected = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[orgPath]", mavenCompatible = false, skipConsistencyCheck = true, descriptorOptional = false, - bootOnly = false) + bootOnly = false + ) repos.size shouldBe 1 repos(0) shouldBe expected } @@ -96,41 +111,58 @@ class RepositoriesParserSpecification extends UnitSpec { | ivyRepo: https://repo1.maven.org, [orgPath], descriptorOptional""".stripMargin val repos = RepositoriesParser(file) val expected = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[orgPath]", mavenCompatible = false, skipConsistencyCheck = false, descriptorOptional = true, - bootOnly = false) + bootOnly = false + ) repos.size shouldBe 1 repos(0) shouldBe expected } it should "parse complex ivy repository definition" in { - val file = """[repositories] + val file = + """[repositories] | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck""".stripMargin val repos = RepositoriesParser(file) val expected = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[artPath]", mavenCompatible = false, skipConsistencyCheck = true, descriptorOptional = true, - bootOnly = false) + bootOnly = false + ) repos.size shouldBe 1 repos(0) shouldBe expected } it should "parse multiple repositories defined together" in { - val file = """[repositories] + val file = + """[repositories] | local | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck | mavenRepo: https://repo1.maven.org""".stripMargin val expected0 = PredefinedRepository(xsbti.Predefined.Local) val expected1 = - IvyRepository("ivyRepo", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", + IvyRepository( + "ivyRepo", + new URL("https://repo1.maven.org"), + "[orgPath]", + "[artPath]", mavenCompatible = false, skipConsistencyCheck = true, descriptorOptional = true, - bootOnly = false) + bootOnly = false + ) val expected2 = MavenRepository("mavenRepo", new URL("https://repo1.maven.org")) val repos = RepositoriesParser(file) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala index 4dace2131..e3cd17d3c 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala @@ -6,10 +6,9 @@ import sbt.util._ import sbt.internal.util._ object TestLogger { - def apply[T](f: Logger => T): T = - { - val log = new BufferedLogger(ConsoleLogger()) - log.setLevel(Level.Debug) - log.bufferQuietly(f(log)) - } + def apply[T](f: Logger => T): T = { + val log = new BufferedLogger(ConsoleLogger()) + log.setLevel(Level.Debug) + log.bufferQuietly(f(log)) + } } diff --git a/project/AutomateScalafmtPlugin.scala b/project/AutomateScalafmtPlugin.scala index f066d0567..28e0c04d8 100644 --- a/project/AutomateScalafmtPlugin.scala +++ b/project/AutomateScalafmtPlugin.scala @@ -11,13 +11,13 @@ object AutomateScalafmtPlugin extends AutoPlugin { configurations.flatMap { c => inConfig(c)( Seq( - compileInputs.in(compile) := { + compileInputs.in(compile) := { scalafmtInc.value compileInputs.in(compile).value }, sourceDirectories.in(scalafmtInc) := Seq(scalaSource.value), scalafmtInc := { - val cache = streams.value.cacheDirectory / "scalafmt" + val cache = streams.value.cacheDirectory / "scalafmt" val include = includeFilter.in(scalafmtInc).value val exclude = excludeFilter.in(scalafmtInc).value val sources = diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index 4b39d3cad..cc95f3ff3 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -19,27 +19,39 @@ object DatatypeConfig { /** Codecs that were manually written. */ val myCodecs: PartialFunction[String, Type => List[String]] = { - case "scala.xml.NodeSeq" => { _ => "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil } + case "scala.xml.NodeSeq" => { _ => + "sbt.internal.librarymanagement.formats.NodeSeqFormat" :: Nil + } - case "org.apache.ivy.plugins.resolver.DependencyResolver" => - { _ => "sbt.internal.librarymanagement.formats.DependencyResolverFormat" :: Nil } + case "org.apache.ivy.plugins.resolver.DependencyResolver" => { _ => + "sbt.internal.librarymanagement.formats.DependencyResolverFormat" :: Nil + } - case "xsbti.GlobalLock" => { _ => "sbt.internal.librarymanagement.formats.GlobalLockFormat" :: Nil } - case "xsbti.Logger" => { _ => "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil } + case "xsbti.GlobalLock" => { _ => + "sbt.internal.librarymanagement.formats.GlobalLockFormat" :: Nil + } + case "xsbti.Logger" => { _ => + "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil + } - case "sbt.librarymanagement.UpdateOptions" => - { _ => "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil } + case "sbt.librarymanagement.UpdateOptions" => { _ => + "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil + } // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo - case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) } - case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => twoArgs(tpe).flatMap(getFormats) } - case "Int" | "Long" => { _ => Nil } + case "Option" | "Set" | "scala.Vector" => { tpe => + getFormats(oneArg(tpe)) + } + case "Map" | "Tuple2" | "scala.Tuple2" => { tpe => + twoArgs(tpe).flatMap(getFormats) + } + case "Int" | "Long" => { _ => + Nil + } } /** Types for which we don't include the format -- they're just aliases to InclExclRule */ - val excluded = Set( - "sbt.librarymanagement.InclusionRule", - "sbt.librarymanagement.ExclusionRule") + val excluded = Set("sbt.librarymanagement.InclusionRule", "sbt.librarymanagement.ExclusionRule") /** Returns the list of formats required to encode the given `TpeRef`. */ val getFormats: Type => List[String] = diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8777d53e7..b8a07cd13 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -11,10 +11,10 @@ object Dependencies { private val sbtIO = "org.scala-sbt" %% "io" % ioVersion private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion - private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion + private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion + private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion - private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion + private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion def getSbtModulePath(key: String, name: String) = { val localProps = new java.util.Properties() @@ -24,21 +24,31 @@ object Dependencies { path } - lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io") + lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io") lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util") - def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID, c: Option[Configuration] = None) = + def addSbtModule(p: Project, + path: Option[String], + projectName: String, + m: ModuleID, + c: Option[Configuration] = None) = path match { - case Some(f) => p dependsOn c.fold[ClasspathDependency](ProjectRef(file(f), projectName))(ProjectRef(file(f), projectName) % _) - case None => p settings (libraryDependencies += c.fold(m)(m % _)) + case Some(f) => + p dependsOn c.fold[ClasspathDependency](ProjectRef(file(f), projectName))( + ProjectRef(file(f), projectName) % _) + case None => p settings (libraryDependencies += c.fold(m)(m % _)) } def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) - def addSbtUtilCollection(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) - def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) - def addSbtUtilTesting(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) - def addSbtUtilCompletion(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) - def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) + def addSbtUtilCollection(p: Project): Project = + addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) + def addSbtUtilLogging(p: Project): Project = + addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) + def addSbtUtilTesting(p: Project): Project = + addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) + def addSbtUtilCompletion(p: Project): Project = + addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) + def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4" @@ -52,7 +62,7 @@ object Dependencies { Def.setting { scalaVersion.value match { case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil - case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil + case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil } } } diff --git a/project/Util.scala b/project/Util.scala index 26533a73b..2b8dccaf2 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -4,29 +4,31 @@ import sbt.IO import java.io.File - object Util { def versionLine(version: String): String = "version=" + version - def containsVersion(propFile: File, version: String): Boolean = IO.read(propFile).contains(versionLine(version)) - def lastCompilationTime(analysis: sbt.inc.Analysis): Long = - { - val lastCompilation = analysis.compilations.allCompilations.lastOption - lastCompilation.map(_.startTime) getOrElse 0L - } + def containsVersion(propFile: File, version: String): Boolean = + IO.read(propFile).contains(versionLine(version)) + def lastCompilationTime(analysis: sbt.inc.Analysis): Long = { + val lastCompilation = analysis.compilations.allCompilations.lastOption + lastCompilation.map(_.startTime) getOrElse 0L + } - def generateVersionFile(version: String, dir: File, s: TaskStreams, analysis: sbt.inc.Analysis): Seq[File] = - { - import java.util.{ Date, TimeZone } - val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") - formatter.setTimeZone(TimeZone.getTimeZone("GMT")) - val timestamp = formatter.format(new Date) - val content = versionLine(version) + "\ntimestamp=" + timestamp - val f = dir / "xsbt.version.properties" - if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { - s.log.info("Writing version information to " + f + " :\n" + content) - IO.write(f, content) - } - f :: Nil + def generateVersionFile(version: String, + dir: File, + s: TaskStreams, + analysis: sbt.inc.Analysis): Seq[File] = { + import java.util.{ Date, TimeZone } + val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") + formatter.setTimeZone(TimeZone.getTimeZone("GMT")) + val timestamp = formatter.format(new Date) + val content = versionLine(version) + "\ntimestamp=" + timestamp + val f = dir / "xsbt.version.properties" + if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, + version)) { + s.log.info("Writing version information to " + f + " :\n" + content) + IO.write(f, content) } + f :: Nil + } } diff --git a/project/plugins.sbt b/project/plugins.sbt index 6d069c96c..1392d8889 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") -addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") +addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M4") -addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") -addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "0.6.8") +addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") +addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "0.6.8") scalacOptions += "-language:postfixOps" From e1d98a1ec2ce42d8abe5b5180e63ebf06ddd7d0b Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 26 Apr 2017 14:15:03 +0200 Subject: [PATCH 0589/1030] Fix sbt/sbt#1518: Handle cross-versioned exclusions The following PR does two things: * Removes the unnecessary `SbtExclusionRule` that was introduced to exclude artifacts at the project level (and not the dependency level). This change was done in an independent class to avoid breaking bincompat in 0.13.x series. * Handle exclusion rules correctly, propagating the cross version to the exclusions of the dependencies. To fix sbt/sbt#1518, this PR takes the avenue taken in `SbtExclusionRule`, it accepts `GroupArtifactID` which should be the preferred way to specify dependencies from now on. Unlike `SbtExclusionRule`, it also supports `ModuleID` for those that want to exclude a concrete dependency. `InclExcl` did not have any tests. The following commit also adds a testing suite for it, showing how the issue it's fixed and how you should use `exclude` if you're calling directly `ExclusionRule` instead of passing in `GroupArtifactID` and `ModuleID`. --- .../main/contraband/librarymanagement.json | 28 +++----- .../sbt/internal/librarymanagement/Ivy.scala | 27 +++++--- .../SbtExclusionRuleExtra.scala | 18 ----- .../librarymanagement/CrossVersionExtra.scala | 12 ++-- .../sbt/librarymanagement/IvyInterface.scala | 23 ++++++- .../sbt/librarymanagement/ModuleIDExtra.scala | 4 +- .../src/test/scala/InclExclSpec.scala | 67 +++++++++++++++++++ 7 files changed, 120 insertions(+), 59 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala create mode 100644 librarymanagement/src/test/scala/InclExclSpec.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index e9f16c123..c93091568 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -207,18 +207,20 @@ "target": "Scala", "type": "record", "doc": [ - "Rule to either:", + "Defines a rule to either:", "
    ", - "
  • exclude unwanted dependencies pulled in transitively by a module, or to
  • ", - "
  • include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
  • ", + "
  • Exclude unwanted dependencies pulled in transitively by a module, or to
  • ", + "
  • Include and merge artifacts coming from the ModuleDescriptor if \"dependencyArtifacts\" are also provided.
  • ", "
", - "Which one depends on the parameter name which it is passed to, but the filter has the same fields in both cases." + "The use case that is applied depends on the parameter name which it is passed to, but the", + "filter has the same fields in both cases." ], "fields": [ { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" } + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1"} ], "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" }, @@ -374,7 +376,7 @@ { "name": "moduleInfo", "type": "sbt.librarymanagement.ModuleInfo" }, { "name": "dependencies", "type": "sbt.librarymanagement.ModuleID*" }, { "name": "overrides", "type": "Set[sbt.librarymanagement.ModuleID]", "default": "Set.empty", "since": "0.0.1" }, - { "name": "excludes", "type": "sbt.internal.librarymanagement.SbtExclusionRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "excludes", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "defaultConfiguration", "type": "Option[sbt.librarymanagement.Configuration]", "default": "None", "since": "0.0.1" }, @@ -781,20 +783,6 @@ { "name": "configurationsToRetrieve", "type": "Option[Set[sbt.librarymanagement.Configuration]]", "default": "None", "since": "0.0.1" } ] }, - { - "name": "SbtExclusionRule", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "organization", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "artifact", "type": "String" }, - { "name": "configurations", "type": "String*" }, - { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion" } - ], - "parentsCompanion": "sbt.internal.librarymanagement.SbtExclusionRuleFunctions" - }, { "name": "UpdateReportLite", "namespace": "sbt.internal.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index b5084ffb6..bd83242f9 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -567,22 +567,30 @@ private[sbt] object IvySbt { ) } - private def substituteCross(m: ModuleSettings): ModuleSettings = + private def substituteCross(m: ModuleSettings): ModuleSettings = { m.ivyScala match { case None => m case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) } + } + private def substituteCross( m: ModuleSettings, scalaFullVersion: String, scalaBinaryVersion: String ): ModuleSettings = { - val sub = CrossVersion(scalaFullVersion, scalaBinaryVersion) m match { case ic: InlineConfiguration => - ic.withModule(sub(ic.module)) - .withDependencies(ic.dependencies map sub) - .withOverrides(ic.overrides map sub) + val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) + def propagateCrossVersion(moduleID: ModuleID): ModuleID = { + val crossExclusions: Vector[ExclusionRule] = + moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.ivyScala)) + applyCross(moduleID) + .withExclusions(crossExclusions) + } + ic.withModule(applyCross(ic.module)) + .withDependencies(ic.dependencies.map(propagateCrossVersion)) + .withOverrides(ic.overrides map applyCross) case _ => m } } @@ -852,13 +860,12 @@ private[sbt] object IvySbt { def addExcludes( moduleID: DefaultModuleDescriptor, - excludes: Seq[SbtExclusionRule], + excludes: Seq[ExclusionRule], ivyScala: Option[IvyScala] - ): Unit = - excludes foreach addExclude(moduleID, ivyScala) + ): Unit = excludes.foreach(exclude => addExclude(moduleID, ivyScala)(exclude)) + def addExclude(moduleID: DefaultModuleDescriptor, ivyScala: Option[IvyScala])( - exclude0: SbtExclusionRule - ): Unit = { + exclude0: ExclusionRule): Unit = { // this adds _2.11 postfix val exclude = CrossVersion.substituteCross(exclude0, ivyScala) val confs = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala deleted file mode 100644 index 6c5c01245..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/SbtExclusionRuleExtra.scala +++ /dev/null @@ -1,18 +0,0 @@ -package sbt.internal.librarymanagement - -import sbt.internal.librarymanagement.impl._ -import sbt.librarymanagement._ - -abstract class SbtExclusionRuleFunctions { - def apply(organization: String, name: String): SbtExclusionRule = - SbtExclusionRule(organization, name, "*", Vector.empty, Disabled()) - - def apply(organization: String): SbtExclusionRule = apply(organization, "*") - - implicit def groupIdToExclusionRule(organization: GroupID): SbtExclusionRule = - apply(organization.groupID) - implicit def stringToExclusionRule(organization: String): SbtExclusionRule = apply(organization) - - implicit def groupArtifactIDToExclusionRule(gaid: GroupArtifactID): SbtExclusionRule = - SbtExclusionRule(gaid.groupID, gaid.artifactID, "*", Vector.empty, gaid.crossVersion) -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 7e90f8c59..29ef28327 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -1,6 +1,5 @@ package sbt.librarymanagement -import sbt.internal.librarymanagement.SbtExclusionRule import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) @@ -69,9 +68,7 @@ abstract class CrossVersionFunctions { /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = - is flatMap { i => - apply(module, i) - } + is.flatMap(i => apply(module, i)) /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ def substituteCross( @@ -94,9 +91,9 @@ abstract class CrossVersionFunctions { /** Cross-versions `exclude` according to its `crossVersion`. */ private[sbt] def substituteCross( - exclude: SbtExclusionRule, + exclude: ExclusionRule, is: Option[IvyScala] - ): SbtExclusionRule = { + ): ExclusionRule = { val fopt: Option[String => String] = is flatMap { i => CrossVersion(exclude.crossVersion, i.scalaFullVersion, i.scalaBinaryVersion) @@ -111,8 +108,7 @@ abstract class CrossVersionFunctions { private[sbt] def substituteCrossA( as: Vector[Artifact], cross: Option[String => String] - ): Vector[Artifact] = - as.map(art => substituteCross(art, cross)) + ): Vector[Artifact] = as.map(art => substituteCross(art, cross)) /** * Constructs a function that will cross-version a ModuleID diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala index 82ddace88..25eb5bc13 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala @@ -5,9 +5,30 @@ package sbt.librarymanagement import org.apache.ivy.core.module.descriptor import org.apache.ivy.util.filter.{ Filter => IvyFilter } +import sbt.internal.librarymanagement.impl.{ GroupArtifactID, GroupID } abstract class InclExclRuleFunctions { - def everything = InclExclRule("*", "*", "*", Vector.empty) + def everything = InclExclRule("*", "*", "*", Vector.empty, Disabled()) + + def apply(organization: String, name: String): InclExclRule = + InclExclRule(organization, name, "*", Vector.empty, Disabled()) + + def apply(organization: String): InclExclRule = apply(organization, "*") + + implicit def groupIdToExclusionRule(organization: GroupID): InclExclRule = + apply(organization.groupID) + implicit def stringToExclusionRule(organization: String): InclExclRule = apply(organization) + + implicit def groupArtifactIDToExclusionRule(gaid: GroupArtifactID): InclExclRule = + InclExclRule(gaid.groupID, gaid.artifactID, "*", Vector.empty, gaid.crossVersion) + + implicit def moduleIDToExclusionRule(moduleID: ModuleID): InclExclRule = { + val org = moduleID.organization + val name = moduleID.name + val version = moduleID.revision + val crossVersion = moduleID.crossVersion + InclExclRule(org, name, version, Vector.empty, crossVersion) + } } abstract class ArtifactTypeFilterExtra { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 7fbb5f348..5b89b5419 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -121,11 +121,11 @@ abstract class ModuleIDExtra { * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify * both the exact organization and name and nothing else will be included in a pom.xml. */ - def excludeAll(rules: InclExclRule*) = copy(exclusions = this.exclusions ++ rules) + def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ def exclude(org: String, name: String) = - excludeAll(InclExclRule().withOrganization(org).withName(name)) + excludeAll(ExclusionRule().withOrganization(org).withName(name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. diff --git a/librarymanagement/src/test/scala/InclExclSpec.scala b/librarymanagement/src/test/scala/InclExclSpec.scala new file mode 100644 index 000000000..c3a867550 --- /dev/null +++ b/librarymanagement/src/test/scala/InclExclSpec.scala @@ -0,0 +1,67 @@ +package sbt.librarymanagement + +import org.scalatest.Assertion +import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.internal.librarymanagement.impl.{ DependencyBuilders, GroupArtifactID } + +class InclExclSpec extends BaseIvySpecification with DependencyBuilders { + def createLiftDep(toExclude: ExclusionRule): ModuleID = + ("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile").excludeAll(toExclude) + + def createMetaDep(toExclude: ExclusionRule): ModuleID = + ("org.scalameta" %% "paradise" % "3.0.0-M8" % "compile") + .cross(CrossVersion.full) + .excludeAll(toExclude) + + def getIvyReport(dep: ModuleID, scalaVersion: Option[String]): UpdateReport = { + cleanIvyCache() + val ivyModule = module(defaultModuleId, Vector(dep), scalaVersion) + ivyUpdate(ivyModule) + } + + def testLiftJsonIsMissing(report: UpdateReport): Assertion = { + assert( + !report.allModules.exists(_.name.contains("lift-json")), + "lift-json has not been excluded." + ) + } + + def testScalahostIsMissing(report: UpdateReport): Assertion = { + assert( + !report.allModules.exists(_.name.contains("scalahost")), + "scalahost has not been excluded." + ) + } + + val scala210 = Some("2.10.4") + it should "exclude any version of lift-json via a new exclusion rule" in { + val toExclude = ExclusionRule("net.liftweb", "lift-json_2.10") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testLiftJsonIsMissing(report) + } + + it should "exclude any version of lift-json with explicit Scala version" in { + val excluded: GroupArtifactID = "net.liftweb" % "lift-json_2.10" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + it should "exclude any version of cross-built lift-json" in { + val excluded: GroupArtifactID = "net.liftweb" %% "lift-json" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + val scala2122 = Some("2.12.2") + it should "exclude a concrete version of lift-json when it's full cross version" in { + val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } + + it should "exclude any version of lift-json when it's full cross version" in { + val excluded = new GroupArtifactID("net.liftweb", "lift-json", CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } +} From 8c993d2d531381585a07c3a3e81c84826fa9f893 Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 26 Apr 2017 23:34:47 +0200 Subject: [PATCH 0590/1030] Fix sbt/sbt#2982: Add a parallel Ivy engine This is a port of https://github.com/sbt/sbt/pull/2992. Original description of the feature: ``` Ivy downloads have traditionally been single-threaded. Parallel downloads are a must for a modern build tool. This commit builds upon the work done by Josh Suereth in the branch sbt/ivy-parallel-download-artifact. To avoid adding external dependencies, it uses the Scala parallel collections. If maintainers consider that is worth it to use a more modern and appropriate approach, like Task, I'm happy to reimplement the features with it. ``` This commit does not preserve Josh's metadata in the commit since the whole design of the repository has changed and I did not know how to import a commit from sbt/sbt. However, it does apply several changes to the original PR. Co-authored-by: Josh Suereth --- .../sbt/internal/librarymanagement/Ivy.scala | 92 ++++++++++------ .../ivyint/ParallelResolveEngine.scala | 102 ++++++++++++++++++ 2 files changed, 160 insertions(+), 34 deletions(-) create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index b5084ffb6..f10561d3a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -12,17 +12,17 @@ import org.apache.ivy.core.IvyPatternHelper import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.module.descriptor.{ - Artifact => IArtifact, DefaultArtifact, DefaultDependencyArtifactDescriptor, - MDArtifact + MDArtifact, + Artifact => IArtifact } import org.apache.ivy.core.module.descriptor.{ DefaultDependencyDescriptor, DefaultModuleDescriptor, DependencyDescriptor, - ModuleDescriptor, - License + License, + ModuleDescriptor } import org.apache.ivy.core.module.descriptor.OverrideDependencyDescriptorMediator import org.apache.ivy.core.module.id.{ ModuleId, ModuleRevisionId } @@ -36,13 +36,13 @@ import org.apache.ivy.util.extendable.ExtendableItem import scala.xml.NodeSeq import scala.collection.mutable - import sbt.util.Logger import sbt.librarymanagement._ import Resolver.PluginPattern import ivyint.{ - CachedResolutionResolveEngine, CachedResolutionResolveCache, + CachedResolutionResolveEngine, + ParallelResolveEngine, SbtDefaultDependencyDescriptor } @@ -101,35 +101,59 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } is } - private[sbt] def mkIvy: Ivy = { - val i = new Ivy() { - private val loggerEngine = new SbtMessageLoggerEngine - override def getLoggerEngine = loggerEngine - override def bind(): Unit = { - val prOpt = Option(getSettings.getResolver(ProjectResolver.InterProject)) map { - case pr: ProjectResolver => pr - } - // We inject the deps we need before we can hook our resolve engine. - setSortEngine(new SortEngine(getSettings)) - setEventManager(new EventManager()) - if (configuration.updateOptions.cachedResolution) { - setResolveEngine( - new ResolveEngine(getSettings, getEventManager, getSortEngine) - with CachedResolutionResolveEngine { - val cachedResolutionResolveCache = IvySbt.cachedResolutionResolveCache - val projectResolver = prOpt - def makeInstance = mkIvy - } - ) - } else setResolveEngine(new ResolveEngine(getSettings, getEventManager, getSortEngine)) - super.bind() - } - } - i.setSettings(settings) - i.bind() - i.getLoggerEngine.pushLogger(new IvyLoggerInterface(configuration.log)) - i + /** Defines a parallel [[CachedResolutionResolveEngine]]. + * + * This is defined here because it needs access to [[mkIvy]]. + */ + private class ParallelCachedResolutionResolveEngine( + settings: IvySettings, + eventManager: EventManager, + sortEngine: SortEngine + ) extends ParallelResolveEngine(settings, eventManager, sortEngine) + with CachedResolutionResolveEngine { + def makeInstance: Ivy = mkIvy + val cachedResolutionResolveCache: CachedResolutionResolveCache = + IvySbt.cachedResolutionResolveCache + val projectResolver: Option[ProjectResolver] = { + val res = settings.getResolver(ProjectResolver.InterProject) + Option(res.asInstanceOf[ProjectResolver]) + } + } + + /** Provides a default ivy implementation that decides which resolution + * engine to use depending on the passed ivy configuration options. */ + private class IvyImplementation extends Ivy { + private val loggerEngine = new SbtMessageLoggerEngine + override def getLoggerEngine: SbtMessageLoggerEngine = loggerEngine + override def bind(): Unit = { + val settings = getSettings + val eventManager = new EventManager() + val sortEngine = new SortEngine(settings) + + // We inject the deps we need before we can hook our resolve engine. + setSortEngine(sortEngine) + setEventManager(eventManager) + + val resolveEngine = { + // Decide to use cached resolution if user enabled it + if (configuration.updateOptions.cachedResolution) + new ParallelCachedResolutionResolveEngine(settings, eventManager, sortEngine) + else new ParallelResolveEngine(settings, eventManager, sortEngine) + } + + setResolveEngine(resolveEngine) + super.bind() + } + } + + private[sbt] def mkIvy: Ivy = { + val ivy = new IvyImplementation() + ivy.setSettings(settings) + ivy.bind() + val logger = new IvyLoggerInterface(configuration.log) + ivy.getLoggerEngine.pushLogger(logger) + ivy } private lazy val ivy: Ivy = mkIvy diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala new file mode 100644 index 000000000..4e3b4bedd --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -0,0 +1,102 @@ +package sbt.internal.librarymanagement.ivyint + +import org.apache.ivy.core.event.EventManager +import org.apache.ivy.core.event.download.PrepareDownloadEvent +import org.apache.ivy.core.module.descriptor.Artifact +import org.apache.ivy.core.report._ +import org.apache.ivy.core.resolve._ +import org.apache.ivy.core.sort.SortEngine +import org.apache.ivy.util.Message +import org.apache.ivy.util.filter.Filter + +import scala.collection.parallel.mutable.ParArray + +private[ivyint] case class DownloadResult(dep: IvyNode, + report: DownloadReport, + totalSizeDownloaded: Long) + +/** Define an ivy [[ResolveEngine]] that resolves dependencies in parallel. */ +private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, + eventManager: EventManager, + sortEngine: SortEngine) + extends ResolveEngine(settings, eventManager, sortEngine) { + + override def downloadArtifacts(report: ResolveReport, + artifactFilter: Filter, + options: DownloadOptions): Unit = { + + val start = System.currentTimeMillis + val dependencies0 = report.getDependencies + val dependencies = dependencies0 + .toArray(new Array[IvyNode](dependencies0.size)) + val artifacts = report.getArtifacts + .toArray(new Array[Artifact](report.getArtifacts.size)) + + getEventManager.fireIvyEvent(new PrepareDownloadEvent(artifacts)) + + // Farm out the dependencies for parallel download + val allDownloads = dependencies.par.flatMap { dep => + if (!(dep.isCompletelyEvicted || dep.hasProblem) && + dep.getModuleRevision != null) { + ParArray(downloadNodeArtifacts(dep, artifactFilter, options)) + } else ParArray.empty[DownloadResult] + } + + // Force parallel downloads and compute total downloaded size + val totalSize = allDownloads.toArray.foldLeft(0L) { + case (size, download) => + val dependency = download.dep + val moduleConfigurations = dependency.getRootModuleConfigurations + moduleConfigurations.foreach { configuration => + val configurationReport = report.getConfigurationReport(configuration) + + // Take into account artifacts required by the given configuration + if (dependency.isEvicted(configuration) || + dependency.isBlacklisted(configuration)) { + configurationReport.addDependency(dependency) + } else configurationReport.addDependency(dependency, download.report) + } + + size + download.totalSizeDownloaded + } + + report.setDownloadTime(System.currentTimeMillis() - start) + report.setDownloadSize(totalSize) + } + + /** + * Download all the artifacts associated with an ivy node. + * + * Return the report and the total downloaded size. + */ + private def downloadNodeArtifacts(dependency: IvyNode, + artifactFilter: Filter, + options: DownloadOptions): DownloadResult = { + + val resolver = dependency.getModuleRevision.getArtifactResolver + val selectedArtifacts = dependency.getSelectedArtifacts(artifactFilter) + val downloadReport = resolver.download(selectedArtifacts, options) + val artifactReports = downloadReport.getArtifactsReports + + val totalSize = artifactReports.foldLeft(0L) { (size, artifactReport) => + // Check download status and report resolution failures + artifactReport.getDownloadStatus match { + case DownloadStatus.SUCCESSFUL => + size + artifactReport.getSize + case DownloadStatus.FAILED => + val artifact = artifactReport.getArtifact + val mergedAttribute = artifact.getExtraAttribute("ivy:merged") + if (mergedAttribute != null) { + Message.warn(s"\tMissing merged artifact: $artifact, required by $mergedAttribute.") + } else { + Message.warn(s"\tDetected merged artifact: $artifactReport.") + resolver.reportFailure(artifactReport.getArtifact) + } + size + case _ => size + } + } + + DownloadResult(dependency, downloadReport, totalSize) + } +} From b68498d013fd5de33758921318f23e9351d58b59 Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 27 Apr 2017 21:22:33 +0200 Subject: [PATCH 0591/1030] Remove unused arguments in clean and use site `cleanCachedResolutionCache` and `clean` were doing extra work because `clean` does only need to clean the cache in the configuration (that is a class parameter). --- .../scala/sbt/internal/librarymanagement/Ivy.scala | 13 ++++--------- .../ivyint/CachedResolutionResolveEngine.scala | 5 ++--- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index b5084ffb6..d0218ad9e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -159,15 +159,10 @@ final class IvySbt(val configuration: IvyConfiguration) { self => * * @param md - module descriptor of the original Ivy graph. */ - private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = - withIvy(log) { i => - val prOpt = Option(i.getSettings.getResolver(ProjectResolver.InterProject)) map { - case pr: ProjectResolver => pr - } - if (configuration.updateOptions.cachedResolution) { - IvySbt.cachedResolutionResolveCache.clean(md, prOpt) - } - } + private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = { + if (!configuration.updateOptions.cachedResolution) () + else IvySbt.cachedResolutionResolveCache.clean() + } final class Module(rawModuleSettings: ModuleSettings) { val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 0b4e2b92a..cfb2cc755 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -64,9 +64,8 @@ private[sbt] class CachedResolutionResolveCache { val maxConflictCacheSize: Int = 1024 val maxUpdateReportCacheSize: Int = 1024 - def clean(md0: ModuleDescriptor, prOpt: Option[ProjectResolver]): Unit = { - updateReportCache.clear - } + def clean(): Unit = updateReportCache.clear + def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector // Returns a vector of (module descriptor, changing, dd) From eea500d64f7d5ac5c38da2096cbabdc436c36643 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:12:34 +0200 Subject: [PATCH 0592/1030] Remove coded uplication in `updateEither` This commit reduces the code duplication in `updateEither` which was duplicating a good deal of the resolution logic to deal with the different resolution mechanisms: the simple one and the cached one. It also unifies the signatures of the helpers that are invoked by `updateEither`, removing the weirdness of the different return type signatures and ad-hoc logic handling. --- .../librarymanagement/IvyActions.scala | 182 +++++++++++------- 1 file changed, 112 insertions(+), 70 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index aad711ff5..c5bce8839 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -236,56 +236,32 @@ object IvyActions { logicalClock: LogicalClock, depDir: Option[File], log: Logger - ): Either[UnresolvedWarning, UpdateReport] = + ): Either[UnresolvedWarning, UpdateReport] = { module.withModule(log) { - case (ivy, md, default) - if module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined => - ivy.getResolveEngine match { - case x: CachedResolutionResolveEngine => - val iw = IvySbt.inconsistentDuplicateWarning(md) - iw foreach { log.warn(_) } - val resolveOptions = new ResolveOptions - val resolveId = ResolveOptions.getDefaultResolveId(md) - resolveOptions.setResolveId(resolveId) - resolveOptions.setArtifactFilter(configuration.artifactFilter) - resolveOptions.setLog(ivyLogLevel(configuration.logging)) - x.customResolve( - md, - configuration.missingOk, - logicalClock, - resolveOptions, - depDir getOrElse { - sys.error("dependency base directory is not specified") - }, - log - ) match { - case Left(x) => - Left(UnresolvedWarning(x, uwconfig)) - case Right(uReport) => - configuration.retrieve match { - case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) - case None => Right(uReport) - } - } - } - case (ivy, md, default) => - val iw = IvySbt.inconsistentDuplicateWarning(md) - iw foreach { log.warn(_) } - val (report, err) = - resolve(configuration.logging)(ivy, md, default, configuration.artifactFilter) - err match { - case Some(x) if !configuration.missingOk => - Left(UnresolvedWarning(x, uwconfig)) - case _ => - val cachedDescriptor = ivy.getSettings.getResolutionCacheManager - .getResolvedIvyFileInCache(md.getModuleRevisionId) - val uReport = IvyRetrieve.updateReport(report, cachedDescriptor) - configuration.retrieve match { - case Some(rConf) => Right(retrieve(log, ivy, uReport, rConf)) - case None => Right(uReport) - } + case (ivy, moduleDescriptor, defaultConf) => + // Warn about duplicated and inconsistent dependencies + val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) + iw.foreach(log.warn(_)) + + // Create inputs, resolve and retrieve the module descriptor + val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) + val resolutionResult: Either[ResolveException, UpdateReport] = { + if (module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined) { + val cache = depDir.getOrElse(sys.error("Missing directory for cached resolution.")) + cachedResolveAndRetrieve(inputs, logicalClock, cache) + } else resolveAndRetrieve(inputs, defaultConf) } + + // Convert to unresolved warning or retrieve update report + resolutionResult.fold( + exception => Left(UnresolvedWarning(exception, uwconfig)), + updateReport => { + val retrieveConf = configuration.retrieve + Right(retrieveConf.map(retrieve(log, ivy, updateReport, _)).getOrElse(updateReport)) + } + ) } + } @deprecated("No longer used.", "0.13.6") def processUnresolved(err: ResolveException, log: Logger): Unit = () def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)( @@ -496,38 +472,104 @@ object IvyActions { .withConfigurations(if (confs) m.configurations else None) .branch(m.branchName) - private[this] def resolve(logging: UpdateLogging)( + /** + * Represents the inputs to pass in to [[resolveAndRetrieve]] and [[cachedResolveAndRetrieve]]. + * + * @param ivy The ivy instance to resolve and retrieve dependencies. + * @param module The module descriptor to be resolved. + * @param updateConfiguration The update configuration for [[ResolveOptions]]. + * @param log The logger. + */ + private case class ResolutionInputs( ivy: Ivy, module: DefaultModuleDescriptor, - defaultConf: String, - filter: ArtifactTypeFilter - ): (ResolveReport, Option[ResolveException]) = { + updateConfiguration: UpdateConfiguration, + log: Logger + ) + + /** + * Defines the internal entrypoint of module resolution and retrieval. + * + * This method is the responsible of populating [[ResolveOptions]] and pass + * it in to the ivy instance to perform the module resolution. + * + * It returns an already resolved [[UpdateReport]] instead of a [[ResolveReport]] + * like its counterpart [[CachedResolutionResolveEngine.customResolve]]. + * + * @param inputs The resolution inputs. + * @param defaultModuleConfiguration The default ivy configuration. + * @return The result of the resolution. + */ + private[this] def resolveAndRetrieve( + inputs: ResolutionInputs, + defaultModuleConfiguration: String + ): Either[ResolveException, UpdateReport] = { + // Populate resolve options from the passed arguments + val ivyInstance = inputs.ivy + val moduleDescriptor = inputs.module + val updateConfiguration = inputs.updateConfiguration + val logging = updateConfiguration.logging val resolveOptions = new ResolveOptions - val resolveId = ResolveOptions.getDefaultResolveId(module) + val resolveId = ResolveOptions.getDefaultResolveId(moduleDescriptor) resolveOptions.setResolveId(resolveId) - resolveOptions.setArtifactFilter(filter) + resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) resolveOptions.setLog(ivyLogLevel(logging)) ResolutionCache.cleanModule( - module.getModuleRevisionId, + moduleDescriptor.getModuleRevisionId, resolveId, - ivy.getSettings.getResolutionCacheManager + ivyInstance.getSettings.getResolutionCacheManager ) - val resolveReport = ivy.resolve(module, resolveOptions) - val err = - if (resolveReport.hasError) { - val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct - val failedPaths = Map(resolveReport.getUnresolvedDependencies map { node => - val m = IvyRetrieve.toModuleID(node.getId) - val path = IvyRetrieve.findPath(node, module.getModuleRevisionId) map { x => - IvyRetrieve.toModuleID(x.getId) - } - m -> path - }: _*) - val failed = failedPaths.keys.toSeq - Some(new ResolveException(messages, failed, failedPaths)) - } else None - (resolveReport, err) + + val resolveReport = ivyInstance.resolve(moduleDescriptor, resolveOptions) + if (resolveReport.hasError && !inputs.updateConfiguration.missingOk) { + // If strict error, collect report information and generated UnresolvedWarning + val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct + val failedPaths = resolveReport.getUnresolvedDependencies.map { node => + val moduleID = IvyRetrieve.toModuleID(node.getId) + val path = IvyRetrieve + .findPath(node, moduleDescriptor.getModuleRevisionId) + .map(x => IvyRetrieve.toModuleID(x.getId)) + moduleID -> path + }.toMap + val failedModules = failedPaths.keys.toSeq + Left(new ResolveException(messages, failedModules, failedPaths)) + } else { + // If no strict error, we convert the resolve report into an update report + val cachedDescriptor = ivyInstance.getSettings.getResolutionCacheManager + .getResolvedIvyFileInCache(moduleDescriptor.getModuleRevisionId) + Right(IvyRetrieve.updateReport(resolveReport, cachedDescriptor)) + } } + + /** + * Resolves and retrieves a module with a cache mechanism defined + * here. + * + * It's the cached version of [[resolveAndRetrieve]]. + * + * @param inputs The resolution inputs. + * @param logicalClock The clock to check if a file is outdated or not. + * @param cache The optional cache dependency. + * @return The result of the cached resolution. + */ + private[this] def cachedResolveAndRetrieve( + inputs: ResolutionInputs, + logicalClock: LogicalClock, + cache: File + ): Either[ResolveException, UpdateReport] = { + val log = inputs.log + val descriptor = inputs.module + val updateConfiguration = inputs.updateConfiguration + val resolver = inputs.ivy.getResolveEngine.asInstanceOf[CachedResolutionResolveEngine] + val resolveOptions = new ResolveOptions + val resolveId = ResolveOptions.getDefaultResolveId(descriptor) + resolveOptions.setResolveId(resolveId) + resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) + resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging)) + val acceptError = updateConfiguration.missingOk + resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log) + } + private def retrieve( log: Logger, ivy: Ivy, From 258cb7c5ac863fd5e9376811b7a3d207a16b4595 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:16:39 +0200 Subject: [PATCH 0593/1030] Remove unused instance of `retrieve` This commit removes the second instance of `retrieve` that was private and unused, therefore reducing the API surface of `IvyActions`. --- .../librarymanagement/IvyActions.scala | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index c5bce8839..2e5d7bef6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -575,27 +575,11 @@ object IvyActions { ivy: Ivy, report: UpdateReport, config: RetrieveConfiguration - ): UpdateReport = - retrieve( - log, - ivy, - report, - config.retrieveDirectory, - config.outputPattern, - config.sync, - config.configurationsToRetrieve - ) - - private def retrieve( - log: Logger, - ivy: Ivy, - report: UpdateReport, - base: File, - pattern: String, - sync: Boolean, - configurationsToRetrieve: Option[Set[Configuration]] ): UpdateReport = { - val configurationNames = configurationsToRetrieve match { + val toRetrieve = config.configurationsToRetrieve + val base = config.retrieveDirectory + val pattern = config.outputPattern + val configurationNames = toRetrieve match { case None => None case Some(configs) => Some(configs.map(_.name)) } @@ -611,7 +595,7 @@ object IvyActions { } IO.copy(toCopy) val resolvedFiles = toCopy.map(_._2) - if (sync) { + if (config.sync) { val filesToDelete = existingFiles.filterNot(resolvedFiles.contains) filesToDelete foreach { f => log.info(s"Deleting old dependency: ${f.getAbsolutePath}") From c84d2979122745ea4bc3942fccc61903435fcaf4 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:23:03 +0200 Subject: [PATCH 0594/1030] Turn `ResolveException` private[sbt] Plus, remove deprecated method using `ResolveException`. --- .../scala/sbt/internal/librarymanagement/IvyActions.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 2e5d7bef6..f13ebb7dd 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -262,8 +262,7 @@ object IvyActions { ) } } - @deprecated("No longer used.", "0.13.6") - def processUnresolved(err: ResolveException, log: Logger): Unit = () + def groupedConflicts[T](moduleFilter: ModuleFilter, grouping: ModuleID => T)( report: UpdateReport ): Map[T, Set[String]] = @@ -685,7 +684,8 @@ object IvyActions { ) } } -final class ResolveException( + +private[sbt] final class ResolveException( val messages: Seq[String], val failed: Seq[ModuleID], val failedPaths: Map[ModuleID, Seq[ModuleID]] From 1f4030ff17b4bca9d6957f9332e59945db3fead7 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:24:35 +0200 Subject: [PATCH 0595/1030] Remove unused apply in `UnresolvedWarning` --- .../scala/sbt/internal/librarymanagement/IvyActions.scala | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index f13ebb7dd..a6e21056a 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -723,13 +723,9 @@ object UnresolvedWarning { (id, modulePosition(id)) } } - apply(err, failedPaths) - } - private[sbt] def apply( - err: ResolveException, - failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] - ): UnresolvedWarning = new UnresolvedWarning(err, failedPaths) + } + private[sbt] def sourcePosStr(posOpt: Option[SourcePosition]): String = posOpt match { case Some(LinePosition(path, start)) => s" ($path#L$start)" From 429dd843935a309e3df4a444fc40dd29cb0ae121 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:27:45 +0200 Subject: [PATCH 0596/1030] Remove deprecated methods in `IvyActions` --- .../librarymanagement/IvyActions.scala | 55 ------------------- 1 file changed, 55 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index a6e21056a..49b0e1091 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -202,29 +202,6 @@ object IvyActions { zipped map { case (a, ivyA) => (ivyA, artifacts(a)) } } - /** - * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. - * 'updateConfig' configures the actual resolution and retrieval process. - */ - @deprecated("This is no longer public.", "0.13.6") - def update( - module: IvySbt#Module, - configuration: UpdateConfiguration, - log: Logger - ): UpdateReport = - updateEither( - module, - configuration, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - None, - log - ) match { - case Right(r) => r - case Left(w) => - throw w.resolveException - } - /** * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. * 'updateConfig' configures the actual resolution and retrieval process. @@ -277,23 +254,6 @@ object IvyActions { def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = mods groupBy (grouping) mapValues (_.map(_.revision).toSet) - @deprecated("This is no longer public.", "0.13.6") - def transitiveScratch( - ivySbt: IvySbt, - label: String, - config: GetClassifiersConfiguration, - log: Logger - ): UpdateReport = - transitiveScratch( - ivySbt, - label, - config, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - None, - log - ) - private[sbt] def transitiveScratch( ivySbt: IvySbt, label: String, @@ -316,21 +276,6 @@ object IvyActions { val newConfig = config.copy(module = mod.copy(modules = report.allModules)) updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) } - @deprecated("This is no longer public.", "0.13.6") - def updateClassifiers( - ivySbt: IvySbt, - config: GetClassifiersConfiguration, - log: Logger - ): UpdateReport = - updateClassifiers( - ivySbt, - config, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - None, - Vector(), - log - ) /** * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This From 0885ae1a966df34c68c9df532f18bf583e7c1380 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 28 Apr 2017 01:32:07 +0200 Subject: [PATCH 0597/1030] Add documentation to `updateEither` --- .../internal/librarymanagement/IvyActions.scala | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 49b0e1091..0c7cef4a6 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -203,8 +203,18 @@ object IvyActions { } /** - * Resolves and retrieves dependencies. 'ivyConfig' is used to produce an Ivy file and configuration. - * 'updateConfig' configures the actual resolution and retrieval process. + * Updates one module's dependencies performing a dependency resolution and retrieval. + * + * The following mechanism uses ivy under the hood. + * + * @param module The module to be resolved. + * @param configuration The update configuration. + * @param uwconfig The configuration to handle unresolved warnings. + * @param logicalClock The clock necessary to cache ivy. + * @param depDir The base directory used for caching resolution. + * @param log The logger. + * @return The result, either an unresolved warning or an update report. Note that this + * update report will or will not be successful depending on the `missingOk` option. */ private[sbt] def updateEither( module: IvySbt#Module, From 1a11fd86a3b8b4aab467caacae4707e2e40fd205 Mon Sep 17 00:00:00 2001 From: jvican Date: Tue, 9 May 2017 10:59:54 +0200 Subject: [PATCH 0598/1030] Disable parallel execution --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index aed7152ab..2e07ce2ce 100644 --- a/build.sbt +++ b/build.sbt @@ -19,6 +19,7 @@ def commonSettings: Seq[Setting[_]] = Seq( mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false, + parallelExecution in Test := false, commands += Command.command("scalafmtCheck") { state => sys.process.Process("git diff --name-only --exit-code").! match { case 0 => // ok From 67d9012a17726a7f0a2d9e5d8800dc26adbedf87 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 5 May 2017 17:25:10 +0200 Subject: [PATCH 0599/1030] Add offline mode to `UpdateConfiguration` The following commit tries to address the well-known issue that sbt cannot be used in offline mode. In order to enable that use case, this commit adds support for a flag in update configuration called `offline` that users can change as they wish (and that sbt will expose via settings). It adds tests to check that the resolution uses the caches instead of trying to resolve from the Internet. Unfortunately, ivy does not expose a way to know whether a resolution was made from the cache or the Internet, so the test case invents a metric to check that resolution indeed happens from cache. In order to benefit from this 100%, we need to update to ivy 2.4.0 or cherry-pick a commit because a major issue in `useCacheOnly` has been fixed: https://issues.apache.org/jira/browse/IVY-1515. In short, this is good for the dependency lock file too. Since we can make sure that once we have downloaded and resolved all the dependencies locally, we do resolve from the cache. --- .../main/contraband/librarymanagement.json | 3 +- .../librarymanagement/IvyActions.scala | 2 + .../DefaultLibraryManagement.scala | 3 +- .../src/test/scala/BaseIvySpecification.scala | 7 +- .../src/test/scala/OfflineModeSpec.scala | 69 +++++++++++++++++++ .../librarymanagement/IvyRepoSpec.scala | 2 +- 6 files changed, 80 insertions(+), 6 deletions(-) create mode 100644 librarymanagement/src/test/scala/OfflineModeSpec.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index c93091568..3758bd902 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -634,7 +634,8 @@ { "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" }, { "name": "missingOk", "type": "boolean" }, { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, - { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" } + { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }, + { "name": "offline", "type": "boolean" } ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 0c7cef4a6..4d8465a10 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -467,6 +467,7 @@ object IvyActions { val resolveId = ResolveOptions.getDefaultResolveId(moduleDescriptor) resolveOptions.setResolveId(resolveId) resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) + resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(logging)) ResolutionCache.cleanModule( moduleDescriptor.getModuleRevisionId, @@ -519,6 +520,7 @@ object IvyActions { val resolveId = ResolveOptions.getDefaultResolveId(descriptor) resolveOptions.setResolveId(resolveId) resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) + resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging)) val acceptError = updateConfiguration.missingOk resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 43bf8b231..3c5d38167 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -68,7 +68,8 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) Some(retrieveConfiguration), true, UpdateLogging.DownloadOnly, - artifactFilter + artifactFilter, + false ) log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.") diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 50a7f1f95..b01f1407d 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -69,18 +69,19 @@ trait BaseIvySpecification extends UnitSpec { log) } - def makeUpdateConfiguration: UpdateConfiguration = { + def makeUpdateConfiguration(offline: Boolean): UpdateConfiguration = { val retrieveConfig = RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) UpdateConfiguration(Some(retrieveConfig), false, UpdateLogging.Full, - ArtifactTypeFilter.forbid(Set("src", "doc"))) + ArtifactTypeFilter.forbid(Set("src", "doc")), + offline) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val config = makeUpdateConfiguration + val config = makeUpdateConfiguration(false) IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala new file mode 100644 index 000000000..903b7125d --- /dev/null +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -0,0 +1,69 @@ +package sbt.librarymanagement + +import org.scalatest.Assertion +import sbt.internal.librarymanagement._ +import sbt.internal.librarymanagement.impl.DependencyBuilders + +class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { + private final val targetDir = Some(currentDependency) + private final val onlineConf = makeUpdateConfiguration(false) + private final val offlineConf = makeUpdateConfiguration(true) + private final val noClock = LogicalClock.unknown + private final val warningConf = UnresolvedWarningConfiguration() + private final val normalOptions = UpdateOptions() + private final val cachedOptions = UpdateOptions().withCachedResolution(true) + + final val scalaCompiler = Vector("org.scala-lang" % "scala-compiler" % "2.12.2" % "compile") + + def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Assertion = { + cleanIvyCache() + + val toResolve = module(defaultModuleId, scalaCompiler, None, updateOptions) + val isCachedResolution = updateOptions.cachedResolution + if (isCachedResolution) cleanCachedResolutionCache(toResolve) + + val onlineResolution = + IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) + assert(onlineResolution.isRight) + assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0)) + + // Compute an estimate to ensure that the second resolution does indeed use the cache + val resolutionTime: Long = onlineResolution.right.map(_.stats.resolveTime).getOrElse(0L) + val estimatedCachedTime = resolutionTime * 0.15 + + val offlineResolution = + IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) + assert(offlineResolution.isRight) + + if (!isCachedResolution) { + // Only check the estimate for the non cached resolution, otherwise resolution is cached + assert(offlineResolution.right.exists(_.stats.resolveTime <= estimatedCachedTime), + "Offline resolution took more than 15% of normal resolution's running time.") + } else assert(true) // We cannot check offline resolution if it's cached. + } + + "Offline update configuration" should "reuse the caches when it's enabled" in { + checkOnlineAndOfflineResolution(normalOptions) + } + + it should "work with cached resolution" in { + checkOnlineAndOfflineResolution(cachedOptions) + } + + def checkFailingResolution(updateOptions: UpdateOptions): Assertion = { + cleanIvyCache() + val toResolve = module(defaultModuleId, scalaCompiler, None, updateOptions) + if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve) + val failedOfflineResolution = + IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) + assert(failedOfflineResolution.isLeft) + } + + it should "fail when artifacts are missing in the cache" in { + checkFailingResolution(normalOptions) + } + + it should "fail when artifacts are missing in the cache for cached resolution" in { + checkFailingResolution(cachedOptions) + } +} diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 61c9aa27c..51be80d06 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -44,7 +44,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val m = makeModuleForDepWithSources // the "default" configuration used in updateEither. - val c = makeUpdateConfiguration + val c = makeUpdateConfiguration(false) val ivyScala = m.moduleSettings.ivyScala val srcTypes = Set("src") From 96c775c4454bcc8be73bb6f68968bfbebbf0d87e Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 5 May 2017 20:41:32 +0200 Subject: [PATCH 0600/1030] Remove previous custom offline implementation The previous custom offline implementation was not working on 100% of the cases and relied on the TTL of ivy. As the previous commit enabled the native offline implementation provided by ivy as of 2.3.0, this functionality is not useful anymore. The current place to specify offline is `UpdateConfiguration`, and not `InlineIvyConfiguration` that is required to instantiate sbt. With the current approach, we can be online or offline without having to instantiate ivy sbt twice. I will provide a Scalafix rewrite for this change. --- .../main/contraband/librarymanagement.json | 4 +- .../librarymanagement/ConvertResolver.scala | 2 +- .../sbt/internal/librarymanagement/Ivy.scala | 51 +++++----------- .../internal/librarymanagement/IvyCache.scala | 1 - .../src/test/scala/BaseIvySpecification.scala | 2 - .../src/test/scala/CustomPomParserTest.scala | 1 - .../src/test/scala/OfflineModeSpec.scala | 58 +++++++++++-------- 7 files changed, 52 insertions(+), 67 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 3758bd902..810ecc1ac 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -729,7 +729,6 @@ { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" }, { "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" }, { "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" }, - { "name": "localOnly", "type": "boolean" }, { "name": "checksums", "type": "String*" }, { "name": "resolutionCacheDir", "type": "java.io.File?" } ], @@ -739,7 +738,6 @@ " resolvers: Vector[sbt.librarymanagement.Resolver],", " otherResolvers: Vector[sbt.librarymanagement.Resolver],", " moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],", - " localOnly: Boolean,", " lock: Option[xsbti.GlobalLock],", " checksums: Vector[String],", " resolutionCacheDir: Option[java.io.File],", @@ -747,7 +745,7 @@ " log: xsbti.Logger", ") =", " this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,", - " moduleConfigurations, localOnly, checksums, resolutionCacheDir)" + " moduleConfigurations, checksums, resolutionCacheDir)" ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index c90ece754..82760272c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -202,7 +202,7 @@ private[sbt] object ConvertResolver { resolver } case repo: ChainedResolver => - IvySbt.resolverChain(repo.name, repo.resolvers, false, settings, log) + IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) case repo: RawRepository => repo.resolver } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 725f98e92..a3b250b78 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -88,16 +88,10 @@ final class IvySbt(val configuration: IvyConfiguration) { self => case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") i.paths.ivyHome foreach is.setDefaultIvyUserDir - IvySbt.configureCache(is, i.localOnly, i.resolutionCacheDir) - IvySbt.setResolvers( - is, - i.resolvers, - i.otherResolvers, - i.localOnly, - configuration.updateOptions, - configuration.log - ) - IvySbt.setModuleConfigurations(is, i.moduleConfigurations, configuration.log) + val log = configuration.log + IvySbt.configureCache(is, i.resolutionCacheDir) + IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, configuration.updateOptions, log) + IvySbt.setModuleConfigurations(is, i.moduleConfigurations, log) } is } @@ -342,13 +336,12 @@ private[sbt] object IvySbt { settings: IvySettings, resolvers: Seq[Resolver], other: Seq[Resolver], - localOnly: Boolean, updateOptions: UpdateOptions, log: Logger ): Unit = { def makeChain(label: String, name: String, rs: Seq[Resolver]) = { log.debug(label + " repositories:") - val chain = resolverChain(name, rs, localOnly, settings, updateOptions, log) + val chain = resolverChain(name, rs, settings, updateOptions, log) settings.addResolver(chain) chain } @@ -362,18 +355,17 @@ private[sbt] object IvySbt { module.revision endsWith "-SNAPSHOT" private[sbt] def isChanging(mrid: ModuleRevisionId): Boolean = mrid.getRevision endsWith "-SNAPSHOT" + def resolverChain( name: String, resolvers: Seq[Resolver], - localOnly: Boolean, settings: IvySettings, log: Logger - ): DependencyResolver = - resolverChain(name, resolvers, localOnly, settings, UpdateOptions(), log) + ): DependencyResolver = resolverChain(name, resolvers, settings, UpdateOptions(), log) + def resolverChain( name: String, resolvers: Seq[Resolver], - localOnly: Boolean, settings: IvySettings, updateOptions: UpdateOptions, log: Logger @@ -446,19 +438,12 @@ private[sbt] object IvySbt { ) } } - private def configureCache( - settings: IvySettings, - localOnly: Boolean, - resCacheDir: Option[File] - ): Unit = { - configureResolutionCache(settings, localOnly, resCacheDir) - configureRepositoryCache(settings, localOnly) + + private def configureCache(settings: IvySettings, resCacheDir: Option[File]): Unit = { + configureResolutionCache(settings, resCacheDir) + configureRepositoryCache(settings) } - private[this] def configureResolutionCache( - settings: IvySettings, - localOnly: Boolean, - resCacheDir: Option[File] - ): Unit = { + private[this] def configureResolutionCache(settings: IvySettings, resCacheDir: Option[File]) = { val base = resCacheDir getOrElse settings.getDefaultResolutionCacheBasedir settings.setResolutionCacheManager(new ResolutionCache(base, settings)) } @@ -485,7 +470,7 @@ private[sbt] object IvySbt { ) } - private[this] def configureRepositoryCache(settings: IvySettings, localOnly: Boolean): Unit = { + private[this] def configureRepositoryCache(settings: IvySettings): Unit = { val cacheDir = settings.getDefaultRepositoryCacheBasedir() val manager = new DefaultRepositoryCacheManager("default-cache", settings, cacheDir) { override def findModuleInCache( @@ -529,12 +514,8 @@ private[sbt] object IvySbt { manager.setDataFilePattern(PluginPattern + manager.getDataFilePattern) manager.setIvyPattern(PluginPattern + manager.getIvyPattern) manager.setUseOrigin(true) - if (localOnly) - manager.setDefaultTTL(java.lang.Long.MAX_VALUE) - else { - manager.setChangingMatcher(PatternMatcher.REGEXP) - manager.setChangingPattern(".*-SNAPSHOT") - } + manager.setChangingMatcher(PatternMatcher.REGEXP) + manager.setChangingPattern(".*-SNAPSHOT") settings.addRepositoryCacheManager(manager) settings.setDefaultRepositoryCacheManager(manager) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index c697b639f..bef341acc 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -108,7 +108,6 @@ class IvyCache(val ivyHome: Option[File]) { Vector(local), Vector.empty, Vector.empty, - false, lock, IvySbt.DefaultChecksums, None, diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index b01f1407d..20041ab04 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -54,14 +54,12 @@ trait BaseIvySpecification extends UnitSpec { val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) - val off = false val check = Vector.empty val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, resolvers, other, moduleConfs, - off, None, check, Some(resCacheDir), diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index ea0113596..950562638 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -19,7 +19,6 @@ class CustomPomParserTest extends UnitSpec { Vector(local), Vector.empty, Vector.empty, - false, None, Vector("sha1", "md5"), None, diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala index 903b7125d..0b941f405 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -3,24 +3,35 @@ package sbt.librarymanagement import org.scalatest.Assertion import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.io.IO class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { - private final val targetDir = Some(currentDependency) - private final val onlineConf = makeUpdateConfiguration(false) - private final val offlineConf = makeUpdateConfiguration(true) - private final val noClock = LogicalClock.unknown - private final val warningConf = UnresolvedWarningConfiguration() - private final val normalOptions = UpdateOptions() - private final val cachedOptions = UpdateOptions().withCachedResolution(true) + private final def targetDir = Some(currentDependency) + private final def onlineConf = makeUpdateConfiguration(false) + private final def offlineConf = makeUpdateConfiguration(true) + private final def warningConf = UnresolvedWarningConfiguration() + private final def normalOptions = UpdateOptions() + private final def cachedOptions = UpdateOptions().withCachedResolution(true) + private final def noClock = LogicalClock.unknown - final val scalaCompiler = Vector("org.scala-lang" % "scala-compiler" % "2.12.2" % "compile") + def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7") + def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40") + def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final") + final def dependencies: Vector[ModuleID] = + Vector(avro177, dataAvro1940, netty320).map(_.withConfigurations(Some("compile"))) + + def cleanAll(): Unit = { + cleanIvyCache() + IO.delete(currentTarget) + IO.delete(currentManaged) + IO.delete(currentDependency) + } def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Assertion = { - cleanIvyCache() - - val toResolve = module(defaultModuleId, scalaCompiler, None, updateOptions) - val isCachedResolution = updateOptions.cachedResolution - if (isCachedResolution) cleanCachedResolutionCache(toResolve) + cleanAll() + val toResolve = module(defaultModuleId, dependencies, None, updateOptions) + if (updateOptions.cachedResolution) + cleanCachedResolutionCache(toResolve) val onlineResolution = IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) @@ -28,31 +39,30 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0)) // Compute an estimate to ensure that the second resolution does indeed use the cache - val resolutionTime: Long = onlineResolution.right.map(_.stats.resolveTime).getOrElse(0L) - val estimatedCachedTime = resolutionTime * 0.15 + val originalResolveTime = onlineResolution.right.get.stats.resolveTime + val estimatedCachedTime = originalResolveTime * 0.15 val offlineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) assert(offlineResolution.isRight) - if (!isCachedResolution) { - // Only check the estimate for the non cached resolution, otherwise resolution is cached - assert(offlineResolution.right.exists(_.stats.resolveTime <= estimatedCachedTime), - "Offline resolution took more than 15% of normal resolution's running time.") - } else assert(true) // We cannot check offline resolution if it's cached. + val resolveTime = offlineResolution.right.get.stats.resolveTime + // Only check the estimate for the non cached resolution, otherwise resolution is cached + assert(resolveTime <= estimatedCachedTime, + "Offline resolution took more than 15% of normal resolution's running time.") } - "Offline update configuration" should "reuse the caches when it's enabled" in { + "Offline update configuration" should "reuse the caches when offline is enabled" in { checkOnlineAndOfflineResolution(normalOptions) } - it should "work with cached resolution" in { + it should "reuse the caches when offline and cached resolution are enabled" in { checkOnlineAndOfflineResolution(cachedOptions) } def checkFailingResolution(updateOptions: UpdateOptions): Assertion = { - cleanIvyCache() - val toResolve = module(defaultModuleId, scalaCompiler, None, updateOptions) + cleanAll() + val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve) val failedOfflineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) From 89b722c13249aba7c5748381876e3bce3ef11a9e Mon Sep 17 00:00:00 2001 From: jvican Date: Tue, 9 May 2017 01:10:41 +0200 Subject: [PATCH 0601/1030] Update ivy version to include IVY-1515 https://github.com/sbt/ivy/pull/25 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b8a07cd13..ef67b2344 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -51,7 +51,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-48dd0744422128446aee9ac31aa356ee203cc9f4" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a3314352b638afbf0dca19f127e8263ed6f898bd" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") From 57d59087377d18d2a2714888ece173b1898effff Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 10 May 2017 20:15:51 +0200 Subject: [PATCH 0602/1030] Make `SbtChainResolver` readable This is the most important part of the sbt ivy management and it's almost unreadable in the previous shape... This attempts to make a rewrite without any semantic change. --- .../ivyint/SbtChainResolver.scala | 383 ++++++++++-------- 1 file changed, 213 insertions(+), 170 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 0c7f2c62c..da7e9f13d 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -1,21 +1,20 @@ package sbt.internal.librarymanagement package ivyint -import java.io.File +import java.io.{ ByteArrayOutputStream, File, PrintWriter } import java.text.ParseException import java.util.Date +import org.apache.ivy.core.cache.ArtifactOrigin import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.core.{ IvyContext, LogOptions } -import org.apache.ivy.core.module.descriptor.{ - Artifact => IArtifact, - DefaultModuleDescriptor, - ModuleDescriptor, - DependencyDescriptor -} -import org.apache.ivy.core.resolve.{ ResolvedModuleRevision, ResolveData } +import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor +import org.apache.ivy.core.module.descriptor.DependencyDescriptor +import org.apache.ivy.core.module.descriptor.ModuleDescriptor +import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } +import org.apache.ivy.core.resolve.{ ResolveData, ResolvedModuleRevision } import org.apache.ivy.plugins.latest.LatestStrategy -import org.apache.ivy.plugins.repository.file.{ FileRepository => IFileRepository, FileResource } +import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => IFileRepository } import org.apache.ivy.plugins.repository.url.URLResource import org.apache.ivy.plugins.resolver._ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResource } @@ -23,6 +22,8 @@ import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } import sbt.util.Logger import sbt.librarymanagement._ +import scala.util.control.NonFatal + private[sbt] case class SbtChainResolver( name: String, resolvers: Seq[DependencyResolver], @@ -71,188 +72,230 @@ private[sbt] case class SbtChainResolver( // // Ideally this could just skip the lookup, but unfortunately several artifacts in practice do not follow the // correct behavior for packaging="pom" and so it is only skipped for source/javadoc classifiers. - override def locate(artifact: IArtifact) = + override def locate(artifact: IArtifact): ArtifactOrigin = if (IvySbt.hasImplicitClassifier(artifact)) null else super.locate(artifact) - override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { + override def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = { if (data.getOptions.getLog != LogOptions.LOG_QUIET) Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") - val gd = doGetDependency(dd, data) + val gd = CustomSbtResolution.getDependency(dd, data) val mod = IvySbt.resetArtifactResolver(gd) mod } - // Modified implementation of ChainResolver#getDependency. - // When the dependency is changing, it will check all resolvers on the chain - // regardless of what the "latest strategy" is set, and look for the published date - // or the module descriptor to sort them. - // This implementation also skips resolution if "return first" is set to true, - // and if a previously resolved or cached revision has been found. - def doGetDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { - // useLatest - Means we should always download the JARs from the internet, no matter what. - // This will only be true *IF* the depenendency is dynamic/changing *and* latestSnapshots is true. - // If you find multiple candidates, - // - If `isReturnFirst` is true, you return the first value found - // - If not, we will ATTEMPT to look at the publish date, which is not correctly discovered for Maven modules and - // leads to undefined behavior. - val useLatest = (dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId)) && updateOptions.latestSnapshots - if (useLatest) { - Message.verbose(s"$getName is changing. Checking all resolvers on the chain") - } - val data = new ResolveData(data0, doValidate(data0)) - // Returns the value if we've already been resolved from some other branch of the resolution tree. - val resolved = Option(data.getCurrentResolvedModuleRevision) - // If we don't have any previously resolved date, we try to pull the value from the cache. - val resolvedOrCached = - resolved orElse { - Message.verbose(getName + ": Checking cache for: " + dd) - Option(findModuleInCache(dd, data, true)) map { mr => - Message.verbose(getName + ": module revision found in cache: " + mr.getId) - forcedRevision(mr) + + /** Implements the custom sbt chain resolution with support for snapshots and caching. */ + private object CustomSbtResolution { + def getCached(dd: DependencyDescriptor, + data: ResolveData, + resolved0: Option[ResolvedModuleRevision]): Option[ResolvedModuleRevision] = { + resolved0.orElse { + val resolverName = getName + Message.verbose(s"$resolverName: Checking cache for: $dd") + Option(findModuleInCache(dd, data, true)).map { moduleRev => + Message.verbose(s"$resolverName: module revision found in cache: ${moduleRev.getId}") + forcedRevision(moduleRev) } } - - // Default value for resolution. We use this while we loop... - // If useLatest is true, we want to try to download from the internet so we DO NOT start with a valid value. - var temp: Option[ResolvedModuleRevision] = - if (useLatest) None - else resolvedOrCached - // Cast resolvers to something useful. TODO - we dropping anything here? - val resolvers = getResolvers.toArray.toVector collect { case x: DependencyResolver => x } - val interProjResolver = resolvers find { x => - x.getName == ProjectResolver.InterProject } - // Here we do an attempt to resolve the artifact from each of the resolvers in the chain. - // - If we have a return value already, AND isReturnFirst is true AND useLatest is false, we DO NOT resolve anything - // - If we do not, try to resolve. - // RETURNS: Left -> Error - // Right -> Some(resolved module) // Found in this resolver, can use this result. - // Right -> None // Do not use this resolver - lazy val results = resolvers map { x => - // if the revision is cached and isReturnFirst is set, don't bother hitting any resolvers, just return None for this guy. - if (isReturnFirst && temp.isDefined && !useLatest) Right(None) - else { - // We actually do resolution. - val resolver = x - val oldLatest: Option[LatestStrategy] = - setLatestIfRequired(resolver, Option(getLatestStrategy)) - try { - val previouslyResolved = temp - // if the module qualifies as changing, then resolve all resolvers - if (useLatest) data.setCurrentResolvedModuleRevision(null) - else data.setCurrentResolvedModuleRevision(temp.orNull) - temp = Option(resolver.getDependency(dd, data)) - Right( - if (temp eq previouslyResolved) None - else if (useLatest) temp map { x => - (reparseModuleDescriptor(dd, data, resolver, x), resolver) - } else - temp map { x => - (forcedRevision(x), resolver) - } - ) - } catch { - case ex: Exception => - Message.verbose( - "problem occurred while resolving " + dd + " with " + resolver - + ": " + IvyStringUtils.getStackTrace(ex) - ) - Left(ex) - } finally { - oldLatest map { _ => - doSetLatestStrategy(resolver, oldLatest) + /* Copy pasted from `IvyStringUtils` to handle `Throwable` */ + private def getStackTrace(e: Throwable): String = { + if (e == null) return "" + val baos = new ByteArrayOutputStream() + val printWriter = new PrintWriter(baos) + e.printStackTrace(printWriter) + printWriter.flush() + val stackTrace = new String(baos.toByteArray) + printWriter.close() + stackTrace + } + + /** If None, module was not found. Otherwise, hit. */ + type TriedResolution = Option[(ResolvedModuleRevision, DependencyResolver)] + + /** Attempts to resolve the artifact from each of the resolvers in the chain. + * + * Contract: + * 1. It doesn't resolve anything when there is a resolved module, `isReturnFirst` is + * enabled and `useLatest` is false (meaning that resolution is pure, no SNAPSHOT). + * 2. Otherwise, we try to resolve it. + * + * @param resolved0 The perhaps already resolved module. + * @param useLatest Whether snapshot resolution should be enabled. + * @param data The resolve data to use. + * @param descriptor The dependency descriptor of the in-resolution module. + */ + def getResults( + resolved0: Option[ResolvedModuleRevision], + useLatest: Boolean, + data: ResolveData, + descriptor: DependencyDescriptor + ): Seq[Either[Throwable, TriedResolution]] = { + var currentlyResolved = resolved0 + + def performResolution( + resolver: DependencyResolver): Option[(ResolvedModuleRevision, DependencyResolver)] = { + // Resolve all resolvers when the module is changing + val previouslyResolved = currentlyResolved + if (useLatest) data.setCurrentResolvedModuleRevision(null) + else data.setCurrentResolvedModuleRevision(currentlyResolved.orNull) + currentlyResolved = Option(resolver.getDependency(descriptor, data)) + if (currentlyResolved eq previouslyResolved) None + else if (useLatest) { + currentlyResolved.map(x => + (reparseModuleDescriptor(descriptor, data, resolver, x), resolver)) + } else currentlyResolved.map(x => (forcedRevision(x), resolver)) + } + + def reportError(throwable: Throwable, resolver: DependencyResolver): Unit = { + val trace = getStackTrace(throwable) + Message.verbose(s"problem occurred while resolving $descriptor with $resolver: $trace") + } + + resolvers.map { (resolver: DependencyResolver) => + // Return none when revision is cached and `isReturnFirst` is set + if (isReturnFirst && currentlyResolved.isDefined && !useLatest) Right(None) + else { + // We actually do resolution. + val oldLatest: Option[LatestStrategy] = + setLatestIfRequired(resolver, Option(getLatestStrategy)) + try Right(performResolution(resolver)) + catch { case NonFatal(t) => reportError(t, resolver); Left(t) } finally { + oldLatest.foreach(_ => doSetLatestStrategy(resolver, oldLatest)) + checkInterrupted() } - checkInterrupted() } } } - lazy val errors = results collect { case Left(e) => e } - // If the value is arleady in cache, SORTED will be a Seq(None, None, ...) which means we'll fall over to the prevously cached or resolved version. - val mrOpt: Option[ResolvedModuleRevision] = { - val interProj: Option[ResolvedModuleRevision] = - if (updateOptions.interProjectFirst) interProjResolver flatMap { x => - Option(x.getDependency(dd, data)) - } else None - def foundRevisions: Vector[(ResolvedModuleRevision, DependencyResolver)] = results collect { - case Right(Some(x)) => x - } - def sorted = - if (useLatest)(foundRevisions - .sortBy { - case (rmr, resolver) => - Message.warn( - s"Sorting results from $rmr, using ${rmr.getPublicationDate} and ${rmr.getDescriptor.getPublicationDate}" - ) - // Just issue warning about issues with publication date, and fake one on it for now. - Option(rmr.getPublicationDate) orElse Option(rmr.getDescriptor.getPublicationDate) match { - case None => - (resolver.findIvyFileRef(dd, data), rmr.getDescriptor) match { - case (null, _) => - // In this instance, the dependency is specified by a direct URL or some other sort of "non-ivy" file - if (dd.isChanging) - Message.warn( - s"Resolving a changing dependency (${rmr.getId}) with no ivy/pom file!, resolution order is undefined!" - ) - 0L - case (ivf, dmd: DefaultModuleDescriptor) => - val lmd = new java.util.Date(ivf.getLastModified) - Message.debug( - s"Getting no publication date from resolver: ${resolver} for ${rmr.getId}, setting to: ${lmd}" - ) - dmd.setPublicationDate(lmd) - ivf.getLastModified - case _ => - Message.warn( - s"Getting null publication date from resolver: ${resolver} for ${rmr.getId}, resolution order is undefined!" - ) - 0L - } - case Some(date) => // All other cases ok - date.getTime + private final val prefix = "Undefined resolution order" + def resolveLatest(foundRevisions: Seq[(ResolvedModuleRevision, DependencyResolver)], + descriptor: DependencyDescriptor, + data: ResolveData): Option[ResolvedModuleRevision] = { + + val sortedRevisions = foundRevisions.sortBy { + case (rmr, resolver) => + val publicationDate = rmr.getPublicationDate + val descriptorDate = rmr.getDescriptor.getPublicationDate + Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") + // Just issue warning about issues with publication date, and fake one on it for now + val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) + chosenPublicationDate match { + case Some(date) => date.getTime + case None => + val id = rmr.getId + val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) + resolvedResource match { + case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => + val resolvedPublicationDate = new java.util.Date(res.getLastModified) + Message.debug(s"No publication date from resolver $resolver for $id.") + Message.debug(s"Setting publication date to: $resolvedPublicationDate.") + dmd.setPublicationDate(resolvedPublicationDate) + res.getLastModified + case (ivf, dmd) => + // The dependency is specified by a direct URL or some sort of non-ivy file + if (ivf == null && descriptor.isChanging) + Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") + if (dmd == null) + Message.warn(s"$prefix: no publication date from resolver $resolver for $id") + 0L } - }) - .reverse - .headOption map { - case (rmr, resolver) => - Message.warn(s"Choosing $resolver for ${rmr.getId}") - // Now that we know the real latest revision, let's force Ivy to use it - val artifactOpt = findFirstArtifactRef(rmr.getDescriptor, dd, data, resolver) - artifactOpt match { - case Some(artifactRef) => - val systemMd = toSystem(rmr.getDescriptor) - getRepositoryCacheManager.cacheModuleDescriptor( - resolver, - artifactRef, - toSystem(dd), - systemMd.getAllArtifacts.head, - None.orNull, - getCacheOptions(data) - ) - case None => // do nothing. There are modules without artifacts - } - rmr - } else - foundRevisions.reverse.headOption map { _._1 } // we have to reverse because resolvers are hit in reverse order. + } + } - interProj orElse sorted orElse resolvedOrCached - } - mrOpt match { - case None if errors.size == 1 => - errors.head match { - case e: RuntimeException => throw e - case e: ParseException => throw e - case e: Throwable => throw new RuntimeException(e.toString, e) + val firstHit = sortedRevisions.reverse.headOption + firstHit.map { hit => + val (resolvedModule, resolver) = hit + Message.warn(s"Choosing $resolver for ${resolvedModule.getId}") + // Now that we know the real latest revision, let's force Ivy to use it + val resolvedDescriptor = resolvedModule.getDescriptor + val artifactOpt = findFirstArtifactRef(resolvedDescriptor, descriptor, data, resolver) + // If `None` do nothing -- modules without artifacts. Otherwise cache. + artifactOpt.foreach { artifactRef => + val dep = toSystem(descriptor) + val first = toSystem(resolvedDescriptor).getAllArtifacts.head + val options = getCacheOptions(data) + val cacheManager = getRepositoryCacheManager + cacheManager.cacheModuleDescriptor(resolver, artifactRef, dep, first, null, options) } - case None if errors.size > 1 => - val err = - (errors.toList map { IvyStringUtils.getErrorMessage }).mkString("\n\t", "\n\t", "\n") - throw new RuntimeException(s"several problems occurred while resolving $dd:$err") - case _ => - if (resolved == mrOpt) resolved.orNull - else (mrOpt map { resolvedRevision }).orNull + resolvedModule + } + } + + def resolveByAllMeans( + cachedModule: Option[ResolvedModuleRevision], + useLatest: Boolean, + interResolver: Option[DependencyResolver], + resolveModules: () => Seq[Either[Throwable, TriedResolution]], + dd: DependencyDescriptor, + data: ResolveData + ): Option[ResolvedModuleRevision] = { + val internallyResolved: Option[ResolvedModuleRevision] = { + if (!updateOptions.interProjectFirst) None + else interResolver.flatMap(resolver => Option(resolver.getDependency(dd, data))) + } + val internalOrExternal = internallyResolved.orElse { + val foundRevisions: Seq[(ResolvedModuleRevision, DependencyResolver)] = + resolveModules().collect { case Right(Some(x)) => x } + if (useLatest) resolveLatest(foundRevisions, dd, data) + else foundRevisions.reverse.headOption.map(_._1) // Resolvers are hit in reverse order + } + internalOrExternal.orElse(cachedModule) + } + + // The ivy implementation guarantees that all resolvers implement `DependencyResolver` + def getDependencyResolvers: Vector[DependencyResolver] = + getResolvers.toArray.collect { case r: DependencyResolver => r }.toVector + + def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] = + resolvers.find(_.getName == ProjectResolver.InterProject) + + /** Gets the dependency for a given descriptor with the pertinent resolve data. + * + * This is a custom sbt chain operation that produces better error output and deals with + * cases that the conventional ivy resolver does not. It accumulates the resolution of + * several resolvers and returns the module which fits the provided resolution strategy. + */ + def getDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { + val isDynamic = dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId) + val useLatest = isDynamic && updateOptions.latestSnapshots + if (useLatest) Message.verbose(s"$getName is changing. Checking all resolvers on the chain.") + + /* Get the resolved module descriptor from: + * 1. An already resolved branch of the resolution tree. + * 2. The value from the cache. */ + val data = new ResolveData(data0, doValidate(data0)) + val resolved0 = Option(data.getCurrentResolvedModuleRevision) + val resolvedOrCached = getCached(dd, data0, resolved0) + + val cached: Option[ResolvedModuleRevision] = if (useLatest) None else resolvedOrCached + val resolvers = getDependencyResolvers + val interResolver = findInterProjectResolver(resolvers) + // TODO: Please, change `Option` return types so that this goes away + lazy val results = getResults(cached, useLatest, data, dd) + lazy val errors = results.collect { case Left(t) => t } + val runResolution = () => results + val resolved = resolveByAllMeans(cached, useLatest, interResolver, runResolution, dd, data) + + resolved match { + case None if errors.size == 1 => + errors.head match { + case e: RuntimeException => throw e + case e: ParseException => throw e + case e: Throwable => throw new RuntimeException(e.toString, e) + } + case None if errors.size > 1 => + val traces = errors.toList.map(e => IvyStringUtils.getErrorMessage(e)) + val msg = s"Resolution failed several times for $dd:" + throw new RuntimeException(s"$msg: ${traces.mkString("\n\t", "\n\t", "\n")}") + case _ => + // Can be either `None` with empty error or `Some` + if (resolved0 == resolved) resolved0.orNull + else resolved.map(resolvedRevision).orNull + } } } + // Ivy seem to not want to use the module descriptor found at the latest resolver private[this] def reparseModuleDescriptor( dd: DependencyDescriptor, From 7391290d8a518b563eabf81448318c9945a946f2 Mon Sep 17 00:00:00 2001 From: jvican Date: Wed, 10 May 2017 20:34:41 +0200 Subject: [PATCH 0603/1030] Add comments to `SbtChainResolver` implementation --- .../internal/librarymanagement/ivyint/SbtChainResolver.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index da7e9f13d..cb7f0cbfa 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -255,6 +255,11 @@ private[sbt] case class SbtChainResolver( * This is a custom sbt chain operation that produces better error output and deals with * cases that the conventional ivy resolver does not. It accumulates the resolution of * several resolvers and returns the module which fits the provided resolution strategy. + * + * These are the differences with regard to the default ivy [[ChainResolver]]: + * 1. It skips resolution if "return first" is set to true. + * 2. It skips resolution if a previously resolved or cached resolution is found. + * 3. It always checks all the resolvers and compares timestamps for changing dependencies. */ def getDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { val isDynamic = dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId) From 5ff32f2a996422b2ec853f96996809598b435885 Mon Sep 17 00:00:00 2001 From: jvican Date: Mon, 8 May 2017 20:03:30 +0200 Subject: [PATCH 0604/1030] Add a frozen mode to update configuration The frozen mode is used by the dependency lock file. It makes sure that the resolution is always intransitive and that ivy does not check for changed dependencies and stores that information in the resolved ivy files. Following the ivy documentation, the last change may bring a slight performance improvement: http://ant.apache.org/ivy/history/latest-milestone/use/resolve.html --- .../main/contraband/librarymanagement.json | 3 +- .../librarymanagement/IvyActions.scala | 8 +++ .../DefaultLibraryManagement.scala | 1 + .../src/test/scala/BaseIvySpecification.scala | 3 +- .../src/test/scala/FrozenModeSpec.scala | 55 +++++++++++++++++++ 5 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 librarymanagement/src/test/scala/FrozenModeSpec.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 810ecc1ac..d28da3b69 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -635,7 +635,8 @@ { "name": "missingOk", "type": "boolean" }, { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }, - { "name": "offline", "type": "boolean" } + { "name": "offline", "type": "boolean" }, + { "name": "frozen", "type": "boolean" } ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 4d8465a10..638aa4770 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -469,6 +469,10 @@ object IvyActions { resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(logging)) + if (updateConfiguration.frozen) { + resolveOptions.setTransitive(false) + resolveOptions.setCheckIfChanged(false) + } ResolutionCache.cleanModule( moduleDescriptor.getModuleRevisionId, resolveId, @@ -522,6 +526,10 @@ object IvyActions { resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) resolveOptions.setUseCacheOnly(updateConfiguration.offline) resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging)) + if (updateConfiguration.frozen) { + resolveOptions.setTransitive(false) + resolveOptions.setCheckIfChanged(false) + } val acceptError = updateConfiguration.missingOk resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala index 3c5d38167..49af3cb71 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala @@ -69,6 +69,7 @@ class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) true, UpdateLogging.DownloadOnly, artifactFilter, + false, false ) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 20041ab04..d87baa862 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -74,7 +74,8 @@ trait BaseIvySpecification extends UnitSpec { false, UpdateLogging.Full, ArtifactTypeFilter.forbid(Set("src", "doc")), - offline) + offline, + false) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { diff --git a/librarymanagement/src/test/scala/FrozenModeSpec.scala b/librarymanagement/src/test/scala/FrozenModeSpec.scala new file mode 100644 index 000000000..e84abfe99 --- /dev/null +++ b/librarymanagement/src/test/scala/FrozenModeSpec.scala @@ -0,0 +1,55 @@ +package sbt.librarymanagement + +import sbt.internal.librarymanagement._ +import sbt.internal.librarymanagement.impl.DependencyBuilders + +class FrozenModeSpec extends BaseIvySpecification with DependencyBuilders { + private final val targetDir = Some(currentDependency) + private final val onlineConf = makeUpdateConfiguration(false) + private final val frozenConf = makeUpdateConfiguration(false).withFrozen(true) + private final val noClock = LogicalClock.unknown + private final val warningConf = UnresolvedWarningConfiguration() + private final val normalOptions = UpdateOptions() + + final val stoml = Vector("me.vican.jorge" % "stoml_2.12" % "0.4" % "compile") + + /* https://repo1.maven.org/maven2/me/vican/jorge/stoml_2.12/0.4/stoml_2.12-0.4.jar + * https://repo1.maven.org/maven2/org/scala-lang/scala-library/2.12.0/scala-library-2.12.0.jar + * https://repo1.maven.org/maven2/com/lihaoyi/fastparse_2.12/0.4.2/fastparse_2.12-0.4.2.jar + * https://repo1.maven.org/maven2/com/lihaoyi/fastparse-utils_2.12/0.4.2/fastparse-utils_2.12-0.4.2.jar + * https://repo1.maven.org/maven2/com/lihaoyi/sourcecode_2.12/0.1.3/sourcecode_2.12-0.1.3.jar */ + final val explicitStoml = Vector( + "me.vican.jorge" % "stoml_2.12" % "0.4" % "compile", + "org.scala-lang" % "scala-library" % "2.12.0" % "compile", + "com.lihaoyi" % "fastparse_2.12" % "0.4.2" % "compile", + "com.lihaoyi" % "fastparse-utils_2.12" % "0.4.2" % "compile", + "com.lihaoyi" % "sourcecode_2.12" % "0.1.3" % "compile" + ) + + it should "fail when artifacts are missing in the cache" in { + cleanIvyCache() + def update(module: IvySbt#Module, conf: UpdateConfiguration) = + IvyActions.updateEither(module, conf, warningConf, noClock, targetDir, log) + + val toResolve = module(defaultModuleId, stoml, None, normalOptions) + val onlineResolution = update(toResolve, onlineConf) + assert(onlineResolution.isRight) + val numberResolved = onlineResolution.right.get.allModules.size + + cleanIvyCache() + val singleFrozenResolution = update(toResolve, frozenConf) + assert(singleFrozenResolution.isRight) + assert( + singleFrozenResolution.right.get.allModules.size == 1, + s"The number of explicit modules in frozen mode should 1" + ) + + cleanIvyCache() + // This relies on the fact that stoml has 5 transitive dependencies + val toExplicitResolve = module(defaultModuleId, explicitStoml, None, normalOptions) + val frozenResolution = update(toExplicitResolve, frozenConf) + assert(frozenResolution.isRight) + assert(frozenResolution.right.get.allModules.size == numberResolved, + s"The number of explicit modules in frozen mode should be equal than $numberResolved") + } +} From b1e36e50c8bbe9ddecb58944d813803b38004ed5 Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 11 May 2017 18:10:01 +0200 Subject: [PATCH 0605/1030] Add review comments and improve docs --- .../librarymanagement/ivyint/SbtChainResolver.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index cb7f0cbfa..f07930105 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -259,7 +259,12 @@ private[sbt] case class SbtChainResolver( * These are the differences with regard to the default ivy [[ChainResolver]]: * 1. It skips resolution if "return first" is set to true. * 2. It skips resolution if a previously resolved or cached resolution is found. - * 3. It always checks all the resolvers and compares timestamps for changing dependencies. + * 3. It always checks all the resolvers and compares timestamps for changing dependencies + * if and only if `latestSnapshots` is enabled in the update options, regardless of what + * the latest strategies are (http://ant.apache.org/ivy/history/2.3.0/settings/latest-strategies.html). + * See https://github.com/sbt/sbt/pull/1520 for more information on this topic. + * + * Note the tradeoff here in SNAPSHOTs: correctness vs slowness. */ def getDependency(dd: DependencyDescriptor, data0: ResolveData): ResolvedModuleRevision = { val isDynamic = dd.isChanging || IvySbt.isChanging(dd.getDependencyRevisionId) From 92cc5339eb28d9e2f8bbe6b1b9e16fbbc5ab6c12 Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 11 May 2017 17:32:19 +0200 Subject: [PATCH 0606/1030] Fix sbt/sbt#2650: Degrade log level and clarify To ensure that SNAPSHOTs are always the latest, we go through all the resolved modules and check their timestamps. Good. However, if in the process of reparsing/redownloading the module descriptor we fail (or it's not found in that resolver at all), then we cannot refresh the resolved module that could have been internalized or heavily cached in memory by ivy. We do this for correctness. This patch does two things: 1. Adds more comments. 2. Warns only when there are parsing errors in ivy files. 3. Adds debug info in the rest of the cases. This removes the pain of seeing `Unable to parse` that could be caused by other reasons that are not related to parsing at all and which would not affect the algorithm at hand. For instance, if we get a URLResource, that's totally fine -- there is no way we could parse the ivy file. Ivy uses URLResources in several cases where the artifact origin URL is specified. --- .../ivyint/SbtChainResolver.scala | 41 ++++++++++++------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index f07930105..2f0789c45 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -306,34 +306,45 @@ private[sbt] case class SbtChainResolver( } } - // Ivy seem to not want to use the module descriptor found at the latest resolver + /* Ivy keeps module descriptors in memory, so we need to make sure that the + * resolved module revision is in fact the one found in the latest resolver. */ private[this] def reparseModuleDescriptor( dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver, - rmr: ResolvedModuleRevision - ): ResolvedModuleRevision = - // TODO - Redownloading/parsing the ivy file is not really the best way to make this correct. - // We should figure out a better alternative, or directly attack the resolvers Ivy uses to - // give them correct behavior around -SNAPSHOT. + previouslyResolved: ResolvedModuleRevision + ): ResolvedModuleRevision = { + // TODO: Figure out better alternative or directly attack the + // resolvers ivy uses to get correct behaviour for SNAPSHOT Option(resolver.findIvyFileRef(dd, data)) flatMap { ivyFile => ivyFile.getResource match { case r: FileResource => + val urlDescriptor = r.getFile.toURI.toURL try { - val parser = rmr.getDescriptor.getParser - val md = parser.parseDescriptor(settings, r.getFile.toURI.toURL, r, false) - Some(new ResolvedModuleRevision(resolver, resolver, md, rmr.getReport, true)) + val parser = previouslyResolved.getDescriptor.getParser + val md = parser.parseDescriptor(settings, urlDescriptor, r, false) + val report = previouslyResolved.getReport + // Note that we always set force for SNAPSHOT resolution... + Some(new ResolvedModuleRevision(resolver, resolver, md, report, true)) } catch { - case _: ParseException => None + case _: ParseException => + Message.warn(s"The descriptor in $urlDescriptor from $resolver could not be parsed.") + Some(previouslyResolved) } - case _ => None + case unhandledResource => + val unhandledClassName = unhandledResource.getClass.getName + val tip = s"Returning previously resolved $previouslyResolved." + Message.debug(s"Latest snapshots option does not handle `$unhandledClassName`. $tip") + Some(previouslyResolved) } } getOrElse { - Message.warn( - s"Unable to reparse ${dd.getDependencyRevisionId} from $resolver, using ${rmr.getPublicationDate}" - ) - rmr + val previousRevision = dd.getDependencyRevisionId + val date = previouslyResolved.getPublicationDate + // Change from warn to debug -- see https://github.com/sbt/sbt/issues/2650. + Message.debug(s"Unable to find new descriptor for $previousRevision at $date in $resolver.") + previouslyResolved } + } /** Ported from BasicResolver#findFirstAirfactRef. */ private[this] def findFirstArtifactRef( From 8bb1676e61b20be874679f5605015c542006c6ab Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 11 May 2017 15:44:32 +0200 Subject: [PATCH 0607/1030] Allow to define concrete resolvers for dependencies Sometimes, for predictability and performance, we may be interested in specifying the concrete resolver that a `ModuleID` should use. This patch achieves this by adding a new field to `UpdateOptions` and then getting this information from the `SbtChainResolver`, that will select the concrete resolver for a given dependency descriptor. Why is this useful? Well, two reasons: * Predictable behaviour. We have the guarantee that an artifact only comes from a concrete resolver. * Resolution speedup. Around 1/3 or 1/2 times faster than normal resolution in a moderate test case scenario. If there is a lot of latency or network connection is poor, speedups will be higher. LOGS: ``` NORMAL RESOLUTION TIME 1790 FASTER RESOLUTION TIME 1054 ``` ``` NORMAL RESOLUTION TIME 2078 FASTER RESOLUTION TIME 1055 ``` Lots of projects can benefit from this option, as well as organizations and companies. This will eventually integrate with the dependency lock file, but can be used independently of it. --- .../sbt/internal/librarymanagement/Ivy.scala | 37 +++++------- .../formats/UpdateOptionsFormat.scala | 21 +++++-- .../ivyint/SbtChainResolver.scala | 57 ++++++++++++++----- .../sbt/librarymanagement/UpdateOptions.scala | 20 +++++-- .../src/test/scala/ModuleResolversTest.scala | 48 ++++++++++++++++ 5 files changed, 139 insertions(+), 44 deletions(-) create mode 100644 librarymanagement/src/test/scala/ModuleResolversTest.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index a3b250b78..e27eb1907 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -349,6 +349,8 @@ private[sbt] object IvySbt { val mainChain = makeChain("Default", "sbt-chain", resolvers) settings.setDefaultResolver(mainChain.getName) } + + // TODO: Expose the changing semantics to the caller so that users can specify a regex private[sbt] def isChanging(dd: DependencyDescriptor): Boolean = dd.isChanging || isChanging(dd.getDependencyRevisionId) private[sbt] def isChanging(module: ModuleID): Boolean = @@ -370,32 +372,23 @@ private[sbt] object IvySbt { updateOptions: UpdateOptions, log: Logger ): DependencyResolver = { - def mapResolvers(rs: Seq[Resolver]) = - rs.map(r => ConvertResolver(r, settings, updateOptions, log)) - val (projectResolvers, rest) = resolvers.partition(_.name == "inter-project") + val ivyResolvers = resolvers.map(r => ConvertResolver(r, settings, updateOptions, log)) + val (projectResolvers, rest) = + ivyResolvers.partition(_.getName == ProjectResolver.InterProject) if (projectResolvers.isEmpty) - new ivyint.SbtChainResolver(name, mapResolvers(rest), settings, updateOptions, log) + ivyint.SbtChainResolver(name, rest, settings, updateOptions, log) else { - // Here we set up a "first repo wins" chain resolver - val delegate = new ivyint.SbtChainResolver( - name + "-delegate", - mapResolvers(rest), - settings, - updateOptions, - log - ) - val prs = mapResolvers(projectResolvers) - // Here we construct a chain resolver which will FORCE looking at the project resolver first. - new ivyint.SbtChainResolver( - name, - prs :+ delegate, - settings, - UpdateOptions().withLatestSnapshots(false), - log - ) - + // Force that we always look at the project resolver first by wrapping the chain resolver + val delegatedName = s"$name-delegate" + val delegate = ivyint.SbtChainResolver(delegatedName, rest, settings, updateOptions, log) + val initialResolvers = projectResolvers :+ delegate + val freshOptions = UpdateOptions() + .withLatestSnapshots(false) + .withModuleResolvers(updateOptions.moduleResolvers) + ivyint.SbtChainResolver(name, initialResolvers, settings, freshOptions, log) } } + def addResolvers(resolvers: Seq[Resolver], settings: IvySettings, log: Logger): Unit = { for (r <- resolvers) { log.debug("\t" + r) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 0770fee85..5074e8a0e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -4,7 +4,18 @@ package formats import sjsonnew._ import sbt.librarymanagement._ -trait UpdateOptionsFormat { self: BasicJsonProtocol => +trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with ResolverFormats => + /* This is necessary to serialize/deserialize `directResolvers`. */ + private implicit val moduleIdJsonKeyFormat: sjsonnew.JsonKeyFormat[ModuleID] = { + new sjsonnew.JsonKeyFormat[ModuleID] { + import sjsonnew.support.scalajson.unsafe._ + val moduleIdFormat: JsonFormat[ModuleID] = implicitly[JsonFormat[ModuleID]] + def write(key: ModuleID): String = + CompactPrinter(Converter.toJsonUnsafe(key)(moduleIdFormat)) + def read(key: String): ModuleID = + Converter.fromJsonUnsafe[ModuleID](Parser.parseUnsafe(key))(moduleIdFormat) + } + } implicit lazy val UpdateOptionsFormat: JsonFormat[UpdateOptions] = project( @@ -14,16 +25,18 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol => uo.interProjectFirst, uo.latestSnapshots, uo.consolidatedResolution, - uo.cachedResolution + uo.cachedResolution, + uo.moduleResolvers ), - (xs: (String, Boolean, Boolean, Boolean, Boolean)) => + (xs: (String, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => new UpdateOptions( levels(xs._1), xs._2, xs._3, xs._4, xs._5, - ConvertResolver.defaultConvert + ConvertResolver.defaultConvert, + xs._6 ) ) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index f07930105..76a075b39 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -52,13 +52,17 @@ private[sbt] case class SbtChainResolver( // TODO - We need to special case the project resolver so it always "wins" when resolving with inter-project dependencies. - // Initialize ourselves. - setName(name) - setReturnFirst(true) - setCheckmodified(false) - // Here we append all the resolvers we were passed *AND* look for - // a project resolver, which we will special-case. - resolvers.foreach(add) + def initializeChainResolver(): Unit = { + // Initialize ourselves. + setName(name) + setReturnFirst(true) + setCheckmodified(false) + + /* Append all the resolvers to the extended chain resolvers since we get its value later on */ + resolvers.foreach(add) + } + + initializeChainResolver() // Technically, this should be applied to module configurations. // That would require custom subclasses of all resolver types in ConvertResolver (a delegation approach does not work). @@ -129,7 +133,8 @@ private[sbt] case class SbtChainResolver( resolved0: Option[ResolvedModuleRevision], useLatest: Boolean, data: ResolveData, - descriptor: DependencyDescriptor + descriptor: DependencyDescriptor, + resolvers: Seq[DependencyResolver] ): Seq[Either[Throwable, TriedResolution]] = { var currentlyResolved = resolved0 @@ -243,9 +248,35 @@ private[sbt] case class SbtChainResolver( internalOrExternal.orElse(cachedModule) } - // The ivy implementation guarantees that all resolvers implement `DependencyResolver` - def getDependencyResolvers: Vector[DependencyResolver] = - getResolvers.toArray.collect { case r: DependencyResolver => r }.toVector + /** Cleans unnecessary module id information not provided by [[IvyRetrieve.toModuleID()]]. */ + private final val moduleResolvers = updateOptions.moduleResolvers.map { + case (key, value) => + val cleanKey = ModuleID(key.organization, key.name, key.revision) + .withExtraAttributes(key.extraAttributes) + .withBranchName(key.branchName) + cleanKey -> value + } + + /** + * Gets the list of resolvers to use for resolving a given descriptor. + * + * NOTE: The ivy implementation guarantees that all resolvers implement dependency resolver. + * @param descriptor The descriptor to be resolved. + */ + def getDependencyResolvers(descriptor: DependencyDescriptor): Vector[DependencyResolver] = { + val moduleRevisionId = descriptor.getDependencyRevisionId + val moduleID = IvyRetrieve.toModuleID(moduleRevisionId) + val resolverForModule = moduleResolvers.get(moduleID) + val ivyResolvers = getResolvers.toArray // Get resolvers from chain resolver directly + val allResolvers = ivyResolvers.collect { case r: DependencyResolver => r }.toVector + // Double check that dependency resolver will always be the super trait of a resolver + assert(ivyResolvers.size == allResolvers.size, "ALERT: Some ivy resolvers were filtered.") + val mappedResolver = resolverForModule.flatMap(r => allResolvers.find(_.getName == r.name)) + mappedResolver match { + case Some(uniqueResolver) => Vector(uniqueResolver) + case None => allResolvers + } + } def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] = resolvers.find(_.getName == ProjectResolver.InterProject) @@ -279,10 +310,10 @@ private[sbt] case class SbtChainResolver( val resolvedOrCached = getCached(dd, data0, resolved0) val cached: Option[ResolvedModuleRevision] = if (useLatest) None else resolvedOrCached - val resolvers = getDependencyResolvers + val resolvers = getDependencyResolvers(dd) val interResolver = findInterProjectResolver(resolvers) // TODO: Please, change `Option` return types so that this goes away - lazy val results = getResults(cached, useLatest, data, dd) + lazy val results = getResults(cached, useLatest, data, dd, resolvers) lazy val errors = results.collect { case Left(t) => t } val runResolution = () => results val resolved = resolveByAllMeans(cached, useLatest, interResolver, runResolution, dd, data) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 0ebcee170..4c3810055 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -23,7 +23,9 @@ final class UpdateOptions private[sbt] ( // If set to true, use cached resolution. val cachedResolution: Boolean, // Extension point for an alternative resolver converter. - val resolverConverter: UpdateOptions.ResolverConverter + val resolverConverter: UpdateOptions.ResolverConverter, + // Map the unique resolver to be checked for the module ID + val moduleResolvers: Map[ModuleID, Resolver] ) { def withCircularDependencyLevel( circularDependencyLevel: CircularDependencyLevel @@ -49,13 +51,17 @@ final class UpdateOptions private[sbt] ( def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = copy(resolverConverter = resolverConverter) + def withModuleResolvers(moduleResolvers: Map[ModuleID, Resolver]): UpdateOptions = + copy(moduleResolvers = moduleResolvers) + private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, - resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter + resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter, + moduleResolvers: Map[ModuleID, Resolver] = this.moduleResolvers ): UpdateOptions = new UpdateOptions( circularDependencyLevel, @@ -63,7 +69,8 @@ final class UpdateOptions private[sbt] ( latestSnapshots, consolidatedResolution, cachedResolution, - resolverConverter + resolverConverter, + moduleResolvers ) override def equals(o: Any): Boolean = o match { @@ -72,7 +79,8 @@ final class UpdateOptions private[sbt] ( this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && - this.resolverConverter == o.resolverConverter + this.resolverConverter == o.resolverConverter && + this.moduleResolvers == o.moduleResolvers case _ => false } @@ -83,6 +91,7 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## hash = hash * 31 + this.resolverConverter.## + hash = hash * 31 + this.moduleResolvers.## hash } } @@ -97,6 +106,7 @@ object UpdateOptions { latestSnapshots = true, consolidatedResolution = false, cachedResolution = false, - resolverConverter = PartialFunction.empty + resolverConverter = PartialFunction.empty, + moduleResolvers = Map.empty ) } diff --git a/librarymanagement/src/test/scala/ModuleResolversTest.scala b/librarymanagement/src/test/scala/ModuleResolversTest.scala new file mode 100644 index 000000000..dd35c89ea --- /dev/null +++ b/librarymanagement/src/test/scala/ModuleResolversTest.scala @@ -0,0 +1,48 @@ +package sbt.librarymanagement + +import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.internal.librarymanagement.impl.DependencyBuilders + +class ModuleResolversTest extends BaseIvySpecification with DependencyBuilders { + override final val resolvers = Vector( + DefaultMavenRepository, + JavaNet2Repository, + JCenterRepository, + Resolver.sbtPluginRepo("releases") + ) + + private final val stubModule = "com.example" % "foo" % "0.1.0" % "compile" + val pluginAttributes = Map("sbtVersion" -> "0.13", "scalaVersion" -> "2.10") + private final val dependencies = Vector( + ("me.lessis" % "bintray-sbt" % "0.3.0" % "compile").withExtraAttributes(pluginAttributes), + "com.jfrog.bintray.client" % "bintray-client-java-api" % "0.9.2" % "compile" + ).map(_.withIsTransitive(false)) + + "The direct resolvers in update options" should "skip the rest of resolvers" in { + cleanIvyCache() + val updateOptions = UpdateOptions() + val ivyModule = module(stubModule, dependencies, None, updateOptions) + val normalResolution = ivyUpdateEither(ivyModule) + assert(normalResolution.isRight) + val normalResolutionTime = normalResolution.right.get.stats.resolveTime + + cleanIvyCache() + val moduleResolvers = Map( + dependencies.head -> resolvers.last, + dependencies.tail.head -> resolvers.init.last + ) + val customUpdateOptions = updateOptions.withModuleResolvers(moduleResolvers) + val ivyModule2 = module(stubModule, dependencies, None, customUpdateOptions) + val fasterResolution = ivyUpdateEither(ivyModule2) + assert(fasterResolution.isRight) + val fasterResolutionTime = fasterResolution.right.get.stats.resolveTime + + // THis is left on purpose so that in spurious error we see the times + println(s"NORMAL RESOLUTION TIME $normalResolutionTime") + println(s"FASTER RESOLUTION TIME $fasterResolutionTime") + + // Check that faster resolution is at least 1/5 faster than normal resolution + // This is a conservative check just to make sure we don't regress -- speedup is higher + assert(fasterResolutionTime <= (normalResolutionTime * 0.80)) + } +} From dd4b33105b8eab4bdb5c3719b24bd1b47a4f732a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 15 May 2017 16:34:38 -0400 Subject: [PATCH 0608/1030] add Gigahorse --- build.sbt | 1 + .../src/main/scala/sbt/librarymanagement/Http.scala | 7 +++++++ project/Dependencies.scala | 1 + 3 files changed, 9 insertions(+) create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala diff --git a/build.sbt b/build.sbt index 2e07ce2ce..c5ad63207 100644 --- a/build.sbt +++ b/build.sbt @@ -60,6 +60,7 @@ lazy val lm = (project in file("librarymanagement")) jsch, scalaReflect.value, launcherInterface, + gigahorseOkhttp, sjsonnewScalaJson % Optional), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala new file mode 100644 index 000000000..9870d9b0f --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala @@ -0,0 +1,7 @@ +package sbt.librarymanagement + +import gigahorse._, support.okhttp.Gigahorse + +object Http { + lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ef67b2344..2ad1ff99a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -57,6 +57,7 @@ object Dependencies { val scalaXml = scala211Module("scala-xml", "1.0.5") val sjsonnewVersion = "0.7.0" val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion + val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" private def scala211Module(name: String, moduleVersion: String) = Def.setting { From fd7cec0148e5a62a8867c9dcdd727cc7a1444247 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 26 May 2017 04:13:55 -0400 Subject: [PATCH 0609/1030] use okhttp to download the artifacts This adds a custom URLHandler that internally uses Square OkHttp. Fixes sbt/librarymanagement#95 --- build.sbt | 1 + .../sbt/internal/librarymanagement/Ivy.scala | 19 +- .../formats/UpdateOptionsFormat.scala | 2 +- .../ivyint/GigahorseUrlHandler.scala | 171 ++++++++++++++++++ .../scala/sbt/librarymanagement/Http.scala | 6 + .../sbt/librarymanagement/UpdateOptions.scala | 26 ++- project/Dependencies.scala | 1 + 7 files changed, 206 insertions(+), 20 deletions(-) create mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala diff --git a/build.sbt b/build.sbt index c5ad63207..97cf4a78e 100644 --- a/build.sbt +++ b/build.sbt @@ -61,6 +61,7 @@ lazy val lm = (project in file("librarymanagement")) scalaReflect.value, launcherInterface, gigahorseOkhttp, + okhttpUrlconnection, sjsonnewScalaJson % Optional), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e27eb1907..a6acdbafc 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -33,7 +33,7 @@ import org.apache.ivy.plugins.matcher.PatternMatcher import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.util.extendable.ExtendableItem - +import org.apache.ivy.util.url._ import scala.xml.NodeSeq import scala.collection.mutable import sbt.util.Logger @@ -43,7 +43,8 @@ import ivyint.{ CachedResolutionResolveCache, CachedResolutionResolveEngine, ParallelResolveEngine, - SbtDefaultDependencyDescriptor + SbtDefaultDependencyDescriptor, + GigahorseUrlHandler } final class IvySbt(val configuration: IvyConfiguration) { self => @@ -72,9 +73,19 @@ final class IvySbt(val configuration: IvyConfiguration) { self => case None => action() } } - private lazy val settings: IvySettings = { - val is = new IvySettings + private lazy val basicUrlHandler: URLHandler = new BasicURLHandler + private lazy val gigahorseUrlHandler: URLHandler = { + val dispatcher = new URLHandlerDispatcher + val handler = new GigahorseUrlHandler + dispatcher.setDownloader("http", handler) + dispatcher.setDownloader("https", handler) + dispatcher + } + private lazy val settings: IvySettings = { + if (configuration.updateOptions.gigahorse) URLHandlerRegistry.setDefault(gigahorseUrlHandler) + else URLHandlerRegistry.setDefault(basicUrlHandler) + val is = new IvySettings is.setBaseDir(baseDirectory) is.setCircularDependencyStrategy( configuration.updateOptions.circularDependencyLevel.ivyStrategy diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 5074e8a0e..ae080e80e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -24,8 +24,8 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re uo.circularDependencyLevel.name, uo.interProjectFirst, uo.latestSnapshots, - uo.consolidatedResolution, uo.cachedResolution, + uo.gigahorse, uo.moduleResolvers ), (xs: (String, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala new file mode 100644 index 000000000..6603919b5 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -0,0 +1,171 @@ +package sbt.internal.librarymanagement +package ivyint + +import java.net.{ URL, UnknownHostException, HttpURLConnection } +import java.io.{ File, IOException, InputStream, ByteArrayOutputStream, ByteArrayInputStream } +import org.apache.ivy.util.{ CopyProgressListener, Message, FileUtil } +import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler } +import org.apache.ivy.util.url.URLHandler._ +import sbt.librarymanagement.Http +import sbt.io.{ IO, Using } + +// Copied from Ivy's BasicURLHandler. +class GigahorseUrlHandler extends AbstractURLHandler { + private val BUFFER_SIZE = 64 * 1024 + + /** + * Returns the URLInfo of the given url or a #UNAVAILABLE instance, + * if the url is not reachable. + */ + def getURLInfo(url: URL): URLInfo = getURLInfo(url, 0) + + /** + * Returns the URLInfo of the given url or a #UNAVAILABLE instance, + * if the url is not reachable. + */ + def getURLInfo(url0: URL, timeout: Int): URLInfo = { + val url = normalizeToURL(url0) + val con = Http.open(url) + val infoOption = try { + con match { + case httpCon: HttpURLConnection => + if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) { + httpCon.setRequestMethod("HEAD") + } + if (checkStatusCode(url, httpCon)) { + val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) + Some( + new SbtUrlInfo(true, + httpCon.getContentLength.toLong, + con.getLastModified(), + bodyCharset)) + } else None + + case _ => + val contentLength = con.getContentLength + if (contentLength <= 0) None + else { + // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? + val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) + Some(new SbtUrlInfo(true, contentLength.toLong, con.getLastModified(), bodyCharset)) + } + } + } catch { + case e: UnknownHostException => + Message.warn("Host " + e.getMessage() + " not found. url=" + url) + Message.info( + "You probably access the destination server through " + + "a proxy server that is not well configured.") + None + case e: IOException => + Message.error("Server access Error: " + e.getMessage() + " url=" + url) + None + } + infoOption.getOrElse(UNAVAILABLE) + } + + def openStream(url0: URL): InputStream = { + val url = normalizeToURL(url0) + val conn = Http.open(url) + conn.setRequestProperty("Accept-Encoding", "gzip,deflate") + conn match { + case httpCon: HttpURLConnection => + if (!checkStatusCode(url, httpCon)) { + throw new IOException( + "The HTTP response code for " + url + " did not indicate a success." + + " See log for more detail.") + } + case _ => + } + val inStream = getDecodingInputStream(conn.getContentEncoding(), conn.getInputStream()) + val outStream = new ByteArrayOutputStream() + val buffer = new Array[Byte](BUFFER_SIZE) + var len = 0 + while ({ + len = inStream.read(buffer) + len > 0 + }) { + outStream.write(buffer, 0, len) + } + new ByteArrayInputStream(outStream.toByteArray()) + } + + def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { + val src = normalizeToURL(src0) + val srcConn = Http.open(src) + srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate") + srcConn match { + case httpCon: HttpURLConnection => + if (!checkStatusCode(src, httpCon)) { + throw new IOException( + "The HTTP response code for " + src + " did not indicate a success." + + " See log for more detail.") + } + case _ => + } + val inStream = getDecodingInputStream(srcConn.getContentEncoding(), srcConn.getInputStream()) + FileUtil.copy(inStream, dest, l) + // check content length only if content was not encoded + Option(srcConn.getContentEncoding) match { + case None => + val contentLength = srcConn.getContentLength + if (contentLength != -1 && dest.length != contentLength) { + IO.delete(dest) + throw new IOException( + "Downloaded file size doesn't match expected Content Length for " + src + + ". Please retry.") + } + case _ => () + } + val lastModified = srcConn.getLastModified + if (lastModified > 0) { + dest.setLastModified(lastModified) + () + } + () + } + + def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { + val dest = normalizeToURL(dest0) + val conn = Http.open(dest) match { + case c: HttpURLConnection => c + } + conn.setDoOutput(true) + conn.setRequestMethod("PUT") + conn.setRequestProperty("Content-type", "application/octet-stream") + conn.setRequestProperty("Content-length", source.length.toLong.toString) + conn.setInstanceFollowRedirects(true) + Using.fileInputStream(source) { in => + val os = conn.getOutputStream + FileUtil.copy(in, os, l) + } + validatePutStatusCode(dest, conn.getResponseCode(), conn.getResponseMessage()) + } + + def checkStatusCode(url: URL, con: HttpURLConnection): Boolean = + con.getResponseCode match { + case 200 => true + case 204 if "HEAD" == con.getRequestMethod => true + case status => + Message.debug("HTTP response status: " + status + " url=" + url) + if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { + Message.warn("Your proxy requires authentication."); + } else if (String.valueOf(status).startsWith("4")) { + Message.verbose("CLIENT ERROR: " + con.getResponseMessage() + " url=" + url) + } else if (String.valueOf(status).startsWith("5")) { + Message.error("SERVER ERROR: " + con.getResponseMessage() + " url=" + url) + } + false + } + + // This is requires to access the constructor of URLInfo. + private[sbt] class SbtUrlInfo(available: Boolean, + contentLength: Long, + lastModified: Long, + bodyCharset: String) + extends URLInfo(available, contentLength, lastModified, bodyCharset) { + def this(available: Boolean, contentLength: Long, lastModified: Long) = { + this(available, contentLength, lastModified, null) + } + } +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala index 9870d9b0f..3fee33b82 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,7 +1,13 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse +import okhttp3.{ OkUrlFactory, OkHttpClient } +import java.net.{ URL, HttpURLConnection } object Http { lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + + private[sbt] lazy val urlFactory = new OkUrlFactory(http.underlying[OkHttpClient]) + private[sbt] def open(url: URL): HttpURLConnection = + urlFactory.open(url) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 4c3810055..c0214a6cb 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -18,10 +18,10 @@ final class UpdateOptions private[sbt] ( val interProjectFirst: Boolean, // If set to true, check all resolvers for snapshots. val latestSnapshots: Boolean, - // If set to true, use consolidated resolution. - val consolidatedResolution: Boolean, // If set to true, use cached resolution. val cachedResolution: Boolean, + // If set to true, use Gigahorse + val gigahorse: Boolean, // Extension point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter, // Map the unique resolver to be checked for the module ID @@ -35,17 +35,11 @@ final class UpdateOptions private[sbt] ( copy(interProjectFirst = interProjectFirst) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) - @deprecated("Use withCachedResolution instead.", "0.13.7") - def withConsolidatedResolution(consolidatedResolution: Boolean): UpdateOptions = - copy( - consolidatedResolution = consolidatedResolution, - cachedResolution = consolidatedResolution - ) def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = - copy( - cachedResolution = cachedResoluton, - consolidatedResolution = cachedResolution - ) + copy(cachedResolution = cachedResoluton) + + def withGigahorse(gigahorse: Boolean): UpdateOptions = + copy(gigahorse = gigahorse) /** Extention point for an alternative resolver converter. */ def withResolverConverter(resolverConverter: UpdateOptions.ResolverConverter): UpdateOptions = @@ -58,8 +52,8 @@ final class UpdateOptions private[sbt] ( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, - consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, + gigahorse: Boolean = this.gigahorse, resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter, moduleResolvers: Map[ModuleID, Resolver] = this.moduleResolvers ): UpdateOptions = @@ -67,8 +61,8 @@ final class UpdateOptions private[sbt] ( circularDependencyLevel, interProjectFirst, latestSnapshots, - consolidatedResolution, cachedResolution, + gigahorse, resolverConverter, moduleResolvers ) @@ -79,6 +73,7 @@ final class UpdateOptions private[sbt] ( this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && + this.gigahorse == o.gigahorse && this.resolverConverter == o.resolverConverter && this.moduleResolvers == o.moduleResolvers case _ => false @@ -90,6 +85,7 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.interProjectFirst.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## + hash = hash * 31 + this.gigahorse.## hash = hash * 31 + this.resolverConverter.## hash = hash * 31 + this.moduleResolvers.## hash @@ -104,8 +100,8 @@ object UpdateOptions { circularDependencyLevel = CircularDependencyLevel.Warn, interProjectFirst = true, latestSnapshots = true, - consolidatedResolution = false, cachedResolution = false, + gigahorse = true, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2ad1ff99a..e5be5fa54 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -58,6 +58,7 @@ object Dependencies { val sjsonnewVersion = "0.7.0" val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" + val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" private def scala211Module(name: String, moduleVersion: String) = Def.setting { From 80ee35b01cbb180922cc7b4b05c61ccd53637ea5 Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 25 May 2017 22:09:12 +0200 Subject: [PATCH 0610/1030] Add custom checksum checks to ivy --- .../librarymanagement/ConvertResolver.scala | 74 +++++++++++++++++-- .../ivyint/SbtChainResolver.scala | 1 + .../src/test/scala/BaseIvySpecification.scala | 2 +- .../src/test/scala/OfflineModeSpec.scala | 2 +- 4 files changed, 70 insertions(+), 9 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 82760272c..2a75124c5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -5,10 +5,15 @@ package sbt.internal.librarymanagement import java.net.URL import java.util.Collections + import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, TransferEvent } +import org.apache.ivy.plugins.repository.{ + RepositoryCopyProgressListener, + Resource, + TransferEvent +} import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, @@ -24,9 +29,10 @@ import org.apache.ivy.plugins.resolver.{ URLResolver } import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } -import org.apache.ivy.plugins.repository.file.{ FileRepository => FileRepo, FileResource } -import java.io.{ IOException, File } -import org.apache.ivy.util.{ FileUtil, ChecksumHelper } +import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => FileRepo } +import java.io.{ File, IOException } + +import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } import sbt.io.IO import sbt.util.Logger @@ -156,6 +162,7 @@ private[sbt] object ConvertResolver { extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) def setPatterns(): Unit = { // done this way for access to protected methods. setArtifactPatterns(pattern) @@ -170,7 +177,9 @@ private[sbt] object ConvertResolver { resolver } case repo: SshRepository => { - val resolver = new SshResolver with DescriptorRequired + val resolver = new SshResolver with DescriptorRequired { + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } initializeSSHResolver(resolver, repo, settings) repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) resolver @@ -187,6 +196,7 @@ private[sbt] object ConvertResolver { // in local files for non-changing revisions. // This will be fully enforced in sbt 1.0. setRepository(new WarnOnOverwriteFileRepo()) + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } resolver.setName(repo.name) initializePatterns(resolver, repo.patterns, settings) @@ -196,7 +206,9 @@ private[sbt] object ConvertResolver { resolver } case repo: URLRepository => { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } resolver.setName(repo.name) initializePatterns(resolver, repo.patterns, settings) resolver @@ -208,11 +220,59 @@ private[sbt] object ConvertResolver { } private sealed trait DescriptorRequired extends BasicResolver { + // Works around implementation restriction to access protected method `get` + def getResource(resource: Resource, dest: File): Long + + override def getAndCheck(resource: Resource, dest: File): Long = { + // Follows the same semantics that private method `check` as defined in ivy `BasicResolver` + def check(resource: Resource, destination: File, algorithm: String) = { + if (!ChecksumHelper.isKnownAlgorithm(algorithm)) { + throw new IllegalArgumentException(s"Unknown checksum algorithm: $algorithm") + } + val checksumResource = resource.clone(s"${resource.getName}.$algorithm") + if (checksumResource.exists) { + Message.debug(s"$algorithm file found for $resource: checking...") + val checksumFile = File.createTempFile("ivytmp", algorithm) + try { + getResource(checksumResource, checksumFile) + try { + ChecksumHelper.check(dest, checksumFile, algorithm) + Message.verbose(s"$algorithm OK for $resource") + true + } catch { + case e: IOException => + dest.delete() + throw e + } + } finally { + checksumFile.delete() + } + } else false + } + + val size = getResource(resource, dest) + val checksums = getChecksumAlgorithms + checksums.foldLeft(false) { (failed, checksum) => + // Continue checking until we hit a failure + if (failed) failed + else check(resource, dest, checksum) + } + size + } + var i = 0 override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { + val moduleID = IvyRetrieve.toModuleID(dd.getDependencyRevisionId) + print(" " * i) + println(s"Downloading and checking for $moduleID") + i += 2 val prev = descriptorString(isAllownomd) setDescriptor(descriptorString(hasExplicitURL(dd))) - try super.getDependency(dd, data) + val t = try super.getDependency(dd, data) finally setDescriptor(prev) + i -= 2 + print(" " * i) + println(s"End $moduleID") + t } def descriptorString(optional: Boolean) = if (optional) BasicResolver.DESCRIPTOR_OPTIONAL else BasicResolver.DESCRIPTOR_REQUIRED diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index a364b9d77..ad6245055 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -31,6 +31,7 @@ private[sbt] case class SbtChainResolver( updateOptions: UpdateOptions, log: Logger ) extends ChainResolver { + override def setCheckmodified(check: Boolean): Unit = super.setCheckmodified(check) override def equals(o: Any): Boolean = o match { case o: SbtChainResolver => diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index d87baa862..6068496d6 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -53,8 +53,8 @@ trait BaseIvySpecification extends UnitSpec { def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty - val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val check = Vector.empty + val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, resolvers, diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala index 0b941f405..04d8cf836 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -44,7 +44,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { val offlineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) - assert(offlineResolution.isRight) + assert(offlineResolution.isRight, s"Offline resolution has failed with $offlineResolution.") val resolveTime = offlineResolution.right.get.stats.resolveTime // Only check the estimate for the non cached resolution, otherwise resolution is cached From 7500291dfc71d02e8c7e9cea1a6b82faa7012ce3 Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 25 May 2017 22:15:46 +0200 Subject: [PATCH 0611/1030] Fix bug in updateOptionsFormat --- .../librarymanagement/formats/UpdateOptionsFormat.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 5074e8a0e..832af13ad 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -35,7 +35,7 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re xs._3, xs._4, xs._5, - ConvertResolver.defaultConvert, + PartialFunction.empty, xs._6 ) ) From 892f6e3775456b6d74021e18b60a2f4cae84648b Mon Sep 17 00:00:00 2001 From: jvican Date: Thu, 25 May 2017 23:30:00 +0200 Subject: [PATCH 0612/1030] Add checksum to ModuleID A checksum in a `ModuleID` ensures that the checksum of the resolved module id matches. This checksum check is done at the same time ivy checks it. --- .../main/contraband/librarymanagement.json | 31 +++++++++++++------ .../sbt/librarymanagement/ModuleIDExtra.scala | 7 +++-- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index d28da3b69..d098603d8 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -267,22 +267,33 @@ { "name": "organization", "type": "String" }, { "name": "name", "type": "String" }, { "name": "revision", "type": "String" }, - { "name": "configurations", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, - { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, - { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, - { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" } + { "name": "configurations", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "isChanging", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "isTransitive", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "isForce", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "explicitArtifacts", "type": "sbt.librarymanagement.Artifact*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "inclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, + { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, + { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } ], "toString": [ "this.toStringImpl" ], "parentsCompanion": "sbt.librarymanagement.ModuleIDFunctions" }, + { + "name": "Checksum", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "digest", "type": "String" }, + { "name": "type", "type": "String", "default": "sha1" } + ] + }, { "name": "ModuleInfo", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 5b89b5419..e52df5a4d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -22,6 +22,7 @@ abstract class ModuleIDExtra { def extraAttributes: Map[String, String] def crossVersion: CrossVersion def branchName: Option[String] + def checksum: Option[Checksum] protected[this] def copy( organization: String = organization, @@ -36,12 +37,14 @@ abstract class ModuleIDExtra { exclusions: Vector[ExclusionRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: CrossVersion = crossVersion, - branchName: Option[String] = branchName + branchName: Option[String] = branchName, + checksum: Option[Checksum] = checksum ): ModuleID protected def toStringImpl: String = s"""$organization:$name:$revision""" + - (configurations match { case Some(s) => ":" + s; case None => "" }) + { + (checksum match { case Some(s) => s": ${s.`type`} ${s.digest}"; case None => "" }) + + (configurations match { case Some(s) => ":" + s; case None => "" }) + { val attr = attributeString if (attr == "") "" else " " + attr From 4c8036c7cb780d1209f997daf1016462b1c290b7 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 26 May 2017 10:44:24 +0200 Subject: [PATCH 0613/1030] Add `managedChecksums` to `UpdateOptions` --- .../formats/UpdateOptionsFormat.scala | 6 ++++-- .../scala/sbt/librarymanagement/UpdateOptions.scala | 10 ++++++++++ .../src/test/scala/BaseIvySpecification.scala | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 832af13ad..217beb77f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -26,17 +26,19 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re uo.latestSnapshots, uo.consolidatedResolution, uo.cachedResolution, + uo.managedChecksums, uo.moduleResolvers ), - (xs: (String, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => + (xs: (String, Boolean, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => new UpdateOptions( levels(xs._1), xs._2, xs._3, xs._4, xs._5, + xs._6, PartialFunction.empty, - xs._6 + xs._7 ) ) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 4c3810055..7253f0edc 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -22,6 +22,8 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, // If set to true, use cached resolution. val cachedResolution: Boolean, + // If set to true, use cached resolution. + val managedChecksums: Boolean, // Extension point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter, // Map the unique resolver to be checked for the module ID @@ -54,12 +56,16 @@ final class UpdateOptions private[sbt] ( def withModuleResolvers(moduleResolvers: Map[ModuleID, Resolver]): UpdateOptions = copy(moduleResolvers = moduleResolvers) + def withManagedChecksums(managedChecksums: Boolean): UpdateOptions = + copy(managedChecksums = managedChecksums) + private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, + managedChecksums: Boolean = this.managedChecksums, resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter, moduleResolvers: Map[ModuleID, Resolver] = this.moduleResolvers ): UpdateOptions = @@ -69,6 +75,7 @@ final class UpdateOptions private[sbt] ( latestSnapshots, consolidatedResolution, cachedResolution, + managedChecksums, resolverConverter, moduleResolvers ) @@ -79,6 +86,7 @@ final class UpdateOptions private[sbt] ( this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && + this.managedChecksums == o.managedChecksums && this.resolverConverter == o.resolverConverter && this.moduleResolvers == o.moduleResolvers case _ => false @@ -90,6 +98,7 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.interProjectFirst.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## + hash = hash * 31 + this.managedChecksums.## hash = hash * 31 + this.resolverConverter.## hash = hash * 31 + this.moduleResolvers.## hash @@ -106,6 +115,7 @@ object UpdateOptions { latestSnapshots = true, consolidatedResolution = false, cachedResolution = false, + managedChecksums = false, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 6068496d6..7ab89de56 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -53,7 +53,7 @@ trait BaseIvySpecification extends UnitSpec { def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty - val check = Vector.empty + val check = IvySbt.DefaultChecksums.headOption.toVector val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, From 7bf60557d9d756bfeb6bb59e69e04ec1f1404c19 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 26 May 2017 12:10:29 +0200 Subject: [PATCH 0614/1030] Implement `managedChecksums` in ivy Managed checksums tells ivy to forget about checking checksums for jar files and just persist them in the cache. The user that enables that option will take care of verifying they are correct. This is a big deal because: 1. Ivy takes *a lot of time* checking timestamps for big jars, and does it sequentially. The user (sbt) can do better by running these checks in parallel, speeding up the whole resolution process! 2. The fact that the sha files are not present in the cache means that build tools cannot check if a checksum is correct without preprocessing the jar. Note that the user is responsible for keeping the cache consistent. If the checksum is not correct, the user should report it and overwrite the checksum file with the valid digest. --- .../librarymanagement/ConvertResolver.scala | 100 ++++++++++-------- .../librarymanagement/IvyActions.scala | 22 +++- .../sbt/librarymanagement/UpdateOptions.scala | 5 +- .../src/test/scala/BaseIvySpecification.scala | 2 +- .../src/test/scala/OfflineModeSpec.scala | 2 +- .../ManagedChecksumsSpec.scala | 75 +++++++++++++ 6 files changed, 159 insertions(+), 47 deletions(-) create mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 2a75124c5..839083dd7 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -141,18 +141,24 @@ private[sbt] object ConvertResolver { def apply(r: Resolver, settings: IvySettings, log: Logger): DependencyResolver = apply(r, settings, UpdateOptions(), log) + private[librarymanagement] val ManagedChecksums = "managedChecksums" + /** Converts the given sbt resolver into an Ivy resolver. */ def apply( r: Resolver, settings: IvySettings, updateOptions: UpdateOptions, log: Logger - ): DependencyResolver = + ): DependencyResolver = { + // Pass in to the resolver converter the update options via ivy settings + settings.setVariable(ManagedChecksums, updateOptions.managedChecksums.toString) (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) + } /** The default implementation of converter. */ lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => + val managedChecksums = settings.getVariable(ManagedChecksums).toBoolean r match { case repo: MavenRepository => { val pattern = Collections.singletonList( @@ -162,6 +168,7 @@ private[sbt] object ConvertResolver { extends IBiblioResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums override def getResource(resource: Resource, dest: File): Long = get(resource, dest) def setPatterns(): Unit = { // done this way for access to protected methods. @@ -178,6 +185,7 @@ private[sbt] object ConvertResolver { } case repo: SshRepository => { val resolver = new SshResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } initializeSSHResolver(resolver, repo, settings) @@ -196,6 +204,7 @@ private[sbt] object ConvertResolver { // in local files for non-changing revisions. // This will be fully enforced in sbt 1.0. setRepository(new WarnOnOverwriteFileRepo()) + override val managedChecksumsEnabled: Boolean = managedChecksums override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } resolver.setName(repo.name) @@ -207,6 +216,7 @@ private[sbt] object ConvertResolver { } case repo: URLRepository => { val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } resolver.setName(repo.name) @@ -223,55 +233,61 @@ private[sbt] object ConvertResolver { // Works around implementation restriction to access protected method `get` def getResource(resource: Resource, dest: File): Long - override def getAndCheck(resource: Resource, dest: File): Long = { - // Follows the same semantics that private method `check` as defined in ivy `BasicResolver` - def check(resource: Resource, destination: File, algorithm: String) = { - if (!ChecksumHelper.isKnownAlgorithm(algorithm)) { - throw new IllegalArgumentException(s"Unknown checksum algorithm: $algorithm") - } - val checksumResource = resource.clone(s"${resource.getName}.$algorithm") - if (checksumResource.exists) { - Message.debug(s"$algorithm file found for $resource: checking...") - val checksumFile = File.createTempFile("ivytmp", algorithm) - try { - getResource(checksumResource, checksumFile) - try { - ChecksumHelper.check(dest, checksumFile, algorithm) - Message.verbose(s"$algorithm OK for $resource") - true - } catch { - case e: IOException => - dest.delete() - throw e - } - } finally { - checksumFile.delete() - } - } else false - } + /** + * Defines an option to tell ivy to disable checksums when downloading and + * let the user handle verifying these checksums. + * + * This means that the checksums are stored in the ivy cache directory. This + * is good for reproducibility from outside ivy. Sbt can check that jars are + * not corrupted, ever, independently of trusting whatever it's there in the + * local directory. + */ + def managedChecksumsEnabled: Boolean - val size = getResource(resource, dest) - val checksums = getChecksumAlgorithms - checksums.foldLeft(false) { (failed, checksum) => - // Continue checking until we hit a failure - if (failed) failed - else check(resource, dest, checksum) + import sbt.io.syntax._ + private def downloadChecksum(resource: Resource, + target: File, + targetChecksumFile: File, + algorithm: String): Boolean = { + if (!ChecksumHelper.isKnownAlgorithm(algorithm)) + throw new IllegalArgumentException(s"Unknown checksum algorithm: $algorithm") + + val checksumResource = resource.clone(s"${resource.getName}.$algorithm") + if (!checksumResource.exists) false + else { + Message.debug(s"$algorithm file found for $resource: downloading...") + // Resource must be cleaned up outside of this function if it's invalid + getResource(checksumResource, targetChecksumFile) + true } - size } - var i = 0 + + private final val PartEnd = ".part" + private final val JarEnd = ".jar" + private final val TemporaryJar = JarEnd + PartEnd + override def getAndCheck(resource: Resource, target: File): Long = { + val targetPath = target.getAbsolutePath + if (!managedChecksumsEnabled || !targetPath.endsWith(TemporaryJar)) { + super.getAndCheck(resource, target) + } else { + // This is where we differ from ivy behaviour + val size = getResource(resource, target) + val checksumAlgorithms = getChecksumAlgorithms + checksumAlgorithms.foldLeft(false) { (checked, algorithm) => + // Continue checking until we hit a failure + val checksumFile = new File(targetPath.stripSuffix(PartEnd) + s".$algorithm") + if (checked) checked + else downloadChecksum(resource, target, checksumFile, algorithm) + } + size + } + } + override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { - val moduleID = IvyRetrieve.toModuleID(dd.getDependencyRevisionId) - print(" " * i) - println(s"Downloading and checking for $moduleID") - i += 2 val prev = descriptorString(isAllownomd) setDescriptor(descriptorString(hasExplicitURL(dd))) val t = try super.getDependency(dd, data) finally setDescriptor(prev) - i -= 2 - print(" " * i) - println(s"End $moduleID") t } def descriptorString(optional: Boolean) = diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 638aa4770..d989d2cd4 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -540,6 +540,7 @@ object IvyActions { report: UpdateReport, config: RetrieveConfiguration ): UpdateReport = { + val copyChecksums = ivy.getVariable(ConvertResolver.ManagedChecksums).toBoolean val toRetrieve = config.configurationsToRetrieve val base = config.retrieveDirectory val pattern = config.outputPattern @@ -551,9 +552,9 @@ object IvyActions { val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf, mid, art, cached) => configurationNames match { - case None => performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + case None => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) case Some(names) if names(conf) => - performRetrieve(conf, mid, art, base, pattern, cached, toCopy) + performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) case _ => cached } } @@ -577,10 +578,27 @@ object IvyActions { base: File, pattern: String, cached: File, + copyChecksums: Boolean, toCopy: collection.mutable.HashSet[(File, File)] ): File = { val to = retrieveTarget(conf, mid, art, base, pattern) toCopy += ((cached, to)) + + if (copyChecksums) { + // Copy over to the lib managed directory any checksum for a jar if it exists + // TODO(jvican): Support user-provided checksums + val cachePath = cached.getAbsolutePath + IvySbt.DefaultChecksums.foreach { checksum => + if (cachePath.endsWith(".jar")) { + val cacheChecksum = new File(s"$cachePath.$checksum") + if (cacheChecksum.exists()) { + val toChecksum = new File(s"${to.getAbsolutePath}.$checksum") + toCopy += ((cacheChecksum, toChecksum)) + } + } + } + } + to } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 7253f0edc..bc210670f 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -9,6 +9,9 @@ import sbt.util.Logger * While UpdateConfiguration is passed into update at runtime, * UpdateOption is intended to be used while setting up the Ivy object. * + * @param managedChecksums Managed checksums tells ivy whether it should only download the + * checksum files and let the caller handle the verification. + * * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( @@ -22,7 +25,7 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, // If set to true, use cached resolution. val cachedResolution: Boolean, - // If set to true, use cached resolution. + // If set to true, use managed checksums. val managedChecksums: Boolean, // Extension point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter, diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 7ab89de56..6068496d6 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -53,7 +53,7 @@ trait BaseIvySpecification extends UnitSpec { def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty - val check = IvySbt.DefaultChecksums.headOption.toVector + val check = Vector.empty val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala index 04d8cf836..ea6b5f1d7 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -3,7 +3,7 @@ package sbt.librarymanagement import org.scalatest.Assertion import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement.impl.DependencyBuilders -import sbt.io.IO +import sbt.io.{ FileFilter, IO, Path } class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { private final def targetDir = Some(currentDependency) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala new file mode 100644 index 000000000..9dc0649de --- /dev/null +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -0,0 +1,75 @@ +package sbt.librarymanagement + +import java.io.File + +import org.apache.ivy.util.Message +import org.scalatest.Assertion +import sbt.internal.librarymanagement.{ + BaseIvySpecification, + InlineIvyConfiguration, + IvyActions, + IvyConfiguration, + IvyPaths, + IvySbt, + LogicalClock, + UnresolvedWarningConfiguration +} +import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.io.IO + +class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders { + private final def targetDir = Some(currentDependency) + private final def onlineConf = makeUpdateConfiguration(false) + private final def warningConf = UnresolvedWarningConfiguration() + private final def noClock = LogicalClock.unknown + private final val Checksum = "sha1" + + def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7") + def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40") + def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final") + final def dependencies: Vector[ModuleID] = + Vector(avro177, dataAvro1940, netty320).map(_.withConfigurations(Some("compile"))) + + import sbt.io.syntax._ + override def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { + val paths = IvyPaths(currentBase, Some(currentTarget)) + val other = Vector.empty + val check = Vector(Checksum) + val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) + val resCacheDir = currentTarget / "resolution-cache" + new InlineIvyConfiguration(paths, + resolvers, + other, + moduleConfs, + None, + check, + Some(resCacheDir), + uo, + log) + } + + def cleanAll(): Unit = { + cleanIvyCache() + IO.delete(currentTarget) + IO.delete(currentManaged) + IO.delete(currentDependency) + } + + def assertChecksumExists(file: File) = { + val shaFile = new File(file.getAbsolutePath + s".$Checksum") + Message.info(s"Checking $shaFile exists...") + assert(shaFile.exists(), s"The checksum $Checksum for $file does not exist") + } + + "Managed checksums" should "should download the checksum files" in { + cleanAll() + val updateOptions = UpdateOptions().withManagedChecksums(true) + val toResolve = module(defaultModuleId, dependencies, None, updateOptions) + val res = IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) + assert(res.isRight, s"Resolution with managed checksums failed! $res") + val updateReport = res.right.get + val allModuleReports = updateReport.configurations.flatMap(_.modules) + val allArtifacts: Seq[File] = allModuleReports.flatMap(_.artifacts.map(_._2)) + allArtifacts.foreach(assertChecksumExists) + } +} From e3a52c3e1f27ca4a63be22ddf9c41d705c75dfd9 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 26 May 2017 12:26:03 +0200 Subject: [PATCH 0615/1030] Make explicit where we deviate from ivy behaviour --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 839083dd7..c7df8a641 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -265,12 +265,13 @@ private[sbt] object ConvertResolver { private final val PartEnd = ".part" private final val JarEnd = ".jar" private final val TemporaryJar = JarEnd + PartEnd + override def getAndCheck(resource: Resource, target: File): Long = { val targetPath = target.getAbsolutePath if (!managedChecksumsEnabled || !targetPath.endsWith(TemporaryJar)) { super.getAndCheck(resource, target) } else { - // This is where we differ from ivy behaviour + // +ivy deviation val size = getResource(resource, target) val checksumAlgorithms = getChecksumAlgorithms checksumAlgorithms.foldLeft(false) { (checked, algorithm) => @@ -279,6 +280,7 @@ private[sbt] object ConvertResolver { if (checked) checked else downloadChecksum(resource, target, checksumFile, algorithm) } + // -ivy deviation size } } From 27bf1308532b03b44b3b13471b38eb9feb5b4d43 Mon Sep 17 00:00:00 2001 From: jvican Date: Fri, 26 May 2017 20:10:53 +0200 Subject: [PATCH 0616/1030] Move `managedChecksums` to InlineIvyConfiguration `UpdateOptions` is only meant for user-provided options. Since this option should not be exposed to users, it's moved to inline ivy configuration, whose parameters require information about the build and is usually defined project-wide instead of `Global`-wide. --- .../src/main/contraband/librarymanagement.json | 4 +++- .../librarymanagement/ConvertResolver.scala | 7 ++----- .../scala/sbt/internal/librarymanagement/Ivy.scala | 1 + .../sbt/internal/librarymanagement/IvyCache.scala | 1 + .../formats/UpdateOptionsFormat.scala | 6 ++---- .../scala/sbt/librarymanagement/UpdateOptions.scala | 13 ------------- .../src/test/scala/BaseIvySpecification.scala | 2 ++ .../src/test/scala/CustomPomParserTest.scala | 1 + .../librarymanagement/ManagedChecksumsSpec.scala | 3 ++- 9 files changed, 14 insertions(+), 24 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index d098603d8..06dea8671 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -742,6 +742,7 @@ { "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" }, { "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" }, { "name": "checksums", "type": "String*" }, + { "name": "managedChecksums", "type": "Boolean" }, { "name": "resolutionCacheDir", "type": "java.io.File?" } ], "extra": [ @@ -752,12 +753,13 @@ " moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],", " lock: Option[xsbti.GlobalLock],", " checksums: Vector[String],", + " managedChecksums: Boolean,", " resolutionCacheDir: Option[java.io.File],", " updateOptions: sbt.librarymanagement.UpdateOptions,", " log: xsbti.Logger", ") =", " this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,", - " moduleConfigurations, checksums, resolutionCacheDir)" + " moduleConfigurations, checksums, managedChecksums, resolutionCacheDir)" ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index c7df8a641..bba247e80 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -141,7 +141,7 @@ private[sbt] object ConvertResolver { def apply(r: Resolver, settings: IvySettings, log: Logger): DependencyResolver = apply(r, settings, UpdateOptions(), log) - private[librarymanagement] val ManagedChecksums = "managedChecksums" + private[librarymanagement] val ManagedChecksums = "sbt.managedChecksums" /** Converts the given sbt resolver into an Ivy resolver. */ def apply( @@ -149,11 +149,8 @@ private[sbt] object ConvertResolver { settings: IvySettings, updateOptions: UpdateOptions, log: Logger - ): DependencyResolver = { - // Pass in to the resolver converter the update options via ivy settings - settings.setVariable(ManagedChecksums, updateOptions.managedChecksums.toString) + ): DependencyResolver = (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) - } /** The default implementation of converter. */ lazy val defaultConvert: ResolverConverter = { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e27eb1907..38bba8076 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -87,6 +87,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => IvySbt.loadURI(is, e.uri) case i: InlineIvyConfiguration => is.setVariable("ivy.checksums", i.checksums mkString ",") + is.setVariable(ConvertResolver.ManagedChecksums, i.managedChecksums.toString) i.paths.ivyHome foreach is.setDefaultIvyUserDir val log = configuration.log IvySbt.configureCache(is, i.resolutionCacheDir) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index bef341acc..5a17a2d82 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -110,6 +110,7 @@ class IvyCache(val ivyHome: Option[File]) { Vector.empty, lock, IvySbt.DefaultChecksums, + false, None, UpdateOptions(), log diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 217beb77f..832af13ad 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -26,19 +26,17 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re uo.latestSnapshots, uo.consolidatedResolution, uo.cachedResolution, - uo.managedChecksums, uo.moduleResolvers ), - (xs: (String, Boolean, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => + (xs: (String, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => new UpdateOptions( levels(xs._1), xs._2, xs._3, xs._4, xs._5, - xs._6, PartialFunction.empty, - xs._7 + xs._6 ) ) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index bc210670f..4c3810055 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -9,9 +9,6 @@ import sbt.util.Logger * While UpdateConfiguration is passed into update at runtime, * UpdateOption is intended to be used while setting up the Ivy object. * - * @param managedChecksums Managed checksums tells ivy whether it should only download the - * checksum files and let the caller handle the verification. - * * See also UpdateConfiguration in IvyActions.scala. */ final class UpdateOptions private[sbt] ( @@ -25,8 +22,6 @@ final class UpdateOptions private[sbt] ( val consolidatedResolution: Boolean, // If set to true, use cached resolution. val cachedResolution: Boolean, - // If set to true, use managed checksums. - val managedChecksums: Boolean, // Extension point for an alternative resolver converter. val resolverConverter: UpdateOptions.ResolverConverter, // Map the unique resolver to be checked for the module ID @@ -59,16 +54,12 @@ final class UpdateOptions private[sbt] ( def withModuleResolvers(moduleResolvers: Map[ModuleID, Resolver]): UpdateOptions = copy(moduleResolvers = moduleResolvers) - def withManagedChecksums(managedChecksums: Boolean): UpdateOptions = - copy(managedChecksums = managedChecksums) - private[sbt] def copy( circularDependencyLevel: CircularDependencyLevel = this.circularDependencyLevel, interProjectFirst: Boolean = this.interProjectFirst, latestSnapshots: Boolean = this.latestSnapshots, consolidatedResolution: Boolean = this.consolidatedResolution, cachedResolution: Boolean = this.cachedResolution, - managedChecksums: Boolean = this.managedChecksums, resolverConverter: UpdateOptions.ResolverConverter = this.resolverConverter, moduleResolvers: Map[ModuleID, Resolver] = this.moduleResolvers ): UpdateOptions = @@ -78,7 +69,6 @@ final class UpdateOptions private[sbt] ( latestSnapshots, consolidatedResolution, cachedResolution, - managedChecksums, resolverConverter, moduleResolvers ) @@ -89,7 +79,6 @@ final class UpdateOptions private[sbt] ( this.interProjectFirst == o.interProjectFirst && this.latestSnapshots == o.latestSnapshots && this.cachedResolution == o.cachedResolution && - this.managedChecksums == o.managedChecksums && this.resolverConverter == o.resolverConverter && this.moduleResolvers == o.moduleResolvers case _ => false @@ -101,7 +90,6 @@ final class UpdateOptions private[sbt] ( hash = hash * 31 + this.interProjectFirst.## hash = hash * 31 + this.latestSnapshots.## hash = hash * 31 + this.cachedResolution.## - hash = hash * 31 + this.managedChecksums.## hash = hash * 31 + this.resolverConverter.## hash = hash * 31 + this.moduleResolvers.## hash @@ -118,7 +106,6 @@ object UpdateOptions { latestSnapshots = true, consolidatedResolution = false, cachedResolution = false, - managedChecksums = false, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/librarymanagement/src/test/scala/BaseIvySpecification.scala index 6068496d6..5fa82c305 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/librarymanagement/src/test/scala/BaseIvySpecification.scala @@ -54,6 +54,7 @@ trait BaseIvySpecification extends UnitSpec { val paths = IvyPaths(currentBase, Some(currentTarget)) val other = Vector.empty val check = Vector.empty + val managedChecksums = false val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" new InlineIvyConfiguration(paths, @@ -62,6 +63,7 @@ trait BaseIvySpecification extends UnitSpec { moduleConfs, None, check, + managedChecksums, Some(resCacheDir), uo, log) diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/librarymanagement/src/test/scala/CustomPomParserTest.scala index 950562638..488f683a8 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/librarymanagement/src/test/scala/CustomPomParserTest.scala @@ -21,6 +21,7 @@ class CustomPomParserTest extends UnitSpec { Vector.empty, None, Vector("sha1", "md5"), + false, None, UpdateOptions(), log) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index 9dc0649de..493d600e5 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -43,6 +43,7 @@ class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders moduleConfs, None, check, + managedChecksums = true, Some(resCacheDir), uo, log) @@ -63,7 +64,7 @@ class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders "Managed checksums" should "should download the checksum files" in { cleanAll() - val updateOptions = UpdateOptions().withManagedChecksums(true) + val updateOptions = UpdateOptions() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) val res = IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) assert(res.isRight, s"Resolution with managed checksums failed! $res") From 87a53986e3a8b4ba3122c125df48dfb6524bff54 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Fri, 28 Apr 2017 11:41:59 +0200 Subject: [PATCH 0617/1030] Fix default scalaBinaryVersion for Dotty Dotty is versioned as 0.*, but `CrossVersionUtil#binaryScalaVersion` will return the full version instead of just `major.minor` for all compiler versions < 2.10, add a special case for Dotty to avoid this. --- .../librarymanagement/cross/CrossVersionUtil.scala | 14 +++++++++++--- .../src/test/scala/CrossVersionTest.scala | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 4ebc79ca0..cebe00ac5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -8,7 +8,8 @@ object CrossVersionUtil { val noneString = "none" val disabledString = "disabled" val binaryString = "binary" - val TransitionScalaVersion = "2.10" + val TransitionDottyVersion = "" // Dotty always respects binary compatibility + val TransitionScalaVersion = "2.10" // ...but scalac doesn't until Scala 2.10 val TransitionSbtVersion = "0.12" def isFull(s: String): Boolean = (s == trueString) || (s == fullString) @@ -61,8 +62,15 @@ object CrossVersionUtil { case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) case _ => None } - def binaryScalaVersion(full: String): String = - binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) + def binaryScalaVersion(full: String): String = { + val cutoff = + if (full.startsWith("0.")) + TransitionDottyVersion + else + TransitionScalaVersion + + binaryVersionWithApi(full, cutoff)(scalaApiVersion) + } def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) private[sbt] def binaryVersion(full: String, cutoff: String): String = diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index d6e245dcd..835ad1058 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -117,6 +117,9 @@ class CrossVersionTest extends UnitSpec { it should "return binary Scala version for 2.20170314093845.0-87654321 as 2.20170314093845.0-87654321" in { CrossVersion.binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" } + it should "return binary Scala version for Dotty 0.1.1 as 0.1" in { + CrossVersion.binaryScalaVersion("0.1.1") shouldBe "0.1" + } it should "return patch Scala version for 2.11.8 as 2.11.8" in { CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some( "artefact_2.11.8") From a50f96c7c46d59cc8c1a5d321f8269da1f89e0cf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 May 2017 13:18:11 -0400 Subject: [PATCH 0618/1030] change EvictionWarningOptions.default Fixes sbt/sbt#3171 change EvictionWarningOptions.default to include transitive evictions and caller info. --- .../librarymanagement/EvictionWarning.scala | 24 ++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index eff181a25..1dd049e5b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -58,11 +58,29 @@ final class EvictionWarningOptions private[sbt] ( object EvictionWarningOptions { def empty: EvictionWarningOptions = - new EvictionWarningOptions(Vector(), false, false, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(), + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + infoAllEvictions = false, + showCallers = false, + defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, false, false, false, defaultGuess) + new EvictionWarningOptions(Vector(Compile), + warnScalaVersionEviction = true, + warnDirectEvictions = true, + warnTransitiveEvictions = true, + infoAllEvictions = false, + showCallers = true, + defaultGuess) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), true, true, true, true, true, defaultGuess) + new EvictionWarningOptions(Vector(Compile), + warnScalaVersionEviction = true, + warnDirectEvictions = true, + warnTransitiveEvictions = true, + infoAllEvictions = true, + showCallers = true, + defaultGuess) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse From 182a07402acf05261fa4b2d5b7ca5cb54f0864f4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 May 2017 13:59:07 -0400 Subject: [PATCH 0619/1030] update EvictionWarningSpec --- .../librarymanagement/EvictionWarning.scala | 24 +++++---- .../src/test/scala/EvictionWarningSpec.scala | 49 ++++++------------- 2 files changed, 30 insertions(+), 43 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 1dd049e5b..b0e22ce47 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -59,28 +59,32 @@ final class EvictionWarningOptions private[sbt] ( object EvictionWarningOptions { def empty: EvictionWarningOptions = new EvictionWarningOptions(Vector(), - warnScalaVersionEviction = false, - warnDirectEvictions = false, - warnTransitiveEvictions = false, - infoAllEvictions = false, - showCallers = false, - defaultGuess) + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + infoAllEvictions = false, + showCallers = false, + defaultGuess) def default: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), + new EvictionWarningOptions( + Vector(Compile), warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, infoAllEvictions = false, showCallers = true, - defaultGuess) + defaultGuess + ) def full: EvictionWarningOptions = - new EvictionWarningOptions(Vector(Compile), + new EvictionWarningOptions( + Vector(Compile), warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, infoAllEvictions = true, showCallers = true, - defaultGuess) + defaultGuess + ) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 8daf2277a..5dd74fb6d 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -26,8 +26,7 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "print out message about the eviction" in javaLibNoWarn2() """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies - """ should "be not detected as eviction" in javaLibTransitiveWarn1() - it should "be detected if it's enabled" in javaLibTransitiveWarn2() + """ should "be detected as eviction" in javaLibTransitiveWarn2() //it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() @@ -40,8 +39,7 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "print out message about the eviction" in scalaLibNoWarn2() """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies - """ should "be not detected as eviction" in scalaLibTransitiveWarn1() - it should "be detected if it's enabled" in scalaLibTransitiveWarn2() + """ should "be detected as eviction" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() def akkaActor214 = @@ -89,7 +87,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn3() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions.withShowCallers(false), report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", @@ -102,7 +100,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", @@ -134,7 +132,12 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn2() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnDirectEvictions(false), report, log).reportedEvictions should have size (0) + EvictionWarning(m, + defaultOptions + .withWarnDirectEvictions(false) + .withWarnTransitiveEvictions(false), + report, + log).reportedEvictions should have size (0) } def javaLibWarn3() = { @@ -144,8 +147,7 @@ class EvictionWarningSpec extends BaseIvySpecification { List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4", - "Run 'evicted' to see detailed eviction warnings" + "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" ) } @@ -176,25 +178,16 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) - def javaLibTransitiveWarn1() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) - } - def javaLibTransitiveWarn2() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, - defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), - report, - log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", @@ -217,8 +210,7 @@ class EvictionWarningSpec extends BaseIvySpecification { List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4", - "Run 'evicted' to see detailed eviction warnings" + "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.example:foo:0.1.0)" ) } @@ -238,25 +230,16 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) - def scalaLibTransitiveWarn1() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) - } - def scalaLibTransitiveWarn2() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnTransitiveEvictions(true), report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) } def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, - defaultOptions.withWarnTransitiveEvictions(true).withShowCallers(true), - report, - log).lines shouldBe + EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", From 182b50a12b990ed58f1b93b629354623ddd12448 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 23 May 2017 02:42:59 -0400 Subject: [PATCH 0620/1030] Improve the eviction warning presentation. Fixes sbt/sbt#2699 Before: [warn] There may be incompatibilities among your library dependencies. [warn] Here are some of the libraries that were evicted: [warn] * com.google.code.findbugs:jsr305:2.0.1 -> 3.0.0 [warn] Run 'evicted' to see detailed eviction warnings After: [warn] Found version conflict(s) in library dependencies; some are suspected to be binary incompatible: [warn] [warn] * com.typesafe.akka:akka-actor_2.12:2.5.0 is selected over 2.4.17 [warn] +- de.heikoseeberger:akka-log4j_2.12:1.4.0 (depends on 2.5.0) [warn] +- com.typesafe.akka:akka-parsing_2.12:10.0.6 (depends on 2.4.17) [warn] +- com.typesafe.akka:akka-stream_2.12:2.4.17 () (depends on 2.4.17) [warn] [warn] Run 'evicted' to see detailed eviction warnings --- .../librarymanagement/EvictionWarning.scala | 37 ++++++++------ .../src/test/scala/EvictionWarningSpec.scala | 49 +++++++++++++------ 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index b0e22ce47..66e9d3185 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -143,17 +143,24 @@ final class EvictionPair private[sbt] ( object EvictionPair { implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { a: EvictionPair => val revs = a.evicteds map { _.module.revision } - val revsStr = if (revs.size <= 1) revs.mkString else "(" + revs.mkString(", ") + ")" - val winnerRev = (a.winner map { r => - val callers: String = - if (a.showCallers) - r.callers match { - case Seq() => "" - case cs => (cs map { _.caller.toString }).mkString(" (caller: ", ", ", ")") - } else "" - r.module.revision + callers - }) map { " -> " + _ } getOrElse "" - Seq(s"\t* ${a.organization}:${a.name}:${revsStr}$winnerRev") + val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") + } + } + } + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} is selected over ${revsStr}" + case _ => " is evicted completely" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") } } @@ -285,13 +292,13 @@ object EvictionWarning { } if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { - out += "There may be incompatibilities among your library dependencies." - out += "Here are some of the libraries that were evicted:" + out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" + out += "" out ++= (a.directEvictions flatMap { _.lines }) out ++= (a.transitiveEvictions flatMap { _.lines }) } - if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty && !a.options.showCallers) { + if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty) { out += "Run 'evicted' to see detailed eviction warnings" } @@ -312,6 +319,6 @@ object EvictionWarning { } } if (out.isEmpty) Nil - else List("Here are other libraries that were evicted:") ::: out.toList + else List("Here are other depedency conflicts that were resolved:", "") ::: out.toList } else Nil } diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/librarymanagement/src/test/scala/EvictionWarningSpec.scala index 5dd74fb6d..1601962d9 100644 --- a/librarymanagement/src/test/scala/EvictionWarningSpec.scala +++ b/librarymanagement/src/test/scala/EvictionWarningSpec.scala @@ -90,7 +90,8 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions.withShowCallers(false), report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "", "To force scalaVersion, add the following:", "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", "Run 'evicted' to see detailed eviction warnings" @@ -103,9 +104,13 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.2 -> 2.10.3 (caller: com.typesafe.akka:akka-actor_2.10:2.3.0, com.example:foo:0.1.0)", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", + "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", + "", "To force scalaVersion, add the following:", - "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" + "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -145,9 +150,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -156,9 +164,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -208,9 +219,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.example:foo:0.1.0)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } @@ -241,9 +255,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report, log).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Here are some of the libraries that were evicted:", - "\t* com.typesafe.akka:akka-actor_2.10:2.1.4 -> 2.3.4 (caller: com.typesafe.akka:akka-remote_2.10:2.3.4, org.w3:banana-sesame_2.10:0.4, org.w3:banana-rdf_2.10:0.4)" + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "", + "Run 'evicted' to see detailed eviction warnings" ) } } From 9d0dfce8696d1ba73d4b2e42905da9ba64927892 Mon Sep 17 00:00:00 2001 From: jvican Date: Sat, 27 May 2017 23:48:21 +0200 Subject: [PATCH 0621/1030] Move checksum to artifact This is a more elegant solution than before since module IDs can bring different artifacts (in updateClassifiers, for instance). --- .../src/main/contraband/librarymanagement.json | 6 +++--- .../scala/sbt/librarymanagement/ArtifactExtra.scala | 10 ++++++---- .../scala/sbt/librarymanagement/ModuleIDExtra.scala | 7 ++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 06dea8671..1ea41015e 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -15,7 +15,8 @@ { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, - { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" } + { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, + { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } ], "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" }, @@ -276,8 +277,7 @@ { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, - { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } + { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" } ], "toString": [ "this.toStringImpl" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 989ef8ce1..d3f7a6e7e 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -14,6 +14,7 @@ abstract class ArtifactExtra { def configurations: Vector[Configuration] def url: Option[URL] def extraAttributes: Map[String, String] + def checksum: Option[Checksum] protected[this] def copy( name: String = name, @@ -22,7 +23,8 @@ abstract class ArtifactExtra { classifier: Option[String] = classifier, configurations: Vector[Configuration] = configurations, url: Option[URL] = url, - extraAttributes: Map[String, String] = extraAttributes + extraAttributes: Map[String, String] = extraAttributes, + checksum: Option[Checksum] = checksum ): Artifact def extra(attributes: (String, String)*) = @@ -33,7 +35,7 @@ import Configurations.{ Optional, Pom, Test } abstract class ArtifactFunctions { def apply(name: String, extra: Map[String, String]): Artifact = - Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra) + Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra, None) def apply(name: String, classifier: String): Artifact = Artifact(name, DefaultType, DefaultExtension, Some(classifier), Vector.empty, None) def apply(name: String, `type`: String, extension: String): Artifact = @@ -50,6 +52,7 @@ abstract class ArtifactFunctions { Some(url) ) + private final val empty = Map.empty[String, String] def apply( name: String, `type`: String, @@ -57,8 +60,7 @@ abstract class ArtifactFunctions { classifier: Option[String], configurations: Vector[Configuration], url: Option[URL] - ): Artifact = - Artifact(name, `type`, extension, classifier, configurations, url, Map.empty[String, String]) + ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) val DefaultExtension = "jar" val DefaultType = "jar" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index e52df5a4d..5b89b5419 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -22,7 +22,6 @@ abstract class ModuleIDExtra { def extraAttributes: Map[String, String] def crossVersion: CrossVersion def branchName: Option[String] - def checksum: Option[Checksum] protected[this] def copy( organization: String = organization, @@ -37,14 +36,12 @@ abstract class ModuleIDExtra { exclusions: Vector[ExclusionRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: CrossVersion = crossVersion, - branchName: Option[String] = branchName, - checksum: Option[Checksum] = checksum + branchName: Option[String] = branchName ): ModuleID protected def toStringImpl: String = s"""$organization:$name:$revision""" + - (checksum match { case Some(s) => s": ${s.`type`} ${s.digest}"; case None => "" }) + - (configurations match { case Some(s) => ":" + s; case None => "" }) + { + (configurations match { case Some(s) => ":" + s; case None => "" }) + { val attr = attributeString if (attr == "") "" else " " + attr From 128798247cc9d2fb6e838ad330e88c9fc9a2fe6d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 30 May 2017 00:32:44 -0400 Subject: [PATCH 0622/1030] Guard ManagedChecksums setting retrieval This setting doesn't exist for ivysettings.xml, which then causes null problem. Fixes sbt/librarymanagement#110 --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index bba247e80..c81bd80a8 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -155,7 +155,10 @@ private[sbt] object ConvertResolver { /** The default implementation of converter. */ lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => - val managedChecksums = settings.getVariable(ManagedChecksums).toBoolean + val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { + case Some(x) => x.toBoolean + case _ => false + } r match { case repo: MavenRepository => { val pattern = Collections.singletonList( From 1bbc4719c68ab0eaa462bcf2404470ad23d1da67 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 9 Jun 2017 11:39:58 +0100 Subject: [PATCH 0623/1030] Cleanup CrossVersion code & tests --- .../cross/CrossVersionUtil.scala | 68 +++--- .../librarymanagement/CrossVersionExtra.scala | 19 +- .../src/test/scala/CrossVersionTest.scala | 203 +++++++++--------- 3 files changed, 139 insertions(+), 151 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index cebe00ac5..8c3bdaec0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -13,79 +13,73 @@ object CrossVersionUtil { val TransitionSbtVersion = "0.12" def isFull(s: String): Boolean = (s == trueString) || (s == fullString) + def isDisabled(s: String): Boolean = (s == falseString) || (s == noneString) || (s == disabledString) + def isBinary(s: String): Boolean = (s == binaryString) - private lazy val intPattern = """\d{1,10}""" - private lazy val basicVersion = """(""" + intPattern + """)\.(""" + intPattern + """)\.(""" + intPattern + """)""" + private val intPattern = """\d{1,10}""" + private val basicVersion = raw"""($intPattern)\.($intPattern)\.($intPattern)""" + private val ReleaseV = raw"""$basicVersion(-\d+)?""".r + private val BinCompatV = raw"""$basicVersion-bin(-.*)?""".r + private val CandidateV = raw"""$basicVersion(-RC\d+)""".r + private val NonReleaseV_1 = raw"""$basicVersion([-\w+]*)""".r + private val NonReleaseV_2 = raw"""$basicVersion(-\w+)""".r + private[sbt] val PartialVersion = raw"""($intPattern)\.($intPattern)(?:\..+)?""".r private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined /** * Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. - * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = { - val ReleaseV = (basicVersion + """(-\d+)?""").r - val CandidateV = (basicVersion + """(-RC\d+)""").r - val NonReleaseV = (basicVersion + """([-\w+]*)""").r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case CandidateV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } + private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = v match { + case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) + case CandidateV(x, y, _, _) => Some((x.toInt, y.toInt)) + case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None } + private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined /** * Returns Scala binary interface x.y API compatible with the given version string v. - * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = { - val ReleaseV = (basicVersion + """(-\d+)?""").r - val BinCompatV = (basicVersion + """-bin(-.*)?""").r - val NonReleaseV = (basicVersion + """(-\w+)""").r - v match { - case ReleaseV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case BinCompatV(x, y, z, ht) => Some((x.toInt, y.toInt)) - case NonReleaseV(x, y, z, ht) if z.toInt > 0 => Some((x.toInt, y.toInt)) - case _ => None - } + private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = v match { + case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) + case BinCompatV(x, y, _, _) => Some((x.toInt, y.toInt)) + case NonReleaseV_2(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case _ => None } - private[sbt] val PartialVersion = - ("""(""" + intPattern + """)\.(""" + intPattern + """)(?:\..+)?""").r + private[sbt] def partialVersion(s: String): Option[(Int, Int)] = s match { case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) case _ => None } - def binaryScalaVersion(full: String): String = { - val cutoff = - if (full.startsWith("0.")) - TransitionDottyVersion - else - TransitionScalaVersion + def binaryScalaVersion(full: String): String = { + val cutoff = if (full.startsWith("0.")) TransitionDottyVersion else TransitionScalaVersion binaryVersionWithApi(full, cutoff)(scalaApiVersion) } + def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) - private[sbt] def binaryVersion(full: String, cutoff: String): String = - binaryVersionWithApi(full, cutoff)(scalaApiVersion) + private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) + private[this] def binaryVersionWithApi(full: String, cutoff: String)( apiVersion: String => Option[(Int, Int)] ): String = { - def sub(major: Int, minor: Int) = major + "." + minor (apiVersion(full), partialVersion(cutoff)) match { - case (Some((major, minor)), None) => sub(major, minor) + case (Some((major, minor)), None) => s"$major.$minor" case (Some((major, minor)), Some((minMajor, minMinor))) if isNewer(major, minor, minMajor, minMinor) => - sub(major, minor) + s"$major.$minor" case _ => full } } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 29ef28327..df7278e8d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -76,8 +76,8 @@ abstract class CrossVersionFunctions { cross: Option[String => String] ): Vector[Artifact] = cross match { - case None => artifacts - case Some(is) => substituteCrossA(artifacts, cross) + case None => artifacts + case Some(_) => substituteCrossA(artifacts, cross) } private[sbt] def applyCross(s: String, fopt: Option[String => String]): String = @@ -124,18 +124,12 @@ abstract class CrossVersionFunctions { m } - @deprecated("Use CrossVersion.isScalaApiCompatible or CrossVersion.isSbtApiCompatible", "0.13.0") - def isStable(v: String): Boolean = isScalaApiCompatible(v) - - @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def selectVersion(full: String, binary: String): String = if (isStable(full)) binary else full - def isSbtApiCompatible(v: String): Boolean = CrossVersionUtil.isSbtApiCompatible(v) /** * Returns sbt binary interface x.y API compatible with the given version string v. * RCs for x.y.0 are considered API compatible. - * Compatibile versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). + * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) @@ -143,7 +137,7 @@ abstract class CrossVersionFunctions { /** * Returns Scala binary interface x.y API compatible with the given version string v. - * Compatibile versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. + * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) @@ -164,9 +158,4 @@ abstract class CrossVersionFunctions { * Full sbt versions earlier than [[sbt.librarymanagement.CrossVersion.TransitionSbtVersion]] are returned as is. */ def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) - - @deprecated("Use CrossVersion.scalaApiVersion or CrossVersion.sbtApiVersion", "0.13.0") - def binaryVersion(full: String, cutoff: String): String = - CrossVersionUtil.binaryVersion(full, cutoff) - } diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 835ad1058..c6a7107a9 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -1,156 +1,161 @@ package sbt.librarymanagement import sbt.internal.util.UnitSpec +import CrossVersion._ class CrossVersionTest extends UnitSpec { - "Cross version" should "return sbt API for xyz as None" in { - CrossVersion.sbtApiVersion("xyz") shouldBe None + "sbtApiVersion" should "for xyz return None" in { + sbtApiVersion("xyz") shouldBe None } - it should "return sbt API for 0.12 as None" in { - CrossVersion.sbtApiVersion("0.12") shouldBe None + it should "for 0.12 return None" in { + sbtApiVersion("0.12") shouldBe None } - it should "return sbt API for 0.12.0-SNAPSHOT as None" in { - CrossVersion.sbtApiVersion("0.12.0-SNAPSHOT") shouldBe None + it should "for 0.12.0-SNAPSHOT return None" in { + sbtApiVersion("0.12.0-SNAPSHOT") shouldBe None } - it should "return sbt API for 0.12.0-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0-RC1") shouldBe Some((0, 12)) + it should "for 0.12.0-RC1 return Some((0, 12))" in { + sbtApiVersion("0.12.0-RC1") shouldBe Some((0, 12)) } - it should "return sbt API for 0.12.0 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.0") shouldBe Some((0, 12)) + it should "for 0.12.0 return Some((0, 12))" in { + sbtApiVersion("0.12.0") shouldBe Some((0, 12)) } - it should "return sbt API for 0.12.1-SNAPSHOT as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-SNAPSHOT") shouldBe Some((0, 12)) + it should "for 0.12.1-SNAPSHOT return Some((0, 12))" in { + sbtApiVersion("0.12.1-SNAPSHOT") shouldBe Some((0, 12)) } - it should "return sbt API for 0.12.1-RC1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1-RC1") shouldBe Some((0, 12)) + it should "for 0.12.1-RC1 return Some((0, 12))" in { + sbtApiVersion("0.12.1-RC1") shouldBe Some((0, 12)) } - it should "return sbt API for 0.12.1 as Some((0, 12))" in { - CrossVersion.sbtApiVersion("0.12.1") shouldBe Some((0, 12)) + it should "for 0.12.1 return Some((0, 12))" in { + sbtApiVersion("0.12.1") shouldBe Some((0, 12)) } - it should "return sbt API compatibility for 0.12.0-M1 as false" in { - CrossVersion.isSbtApiCompatible("0.12.0-M1") shouldBe false + + "isSbtApiCompatible" should "for 0.12.0-M1 return false" in { + isSbtApiCompatible("0.12.0-M1") shouldBe false } - it should "return sbt API compatibility for 0.12.0-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.0-RC1") shouldBe true + it should "for 0.12.0-RC1 return true" in { + isSbtApiCompatible("0.12.0-RC1") shouldBe true } - it should "return sbt API compatibility for 0.12.1-RC1 as true" in { - CrossVersion.isSbtApiCompatible("0.12.1-RC1") shouldBe true + it should "for 0.12.1-RC1 return true" in { + isSbtApiCompatible("0.12.1-RC1") shouldBe true } - it should "return binary sbt version for 0.11.3 as 0.11.3" in { - CrossVersion.binarySbtVersion("0.11.3") shouldBe "0.11.3" + + "binarySbtVersion" should "for 0.11.3 return 0.11.3" in { + binarySbtVersion("0.11.3") shouldBe "0.11.3" } - it should "return binary sbt version for 0.12.0-M1 as 0.12.0-M1" in { - CrossVersion.binarySbtVersion("0.12.0-M1") shouldBe "0.12.0-M1" + it should "for 0.12.0-M1 return 0.12.0-M1" in { + binarySbtVersion("0.12.0-M1") shouldBe "0.12.0-M1" } - it should "return binary sbt version for 0.12.0-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0-RC1") shouldBe "0.12" + it should "for 0.12.0-RC1 return 0.12" in { + binarySbtVersion("0.12.0-RC1") shouldBe "0.12" } - it should "return binary sbt version for 0.12.0 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.0") shouldBe "0.12" + it should "for 0.12.0 return 0.12" in { + binarySbtVersion("0.12.0") shouldBe "0.12" } - it should "return binary sbt version for 0.12.1-SNAPSHOT as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-SNAPSHOT") shouldBe "0.12" + it should "for 0.12.1-SNAPSHOT return 0.12" in { + binarySbtVersion("0.12.1-SNAPSHOT") shouldBe "0.12" } - it should "return binary sbt version for 0.12.1-RC1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1-RC1") shouldBe "0.12" + it should "for 0.12.1-RC1 return 0.12" in { + binarySbtVersion("0.12.1-RC1") shouldBe "0.12" } - it should "return binary sbt version for 0.12.1 as 0.12" in { - CrossVersion.binarySbtVersion("0.12.1") shouldBe "0.12" + it should "for 0.12.1 return 0.12" in { + binarySbtVersion("0.12.1") shouldBe "0.12" } - it should "return Scala API for xyz as None" in { - CrossVersion.scalaApiVersion("xyz") shouldBe None + + "scalaApiVersion" should "for xyz return None" in { + scalaApiVersion("xyz") shouldBe None } - it should "return Scala API for 2.10 as None" in { - CrossVersion.scalaApiVersion("2.10") shouldBe None + it should "for 2.10 return None" in { + scalaApiVersion("2.10") shouldBe None } - it should "return Scala API for 2.10.0-SNAPSHOT as None" in { - CrossVersion.scalaApiVersion("2.10.0-SNAPSHOT") shouldBe None + it should "for 2.10.0-SNAPSHOT return None" in { + scalaApiVersion("2.10.0-SNAPSHOT") shouldBe None } - it should "return Scala API for 2.10.0-RC1 as None" in { - CrossVersion.scalaApiVersion("2.10.0-RC1") shouldBe None + it should "for 2.10.0-RC1 return None" in { + scalaApiVersion("2.10.0-RC1") shouldBe None } - it should "return Scala API for 2.10.0 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0") shouldBe Some((2, 10)) + it should "for 2.10.0 return Some((2, 10))" in { + scalaApiVersion("2.10.0") shouldBe Some((2, 10)) } - it should "return Scala API for 2.10.0-1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.0-1") shouldBe Some((2, 10)) + it should "for 2.10.0-1 return Some((2, 10))" in { + scalaApiVersion("2.10.0-1") shouldBe Some((2, 10)) } - it should "return Scala API for 2.10.1-SNAPSHOT as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-SNAPSHOT") shouldBe Some((2, 10)) + it should "for 2.10.1-SNAPSHOT return Some((2, 10))" in { + scalaApiVersion("2.10.1-SNAPSHOT") shouldBe Some((2, 10)) } - it should "return Scala API for 2.10.1-RC1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1-RC1") shouldBe Some((2, 10)) + it should "for 2.10.1-RC1 return Some((2, 10))" in { + scalaApiVersion("2.10.1-RC1") shouldBe Some((2, 10)) } - it should "return Scala API for 2.10.1 as Some((2, 10))" in { - CrossVersion.scalaApiVersion("2.10.1") shouldBe Some((2, 10)) + it should "for 2.10.1 return Some((2, 10))" in { + scalaApiVersion("2.10.1") shouldBe Some((2, 10)) } - it should "return Scala API compatibility for 2.10.0-M1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-M1") shouldBe false + + "isScalaApiCompatible" should "for 2.10.0-M1 return false" in { + isScalaApiCompatible("2.10.0-M1") shouldBe false } - it should "return Scala API compatibility for 2.10.0-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.0-RC1") shouldBe false + it should "for 2.10.0-RC1 return false" in { + isScalaApiCompatible("2.10.0-RC1") shouldBe false } - it should "return Scala API compatibility for 2.10.1-RC1 as false" in { - CrossVersion.isScalaApiCompatible("2.10.1-RC1") shouldBe true + it should "for 2.10.1-RC1 return false" in { + isScalaApiCompatible("2.10.1-RC1") shouldBe true } - it should "return binary Scala version for 2.9.2 as 2.9.2" in { - CrossVersion.binaryScalaVersion("2.9.2") shouldBe "2.9.2" + + "binaryScalaVersion" should "for 2.9.2 return 2.9.2" in { + binaryScalaVersion("2.9.2") shouldBe "2.9.2" } - it should "return binary Scala version for 2.10.0-M1 as 2.10.0-M1" in { - CrossVersion.binaryScalaVersion("2.10.0-M1") shouldBe "2.10.0-M1" + it should "for 2.10.0-M1 return 2.10.0-M1" in { + binaryScalaVersion("2.10.0-M1") shouldBe "2.10.0-M1" } - it should "return binary Scala version for 2.10.0-RC1 as 2.10.0-RC1" in { - CrossVersion.binaryScalaVersion("2.10.0-RC1") shouldBe "2.10.0-RC1" + it should "for 2.10.0-RC1 return 2.10.0-RC1" in { + binaryScalaVersion("2.10.0-RC1") shouldBe "2.10.0-RC1" } - it should "return binary Scala version for 2.10.0 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.0") shouldBe "2.10" + it should "for 2.10.0 return 2.10" in { + binaryScalaVersion("2.10.0") shouldBe "2.10" } - it should "return binary Scala version for 2.10.1-M1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-M1") shouldBe "2.10" + it should "for 2.10.1-M1 return 2.10" in { + binaryScalaVersion("2.10.1-M1") shouldBe "2.10" } - it should "return binary Scala version for 2.10.1-RC1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1-RC1") shouldBe "2.10" + it should "for 2.10.1-RC1 return 2.10" in { + binaryScalaVersion("2.10.1-RC1") shouldBe "2.10" } - it should "return binary Scala version for 2.10.1 as 2.10" in { - CrossVersion.binaryScalaVersion("2.10.1") shouldBe "2.10" + it should "for 2.10.1 return 2.10" in { + binaryScalaVersion("2.10.1") shouldBe "2.10" } - it should "return binary Scala version for 2.20170314093845.0-87654321 as 2.20170314093845.0-87654321" in { - CrossVersion.binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" + it should "for 2.20170314093845.0-87654321 return 2.20170314093845.0-87654321" in { + binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" } - it should "return binary Scala version for Dotty 0.1.1 as 0.1" in { - CrossVersion.binaryScalaVersion("0.1.1") shouldBe "0.1" + it should "for Dotty 0.1.1 return 0.1" in { + binaryScalaVersion("0.1.1") shouldBe "0.1" } - it should "return patch Scala version for 2.11.8 as 2.11.8" in { - CrossVersion(CrossVersion.patch, "2.11.8", "dummy").map(_("artefact")) shouldBe Some( - "artefact_2.11.8") + + private def patchVersion(fullVersion: String) = + CrossVersion(CrossVersion.patch, fullVersion, "dummy") map (fn => fn("artefact")) + + "CrossVersion.patch" should "for 2.11.8 return 2.11.8" in { + patchVersion("2.11.8") shouldBe Some("artefact_2.11.8") } - it should "return patch Scala version for 2.11.8-M1 as 2.11.8-M1" in { - CrossVersion(CrossVersion.patch, "2.11.8-M1", "dummy").map(_("artefact")) shouldBe Some( - "artefact_2.11.8-M1") + it should "for 2.11.8-M1 return 2.11.8-M1" in { + patchVersion("2.11.8-M1") shouldBe Some("artefact_2.11.8-M1") } - it should "return patch Scala version for 2.11.8-RC1 as 2.11.8-RC1" in { - CrossVersion(CrossVersion.patch, "2.11.8-RC1", "dummy").map(_("artefact")) shouldBe Some( - "artefact_2.11.8-RC1") + it should "for 2.11.8-RC1 return 2.11.8-RC1" in { + patchVersion("2.11.8-RC1") shouldBe Some("artefact_2.11.8-RC1") } - it should "return patch Scala version for 2.11.8-bin-extra as 2.11.8" in { - CrossVersion(CrossVersion.patch, "2.11.8-bin-extra", "dummy").map(_("artefact")) shouldBe Some( - "artefact_2.11.8") + it should "for 2.11.8-bin-extra return 2.11.8" in { + patchVersion("2.11.8-bin-extra") shouldBe Some("artefact_2.11.8") } - it should "return patch Scala version for 2.11.8-M1-bin-extra as 2.11.8-M1" in { - CrossVersion(CrossVersion.patch, "2.11.8-M1-bin-extra", "dummy") - .map(_("artefact")) shouldBe Some("artefact_2.11.8-M1") + it should "for 2.11.8-M1-bin-extra return 2.11.8-M1" in { + patchVersion("2.11.8-M1-bin-extra") shouldBe Some("artefact_2.11.8-M1") } - it should "return patch Scala version for 2.11.8-RC1-bin-extra as 2.11.8-RC1" in { - CrossVersion(CrossVersion.patch, "2.11.8-RC1-bin-extra", "dummy") - .map(_("artefact")) shouldBe Some("artefact_2.11.8-RC1") + it should "for 2.11.8-RC1-bin-extra return 2.11.8-RC1" in { + patchVersion("2.11.8-RC1-bin-extra") shouldBe Some("artefact_2.11.8-RC1") } - it should "return disabled cross version as equal to a copy" in { + + "Disabled" should "have structural equality" in { Disabled() shouldBe Disabled() } - it should "return full cross version as equal to a copy" in { + "CrossVersion.full" should "have structural equality" in { CrossVersion.full shouldBe CrossVersion.full } - it should "return binary cross version as equal to a copy" in { + "CrossVersion.binary" should "have structural equality" in { CrossVersion.binary shouldBe CrossVersion.binary } } From f98ee86668d7065ffb49d541e81e303558cd6229 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 9 Jun 2017 11:49:12 +0100 Subject: [PATCH 0624/1030] Clarify NonRelease variants in CrossVersion --- .../librarymanagement/cross/CrossVersionUtil.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 8c3bdaec0..e2b9999fb 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -24,8 +24,8 @@ object CrossVersionUtil { private val ReleaseV = raw"""$basicVersion(-\d+)?""".r private val BinCompatV = raw"""$basicVersion-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r - private val NonReleaseV_1 = raw"""$basicVersion([-\w+]*)""".r - private val NonReleaseV_2 = raw"""$basicVersion(-\w+)""".r + private val NonReleaseV_n = raw"""$basicVersion([-\w]*)""".r // 0-n word suffixes, with leading dashes + private val NonReleaseV_1 = raw"""$basicVersion(-\w+)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($intPattern)\.($intPattern)(?:\..+)?""".r private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined @@ -38,7 +38,7 @@ object CrossVersionUtil { private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = v match { case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) case CandidateV(x, y, _, _) => Some((x.toInt, y.toInt)) - case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) case _ => None } @@ -51,7 +51,7 @@ object CrossVersionUtil { private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = v match { case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) case BinCompatV(x, y, _, _) => Some((x.toInt, y.toInt)) - case NonReleaseV_2(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) case _ => None } From 039e2e6b6ac3c8bd88bb140b6c77d3ef79135a17 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 9 Jun 2017 12:17:02 +0100 Subject: [PATCH 0625/1030] Change the sbt API/binary version for sbt 1.x to be 1.0 --- .../cross/CrossVersionUtil.scala | 14 +++- .../src/test/scala/CrossVersionTest.scala | 81 +++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index e2b9999fb..26ea94460 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -36,12 +36,20 @@ object CrossVersionUtil { * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = v match { - case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) - case CandidateV(x, y, _, _) => Some((x.toInt, y.toInt)) - case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toInt, y.toInt)) + case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toInt, y.toInt)) + case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some(sbtApiVersion(x.toInt, y.toInt)) case _ => None } + private def sbtApiVersion(x: Int, y: Int) = { + // Prior to sbt 1 the "sbt api version" was the X.Y in the X.Y.Z version. + // For example for sbt 0.13.x releases, the sbt api version is 0.13 + // As of sbt 1 it is now X.0. + // This means, for example, that all versions of sbt 1.x have sbt api version 1.0 + if (x > 0) (x, 0) else (x, y) + } + private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined /** diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index c6a7107a9..5db072909 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -28,6 +28,33 @@ class CrossVersionTest extends UnitSpec { it should "for 0.12.1 return Some((0, 12))" in { sbtApiVersion("0.12.1") shouldBe Some((0, 12)) } + it should "for 1.0.0-M6 return None" in { + sbtApiVersion("1.0.0-M6") shouldBe None + } + it should "for 1.0.0-RC1 return Some((1, 0))" in { + sbtApiVersion("1.0.0-RC1") shouldBe Some((1, 0)) + } + it should "for 1.0.0 return Some((1, 0))" in { + sbtApiVersion("1.0.0") shouldBe Some((1, 0)) + } + it should "for 1.0.2-M1 return Some((1, 0))" in { + sbtApiVersion("1.0.2-M1") shouldBe Some((1, 0)) + } + it should "for 1.0.2-RC1 return Some((1, 0))" in { + sbtApiVersion("1.0.2-RC1") shouldBe Some((1, 0)) + } + it should "for 1.0.2 return Some((1, 0))" in { + sbtApiVersion("1.0.2") shouldBe Some((1, 0)) + } + it should "for 1.3.0 return Some((1, 0))" in { + sbtApiVersion("1.3.0") shouldBe Some((1, 0)) + } + it should "for 1.10.0 return Some((1, 0))" in { + sbtApiVersion("1.10.0") shouldBe Some((1, 0)) + } + it should "for 2.0.0 return Some((2, 0))" in { + sbtApiVersion("2.0.0") shouldBe Some((2, 0)) + } "isSbtApiCompatible" should "for 0.12.0-M1 return false" in { isSbtApiCompatible("0.12.0-M1") shouldBe false @@ -38,6 +65,33 @@ class CrossVersionTest extends UnitSpec { it should "for 0.12.1-RC1 return true" in { isSbtApiCompatible("0.12.1-RC1") shouldBe true } + it should "for 1.0.0-M6 return false" in { + isSbtApiCompatible("1.0.0-M6") shouldBe false + } + it should "for 1.0.0-RC1 return true" in { + isSbtApiCompatible("1.0.0-RC1") shouldBe true + } + it should "for 1.0.0 return true" in { + isSbtApiCompatible("1.0.0") shouldBe true + } + it should "for 1.0.2-M1 return true" in { + isSbtApiCompatible("1.0.2-M1") shouldBe true + } + it should "for 1.0.2-RC1 return true" in { + isSbtApiCompatible("1.0.2-RC1") shouldBe true + } + it should "for 1.0.2 return true" in { + isSbtApiCompatible("1.0.2") shouldBe true + } + it should "for 1.3.0 return true" in { + isSbtApiCompatible("1.3.0") shouldBe true + } + it should "for 1.10.0 return true" in { + isSbtApiCompatible("1.10.0") shouldBe true + } + it should "for 2.0.0 return true" in { + isSbtApiCompatible("2.0.0") shouldBe true + } "binarySbtVersion" should "for 0.11.3 return 0.11.3" in { binarySbtVersion("0.11.3") shouldBe "0.11.3" @@ -60,6 +114,33 @@ class CrossVersionTest extends UnitSpec { it should "for 0.12.1 return 0.12" in { binarySbtVersion("0.12.1") shouldBe "0.12" } + it should "for 1.0.0-M6 return 1.0.0-M6" in { + binarySbtVersion("1.0.0-M6") shouldBe "1.0.0-M6" + } + it should "for 1.0.0-RC1 return 1.0" in { + binarySbtVersion("1.0.0-RC1") shouldBe "1.0" + } + it should "for 1.0.0 return 1.0" in { + binarySbtVersion("1.0.0") shouldBe "1.0" + } + it should "for 1.0.2-M1 return 1.0" in { + binarySbtVersion("1.0.2-M1") shouldBe "1.0" + } + it should "for 1.0.2-RC1 return 1.0" in { + binarySbtVersion("1.0.2-RC1") shouldBe "1.0" + } + it should "for 1.0.2 return 1.0" in { + binarySbtVersion("1.0.2") shouldBe "1.0" + } + it should "for 1.3.0 return 1.0" in { + binarySbtVersion("1.3.0") shouldBe "1.0" + } + it should "for 1.10.0 return 1.0" in { + binarySbtVersion("1.10.0") shouldBe "1.0" + } + it should "for 2.0.0 return 2.0" in { + binarySbtVersion("2.0.0") shouldBe "2.0" + } "scalaApiVersion" should "for xyz return None" in { scalaApiVersion("xyz") shouldBe None From e45d9a254b1cd1e1173b57d2d215958bd8489225 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 9 Jun 2017 15:36:06 +0100 Subject: [PATCH 0626/1030] Switch version patterns to Long instead of Int For sbt/sbt#3011 reasons. --- .../cross/CrossVersionUtil.scala | 34 +++++++++---------- .../librarymanagement/CrossVersionExtra.scala | 6 ++-- .../src/test/scala/CrossVersionTest.scala | 4 +-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 26ea94460..b9d4cc2dd 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -19,14 +19,14 @@ object CrossVersionUtil { def isBinary(s: String): Boolean = (s == binaryString) - private val intPattern = """\d{1,10}""" - private val basicVersion = raw"""($intPattern)\.($intPattern)\.($intPattern)""" + private val longPattern = """\d{1,19}""" + private val basicVersion = raw"""($longPattern)\.($longPattern)\.($longPattern)""" private val ReleaseV = raw"""$basicVersion(-\d+)?""".r private val BinCompatV = raw"""$basicVersion-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r private val NonReleaseV_n = raw"""$basicVersion([-\w]*)""".r // 0-n word suffixes, with leading dashes private val NonReleaseV_1 = raw"""$basicVersion(-\w+)""".r // 1 word suffix, after a dash - private[sbt] val PartialVersion = raw"""($intPattern)\.($intPattern)(?:\..+)?""".r + private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined @@ -35,19 +35,19 @@ object CrossVersionUtil { * RCs for x.y.0 are considered API compatible. * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - private[sbt] def sbtApiVersion(v: String): Option[(Int, Int)] = v match { - case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toInt, y.toInt)) - case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toInt, y.toInt)) - case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some(sbtApiVersion(x.toInt, y.toInt)) + private[sbt] def sbtApiVersion(v: String): Option[(Long, Long)] = v match { + case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some(sbtApiVersion(x.toLong, y.toLong)) case _ => None } - private def sbtApiVersion(x: Int, y: Int) = { + private def sbtApiVersion(x: Long, y: Long) = { // Prior to sbt 1 the "sbt api version" was the X.Y in the X.Y.Z version. // For example for sbt 0.13.x releases, the sbt api version is 0.13 // As of sbt 1 it is now X.0. // This means, for example, that all versions of sbt 1.x have sbt api version 1.0 - if (x > 0) (x, 0) else (x, y) + if (x > 0) (x, 0L) else (x, y) } private[sbt] def isScalaApiCompatible(v: String): Boolean = scalaApiVersion(v).isDefined @@ -56,16 +56,16 @@ object CrossVersionUtil { * Returns Scala binary interface x.y API compatible with the given version string v. * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - private[sbt] def scalaApiVersion(v: String): Option[(Int, Int)] = v match { - case ReleaseV(x, y, _, _) => Some((x.toInt, y.toInt)) - case BinCompatV(x, y, _, _) => Some((x.toInt, y.toInt)) - case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toInt, y.toInt)) + private[sbt] def scalaApiVersion(v: String): Option[(Long, Long)] = v match { + case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) + case BinCompatV(x, y, _, _) => Some((x.toLong, y.toLong)) + case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toLong, y.toLong)) case _ => None } - private[sbt] def partialVersion(s: String): Option[(Int, Int)] = + private[sbt] def partialVersion(s: String): Option[(Long, Long)] = s match { - case PartialVersion(major, minor) => Some((major.toInt, minor.toInt)) + case PartialVersion(major, minor) => Some((major.toLong, minor.toLong)) case _ => None } @@ -77,11 +77,11 @@ object CrossVersionUtil { def binarySbtVersion(full: String): String = binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) - private[this] def isNewer(major: Int, minor: Int, minMajor: Int, minMinor: Int): Boolean = + private[this] def isNewer(major: Long, minor: Long, minMajor: Long, minMinor: Long): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) private[this] def binaryVersionWithApi(full: String, cutoff: String)( - apiVersion: String => Option[(Int, Int)] + apiVersion: String => Option[(Long, Long)] ): String = { (apiVersion(full), partialVersion(cutoff)) match { case (Some((major, minor)), None) => s"$major.$minor" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index df7278e8d..c7e8fecc8 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -131,7 +131,7 @@ abstract class CrossVersionFunctions { * RCs for x.y.0 are considered API compatible. * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ - def sbtApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.sbtApiVersion(v) + def sbtApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.sbtApiVersion(v) def isScalaApiCompatible(v: String): Boolean = CrossVersionUtil.isScalaApiCompatible(v) @@ -139,13 +139,13 @@ abstract class CrossVersionFunctions { * Returns Scala binary interface x.y API compatible with the given version string v. * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ - def scalaApiVersion(v: String): Option[(Int, Int)] = CrossVersionUtil.scalaApiVersion(v) + def scalaApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.scalaApiVersion(v) /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ val PartialVersion = CrossVersionUtil.PartialVersion /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ - def partialVersion(s: String): Option[(Int, Int)] = CrossVersionUtil.partialVersion(s) + def partialVersion(s: String): Option[(Long, Long)] = CrossVersionUtil.partialVersion(s) /** * Computes the binary Scala version from the `full` version. diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 5db072909..b65c9a11b 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -201,8 +201,8 @@ class CrossVersionTest extends UnitSpec { it should "for 2.10.1 return 2.10" in { binaryScalaVersion("2.10.1") shouldBe "2.10" } - it should "for 2.20170314093845.0-87654321 return 2.20170314093845.0-87654321" in { - binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845.0-87654321" + it should "for 2.20170314093845.0-87654321 return 2.20170314093845" in { + binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845" } it should "for Dotty 0.1.1 return 0.1" in { binaryScalaVersion("0.1.1") shouldBe "0.1" From 60e1eb6275f5ca8ee35a8728989b49d1d5995a4d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 14 Jun 2017 01:56:08 -0400 Subject: [PATCH 0627/1030] Bump to sbt 1.0.0-M6 --- .travis.yml | 2 +- build.sbt | 32 ++++----- .../internal/librarymanagement/IvyUtil.scala | 2 +- project/AutomateScalafmtPlugin.scala | 66 ------------------- project/Dependencies.scala | 6 +- project/Util.scala | 8 ++- project/build.properties | 2 +- project/plugins.sbt | 9 ++- 8 files changed, 32 insertions(+), 95 deletions(-) delete mode 100644 project/AutomateScalafmtPlugin.scala diff --git a/.travis.yml b/.travis.yml index 535d8f33c..dc51710ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ scala: - 2.12.1 script: - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmtCheck" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" jdk: - oraclejdk8 diff --git a/build.sbt b/build.sbt index 97cf4a78e..d949c1797 100644 --- a/build.sbt +++ b/build.sbt @@ -1,5 +1,7 @@ import Dependencies._ -import com.typesafe.tools.mima.core._, ProblemFilters._ +import Path._ + +// import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "1.0.0" @@ -12,26 +14,24 @@ def commonSettings: Seq[Setting[_]] = Seq( // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), - incOptions := incOptions.value.withNameHashing(true), crossScalaVersions := Seq(scala211, scala212), resolvers += Resolver.sonatypeRepo("public"), - scalacOptions += "-Ywarn-unused", - mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), + scalacOptions := { + val old = scalacOptions.value + scalaVersion.value match { + case sv if sv.startsWith("2.10") => old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") + case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") + case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + } + }, + // mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false, - parallelExecution in Test := false, - commands += Command.command("scalafmtCheck") { state => - sys.process.Process("git diff --name-only --exit-code").! match { - case 0 => // ok - case x => sys.error("git diff detected! Did you compile before committing?") - } - state - } + parallelExecution in Test := false ) lazy val lmRoot = (project in file(".")) .aggregate(lm) - .disablePlugins(com.typesafe.sbt.SbtScalariform) .settings( inThisBuild( Seq( @@ -40,6 +40,9 @@ lazy val lmRoot = (project in file(".")) scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git")), bintrayPackage := "librarymanagement", + scalafmtOnCompile := true, + // scalafmtVersion 1.0.0-RC3 has regression + scalafmtVersion := "0.6.8", git.baseVersion := baseVersion )), commonSettings, @@ -52,7 +55,6 @@ lazy val lmRoot = (project in file(".")) ) lazy val lm = (project in file("librarymanagement")) - .disablePlugins(com.typesafe.sbt.SbtScalariform) .settings( commonSettings, name := "librarymanagement", @@ -71,7 +73,7 @@ lazy val lm = (project in file("librarymanagement")) streams.value, (compile in Compile).value)) .taskValue, - mimaBinaryIssueFilters ++= Seq(), + // mimaBinaryIssueFilters ++= Seq(), contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc mappings in (Compile, packageSrc) ++= { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala index d9477b9cc..6c4622d90 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala @@ -3,4 +3,4 @@ package sbt.internal.librarymanagement private[sbt] object IvyUtil { def separate[A, B](l: Seq[Either[A, B]]): (Seq[A], Seq[B]) = (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) -} \ No newline at end of file +} diff --git a/project/AutomateScalafmtPlugin.scala b/project/AutomateScalafmtPlugin.scala deleted file mode 100644 index 28e0c04d8..000000000 --- a/project/AutomateScalafmtPlugin.scala +++ /dev/null @@ -1,66 +0,0 @@ -import org.scalafmt.bootstrap.ScalafmtBootstrap -import org.scalafmt.sbt.ScalafmtPlugin -import sbt._ -import sbt.Keys._ -import sbt.inc.Analysis - -// Taken from https://github.com/akka/alpakka/blob/master/project/AutomateScalafmtPlugin.scala -object AutomateScalafmtPlugin extends AutoPlugin { - object autoImport { - def automateScalafmtFor(configurations: Configuration*): Seq[Setting[_]] = - configurations.flatMap { c => - inConfig(c)( - Seq( - compileInputs.in(compile) := { - scalafmtInc.value - compileInputs.in(compile).value - }, - sourceDirectories.in(scalafmtInc) := Seq(scalaSource.value), - scalafmtInc := { - val cache = streams.value.cacheDirectory / "scalafmt" - val include = includeFilter.in(scalafmtInc).value - val exclude = excludeFilter.in(scalafmtInc).value - val sources = - sourceDirectories - .in(scalafmtInc) - .value - .descendantsExcept(include, exclude) - .get - .toSet - def format(handler: Set[File] => Unit, msg: String) = { - def update(handler: Set[File] => Unit, msg: String)(in: ChangeReport[File], - out: ChangeReport[File]) = { - val label = Reference.display(thisProjectRef.value) - val files = in.modified -- in.removed - Analysis - .counted("Scala source", "", "s", files.size) - .foreach(count => streams.value.log.info(s"$msg $count in $label ...")) - handler(files) - files - } - FileFunction.cached(cache)(FilesInfo.hash, FilesInfo.exists)(update(handler, msg))( - sources - ) - } - def formattingHandler(files: Set[File]) = - if (files.nonEmpty) { - val filesArg = files.map(_.getAbsolutePath).mkString(",") - ScalafmtBootstrap.main(List("--quiet", "-i", "-f", filesArg)) - } - format(formattingHandler, "Formatting") - format(_ => (), "Reformatted") // Recalculate the cache - } - ) - ) - } - } - - private val scalafmtInc = taskKey[Unit]("Incrementally format modified sources") - - override def requires = ScalafmtPlugin - - override def trigger = allRequirements - - override def projectSettings = - (includeFilter.in(scalafmtInc) := "*.scala") +: autoImport.automateScalafmtFor(Compile, Test) -} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e5be5fa54..561601327 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -2,8 +2,8 @@ import sbt._ import Keys._ object Dependencies { - val scala211 = "2.11.8" - val scala212 = "2.12.1" + val scala211 = "2.11.11" + val scala212 = "2.12.2" private val ioVersion = "1.0.0-M11" private val utilVersion = "1.0.0-M23" @@ -34,7 +34,7 @@ object Dependencies { c: Option[Configuration] = None) = path match { case Some(f) => - p dependsOn c.fold[ClasspathDependency](ProjectRef(file(f), projectName))( + p dependsOn c.fold[ClasspathDep[ProjectReference]](ProjectRef(file(f), projectName))( ProjectRef(file(f), projectName) % _) case None => p settings (libraryDependencies += c.fold(m)(m % _)) } diff --git a/project/Util.scala b/project/Util.scala index 2b8dccaf2..62be2772b 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -3,21 +3,23 @@ import Keys._ import sbt.IO import java.io.File +import xsbti.compile.CompileAnalysis object Util { def versionLine(version: String): String = "version=" + version def containsVersion(propFile: File, version: String): Boolean = IO.read(propFile).contains(versionLine(version)) - def lastCompilationTime(analysis: sbt.inc.Analysis): Long = { + def lastCompilationTime(analysis0: CompileAnalysis): Long = { + val analysis = analysis0 match { case a: sbt.internal.inc.Analysis => a } val lastCompilation = analysis.compilations.allCompilations.lastOption - lastCompilation.map(_.startTime) getOrElse 0L + lastCompilation.map(_.getStartTime) getOrElse 0L } def generateVersionFile(version: String, dir: File, s: TaskStreams, - analysis: sbt.inc.Analysis): Seq[File] = { + analysis: CompileAnalysis): Seq[File] = { import java.util.{ Date, TimeZone } val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") formatter.setTimeZone(TimeZone.getTimeZone("GMT")) diff --git a/project/build.properties b/project/build.properties index 64317fdae..cd66fd542 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.15 +sbt.version=1.0.0-M6 diff --git a/project/plugins.sbt b/project/plugins.sbt index 1392d8889..64f6761ab 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,6 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.2") -addSbtPlugin("com.eed3si9n" % "sbt-doge" % "0.1.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M4") -addSbtPlugin("me.lessis" % "bintray-sbt" % "0.3.0") -addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "0.6.8") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M5") +addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0") +addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") scalacOptions += "-language:postfixOps" From aaf471dd36447f52ead4f334a10eb2a79cdc1914 Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Fri, 23 Jun 2017 16:24:47 +0200 Subject: [PATCH 0628/1030] Add constant CrossVersion sbt 1 removes CrossVersion.binaryMapped which was used in the sbt-dotty plugin to provide a way to depend on Scala 2.x artifacts in a project that cross-compiles between Scala 2.x and Dotty (see `withDottyCompat()` in https://github.com/lampepfl/dotty/blob/master/sbt-dotty/src/dotty/tools/sbtplugin/DottyPlugin.scala). Using `binaryWith` is not enough because it only allows the user to specify a prefix and a suffix for the binary version which will always be set to `scalaBinaryVersion`. This commit introduces a new `Constant` kind of CrossVersion which allows the user to specify any string he wants as a cross-version, thus making it possible to port `withDottyCompat()` to sbt 1. --- .../src/main/contraband/librarymanagement.json | 12 ++++++++++++ .../sbt/librarymanagement/CrossVersionExtra.scala | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 1ea41015e..71b18d691 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -150,6 +150,18 @@ { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } ] }, + { + "name": "Constant", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "doc": [ + "Cross-versions a module using the string `value`." + ], + "type": "record", + "fields": [ + { "name": "value", "type": "String", "default": "\"\"", "since": "0.0.2" } + ] + }, { "name": "Patch", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index c7e8fecc8..b556a8a50 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -24,6 +24,9 @@ abstract class CrossVersionFunctions { /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() + /** Cross-versions a module with a constant string (typically the binary Scala version). */ + def constant(value: String): CrossVersion = Constant(value) + /** * Cross-versions a module with the result of prepending `prefix` and appending `suffix` to the binary version * (typically the binary Scala version). See also [[sbt.librarymanagement.Binary]]. @@ -58,6 +61,7 @@ abstract class CrossVersionFunctions { cross match { case _: Disabled => None case b: Binary => append(b.prefix + binaryVersion + b.suffix) + case c: Constant => append(c.value) case _: Patch => append(patchFun(fullVersion)) case f: Full => append(f.prefix + fullVersion + f.suffix) } From f325d466deada6f114e6ff056f47952481bca84f Mon Sep 17 00:00:00 2001 From: Guillaume Martres Date: Fri, 23 Jun 2017 16:49:10 +0200 Subject: [PATCH 0629/1030] Add tests for CrossVersion.constant --- .../src/test/scala/CrossVersionTest.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index b65c9a11b..376a17cb1 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -230,6 +230,13 @@ class CrossVersionTest extends UnitSpec { patchVersion("2.11.8-RC1-bin-extra") shouldBe Some("artefact_2.11.8-RC1") } + private def constantVersion(value: String) = + CrossVersion(CrossVersion.constant(value), "dummy1", "dummy2") map (fn => fn("artefact")) + + "CrossVersion.constant" should "add a constant to the version" in { + constantVersion("duck") shouldBe Some("artefact_duck") + } + "Disabled" should "have structural equality" in { Disabled() shouldBe Disabled() } @@ -239,4 +246,7 @@ class CrossVersionTest extends UnitSpec { "CrossVersion.binary" should "have structural equality" in { CrossVersion.binary shouldBe CrossVersion.binary } + "CrossVersion.constant" should "have structural equality" in { + CrossVersion.constant("duck") shouldBe CrossVersion.constant("duck") + } } From 31d519a003a218f023fe51cde25c5708efe895e2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 30 Jun 2017 04:25:48 -0400 Subject: [PATCH 0630/1030] Fix toString --- .../scala/sbt/librarymanagement/UpdateOptions.scala | 1 - .../src/test/scala/UpdateOptionsSpec.scala | 13 +++++-------- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala index 34f4a8873..bafbc3e4c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala @@ -71,7 +71,6 @@ final class UpdateOptions private[sbt] ( s"""UpdateOptions( | circularDependencyLevel = $circularDependencyLevel, | latestSnapshots = $latestSnapshots, - | consolidatedResolution = $consolidatedResolution, | cachedResolution = $cachedResolution |)""".stripMargin diff --git a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala index c347ef0e6..8a152bb13 100644 --- a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala +++ b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala @@ -5,22 +5,19 @@ import sbt.internal.util.UnitSpec class UpdateOptionsSpec extends UnitSpec { "UpdateOptions" should "have proper toString defined" in { - UpdateOptions().toString() should be( - """|UpdateOptions( + UpdateOptions().toString() should be("""|UpdateOptions( | circularDependencyLevel = warn, - | latestSnapshots = false, - | consolidatedResolution = false, + | latestSnapshots = true, | cachedResolution = false |)""".stripMargin) UpdateOptions() .withCircularDependencyLevel(CircularDependencyLevel.Error) .withCachedResolution(true) - .withLatestSnapshots(true).toString() should be( - """|UpdateOptions( + .withLatestSnapshots(false) + .toString() should be("""|UpdateOptions( | circularDependencyLevel = error, - | latestSnapshots = true, - | consolidatedResolution = false, + | latestSnapshots = false, | cachedResolution = true |)""".stripMargin) } From 9d9e8112dfc60bb0c520fc9eb7f164be995cf21b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 30 Jun 2017 14:55:08 +0100 Subject: [PATCH 0631/1030] Add CrossVersion val/type compat aliases & .disabled To ease migrating code from sbt 0.13 to sbt 1 this introduces val and type aliases to CrossVersion's companion object (via CrossVersionFunctions). In addition, for consistency, it introduces CrossVersion.disabled. --- .../sbt/librarymanagement/CrossVersionExtra.scala | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index b556a8a50..0273a2930 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -5,6 +5,14 @@ import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) abstract class CrossVersionFunctions { + /** Compatibility with 0.13 */ + final val Disabled = sbt.librarymanagement.Disabled + final val Binary = sbt.librarymanagement.Binary + final val Full = sbt.librarymanagement.Full + final val Patch = sbt.librarymanagement.Patch + type Binary = sbt.librarymanagement.Binary + type Full = sbt.librarymanagement.Full + type Patch = sbt.librarymanagement.Patch /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion @@ -24,6 +32,9 @@ abstract class CrossVersionFunctions { /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() + /** Disables cross versioning for a module. */ + def disabled: CrossVersion = Disabled() + /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) From e4c1a1c5594001452ee8e171c5fdf493b8b24ce6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Jun 2017 01:58:38 -0400 Subject: [PATCH 0632/1030] Adjust to util bump --- .../sbt/internal/librarymanagement/formats/NodeSeqFormat.scala | 2 +- .../librarymanagement/formats/UpdateOptionsFormat.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala index fbc99e9b9..2a81aa37b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala @@ -4,7 +4,7 @@ import sjsonnew._ import scala.xml._ trait NodeSeqFormat { self: BasicJsonProtocol => - implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = project[NodeSeq, String]( + implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = projectFormat[NodeSeq, String]( xml => { xml }.toString, str => XML.loadString(str).child ) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala index 147e53b80..c948a12c1 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala @@ -18,7 +18,7 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re } implicit lazy val UpdateOptionsFormat: JsonFormat[UpdateOptions] = - project( + projectFormat( (uo: UpdateOptions) => ( uo.circularDependencyLevel.name, From e8d5bcc6007ce9d31864cacbe75c83119b0498b9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 28 Jun 2017 02:27:41 -0400 Subject: [PATCH 0633/1030] bump sjson-new to latest --- build.sbt | 9 +++++++-- project/Dependencies.scala | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index d949c1797..69bd536f6 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ import Path._ // import com.typesafe.tools.mima.core._, ProblemFilters._ -def baseVersion = "1.0.0" +def baseVersion = "1.0.0-SNAPSHOT" def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, @@ -43,7 +43,12 @@ lazy val lmRoot = (project in file(".")) scalafmtOnCompile := true, // scalafmtVersion 1.0.0-RC3 has regression scalafmtVersion := "0.6.8", - git.baseVersion := baseVersion + git.baseVersion := baseVersion, + version := { + val v = version.value + if (v contains "SNAPSHOT") git.baseVersion.value + else v + } )), commonSettings, name := "LM Root", diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 561601327..6c618249f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -55,7 +55,7 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") - val sjsonnewVersion = "0.7.0" + val sjsonnewVersion = "0.8.0-M1" val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" From 4ac724e529b807c2b86b435439e5d831713cbcbf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 1 Jul 2017 19:27:54 -0400 Subject: [PATCH 0634/1030] bump to sbt-contraband 0.3.0-M7 and latest util --- build.sbt | 5 +- .../ConfigurationReportLite.scala | 36 ++++++ .../ExternalIvyConfiguration.scala | 56 +++++++++ .../InlineConfiguration.scala | 78 +++++++++++++ .../InlineIvyConfiguration.scala | 92 +++++++++++++++ .../librarymanagement/IvyConfiguration.scala | 29 +++++ .../internal/librarymanagement/IvyPaths.scala | 40 +++++++ .../RetrieveConfiguration.scala | 45 ++++++++ .../librarymanagement/UpdateReportLite.scala | 32 ++++++ .../sbt/librarymanagement/Artifact.scala | 61 ++++++++++ .../librarymanagement/ArtifactFormats.scala | 41 +++++++ .../ArtifactTypeFilter.scala | 43 +++++++ .../ArtifactTypeFilterFormats.scala | 29 +++++ .../sbt/librarymanagement/Binary.scala | 43 +++++++ .../sbt/librarymanagement/BinaryFormats.scala | 29 +++++ .../sbt/librarymanagement/Caller.scala | 56 +++++++++ .../sbt/librarymanagement/CallerFormats.scala | 39 +++++++ .../librarymanagement/ChainedResolver.scala | 36 ++++++ .../ChainedResolverFormats.scala | 29 +++++ .../sbt/librarymanagement/Checksum.scala | 36 ++++++ .../librarymanagement/ChecksumFormats.scala | 29 +++++ .../sbt/librarymanagement/Configuration.scala | 50 +++++++++ .../ConfigurationFormats.scala | 35 ++++++ .../ConfigurationReport.scala | 46 ++++++++ .../ConfigurationReportFormats.scala | 31 +++++ .../ConfigurationReportLiteFormats.scala | 29 +++++ .../librarymanagement/ConflictManager.scala | 42 +++++++ .../ConflictManagerFormats.scala | 31 +++++ .../sbt/librarymanagement/Constant.scala | 34 ++++++ .../librarymanagement/ConstantFormats.scala | 27 +++++ .../sbt/librarymanagement/CrossVersion.scala | 26 +++++ .../CrossVersionFormats.scala | 11 ++ .../sbt/librarymanagement/Developer.scala | 44 ++++++++ .../librarymanagement/DeveloperFormats.scala | 33 ++++++ .../sbt/librarymanagement/Disabled.scala | 30 +++++ .../librarymanagement/DisabledFormats.scala | 27 +++++ .../ExternalIvyConfigurationFormats.scala | 37 ++++++ .../librarymanagement/FileConfiguration.scala | 41 +++++++ .../FileConfigurationFormats.scala | 29 +++++ .../librarymanagement/FileRepository.scala | 43 +++++++ .../FileRepositoryFormats.scala | 31 +++++ .../sbt/librarymanagement/Full.scala | 43 +++++++ .../sbt/librarymanagement/FullFormats.scala | 29 +++++ .../sbt/librarymanagement/InclExclRule.scala | 58 ++++++++++ .../InclExclRuleFormats.scala | 35 ++++++ .../InlineConfigurationFormats.scala | 47 ++++++++ .../InlineIvyConfigurationFormats.scala | 47 ++++++++ .../IvyConfigurationFormats.scala | 11 ++ .../IvyFileConfiguration.scala | 48 ++++++++ .../IvyFileConfigurationFormats.scala | 33 ++++++ .../librarymanagement/IvyPathsFormats.scala | 29 +++++ .../sbt/librarymanagement/IvyScala.scala | 61 ++++++++++ .../librarymanagement/IvyScalaFormats.scala | 41 +++++++ .../KeyFileAuthentication.scala | 44 ++++++++ .../KeyFileAuthenticationFormats.scala | 31 +++++ .../LibraryManagementCodec.scala | 66 +++++++++++ .../sbt/librarymanagement/MavenCache.scala | 50 +++++++++ .../librarymanagement/MavenCacheFormats.scala | 33 ++++++ .../sbt/librarymanagement/MavenRepo.scala | 41 +++++++ .../librarymanagement/MavenRepoFormats.scala | 31 +++++ .../librarymanagement/MavenRepository.scala | 29 +++++ .../MavenRepositoryFormats.scala | 11 ++ .../ModuleConfiguration.scala | 45 ++++++++ .../ModuleConfigurationFormats.scala | 33 ++++++ .../sbt/librarymanagement/ModuleID.scala | 81 +++++++++++++ .../librarymanagement/ModuleIDFormats.scala | 51 +++++++++ .../sbt/librarymanagement/ModuleInfo.scala | 66 +++++++++++ .../librarymanagement/ModuleInfoFormats.scala | 43 +++++++ .../sbt/librarymanagement/ModuleReport.scala | 106 ++++++++++++++++++ .../ModuleReportFormats.scala | 61 ++++++++++ .../librarymanagement/ModuleSettings.scala | 27 +++++ .../ModuleSettingsFormats.scala | 11 ++ .../OrganizationArtifactReport.scala | 51 +++++++++ .../OrganizationArtifactReportFormats.scala | 31 +++++ .../PasswordAuthentication.scala | 40 +++++++ .../PasswordAuthenticationFormats.scala | 29 +++++ .../sbt/librarymanagement/Patch.scala | 33 ++++++ .../sbt/librarymanagement/PatchFormats.scala | 27 +++++ .../sbt/librarymanagement/Patterns.scala | 50 +++++++++ .../PatternsBasedRepository.scala | 28 +++++ .../PatternsBasedRepositoryFormats.scala | 11 ++ .../librarymanagement/PatternsFormats.scala | 35 ++++++ .../librarymanagement/PomConfiguration.scala | 48 ++++++++ .../PomConfigurationFormats.scala | 33 ++++++ .../sbt/librarymanagement/Resolver.scala | 26 +++++ .../librarymanagement/ResolverFormats.scala | 11 ++ .../RetrieveConfigurationFormats.scala | 33 ++++++ .../sbt/librarymanagement/ScmInfo.scala | 46 ++++++++ .../librarymanagement/ScmInfoFormats.scala | 31 +++++ .../librarymanagement/SftpRepository.scala | 43 +++++++ .../SftpRepositoryFormats.scala | 31 +++++ .../librarymanagement/SshAuthentication.scala | 25 +++++ .../SshAuthenticationFormats.scala | 11 ++ .../SshBasedRepository.scala | 29 +++++ .../SshBasedRepositoryFormats.scala | 11 ++ .../sbt/librarymanagement/SshConnection.scala | 50 +++++++++ .../SshConnectionFormats.scala | 31 +++++ .../sbt/librarymanagement/SshRepository.scala | 51 +++++++++ .../SshRepositoryFormats.scala | 33 ++++++ .../sbt/librarymanagement/URLRepository.scala | 36 ++++++ .../URLRepositoryFormats.scala | 29 +++++ .../UpdateConfiguration.scala | 56 +++++++++ .../UpdateConfigurationFormats.scala | 37 ++++++ .../sbt/librarymanagement/UpdateLogging.scala | 22 ++++ .../UpdateLoggingFormats.scala | 33 ++++++ .../sbt/librarymanagement/UpdateReport.scala | 52 +++++++++ .../UpdateReportFormats.scala | 33 ++++++ .../UpdateReportLiteFormats.scala | 27 +++++ .../sbt/librarymanagement/UpdateStats.scala | 44 ++++++++ .../UpdateStatsFormats.scala | 33 ++++++ .../internal/librarymanagement/IvyCache.scala | 2 +- .../librarymanagement/CrossVersionExtra.scala | 1 + .../src/test/scala/DMSerializationSpec.scala | 2 +- project/Dependencies.scala | 9 +- project/plugins.sbt | 2 +- 115 files changed, 4191 insertions(+), 8 deletions(-) create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala diff --git a/build.sbt b/build.sbt index 69bd536f6..8cb4a343f 100644 --- a/build.sbt +++ b/build.sbt @@ -69,7 +69,7 @@ lazy val lm = (project in file("librarymanagement")) launcherInterface, gigahorseOkhttp, okhttpUrlconnection, - sjsonnewScalaJson % Optional), + sjsonnewScalaJson.value % Optional), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def .task( @@ -79,6 +79,9 @@ lazy val lm = (project in file("librarymanagement")) (compile in Compile).value)) .taskValue, // mimaBinaryIssueFilters ++= Seq(), + managedSourceDirectories in Compile += + baseDirectory.value / "src" / "main" / "contraband-scala", + sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc mappings in (Compile, packageSrc) ++= { diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala new file mode 100644 index 000000000..f63313b93 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class ConfigurationReportLite private ( + val configuration: String, + val details: Vector[sbt.librarymanagement.OrganizationArtifactReport]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ConfigurationReportLite => (this.configuration == x.configuration) && (this.details == x.details) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "ConfigurationReportLite".##) + configuration.##) + details.##) + } + override def toString: String = { + "ConfigurationReportLite(" + configuration + ", " + details + ")" + } + protected[this] def copy(configuration: String = configuration, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReportLite = { + new ConfigurationReportLite(configuration, details) + } + def withConfiguration(configuration: String): ConfigurationReportLite = { + copy(configuration = configuration) + } + def withDetails(details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReportLite = { + copy(details = details) + } +} +object ConfigurationReportLite { + + def apply(configuration: String, details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReportLite = new ConfigurationReportLite(configuration, details) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala new file mode 100644 index 000000000..b99ec9238 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala @@ -0,0 +1,56 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class ExternalIvyConfiguration private ( + lock: Option[xsbti.GlobalLock], + baseDirectory: java.io.File, + log: xsbti.Logger, + updateOptions: sbt.librarymanagement.UpdateOptions, + val uri: java.net.URI, + val extraResolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.internal.librarymanagement.IvyConfiguration(lock, baseDirectory, log, updateOptions) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ExternalIvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.uri == x.uri) && (this.extraResolvers == x.extraResolvers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ExternalIvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) + uri.##) + extraResolvers.##) + } + override def toString: String = { + "ExternalIvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ", " + uri + ", " + extraResolvers + ")" + } + protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, baseDirectory: java.io.File = baseDirectory, log: xsbti.Logger = log, updateOptions: sbt.librarymanagement.UpdateOptions = updateOptions, uri: java.net.URI = uri, extraResolvers: Vector[sbt.librarymanagement.Resolver] = extraResolvers): ExternalIvyConfiguration = { + new ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) + } + def withLock(lock: Option[xsbti.GlobalLock]): ExternalIvyConfiguration = { + copy(lock = lock) + } + def withLock(lock: xsbti.GlobalLock): ExternalIvyConfiguration = { + copy(lock = Option(lock)) + } + def withBaseDirectory(baseDirectory: java.io.File): ExternalIvyConfiguration = { + copy(baseDirectory = baseDirectory) + } + def withLog(log: xsbti.Logger): ExternalIvyConfiguration = { + copy(log = log) + } + def withUpdateOptions(updateOptions: sbt.librarymanagement.UpdateOptions): ExternalIvyConfiguration = { + copy(updateOptions = updateOptions) + } + def withUri(uri: java.net.URI): ExternalIvyConfiguration = { + copy(uri = uri) + } + def withExtraResolvers(extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = { + copy(extraResolvers = extraResolvers) + } +} +object ExternalIvyConfiguration { + + def apply(lock: Option[xsbti.GlobalLock], baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) + def apply(lock: xsbti.GlobalLock, baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(Option(lock), baseDirectory, log, updateOptions, uri, extraResolvers) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala new file mode 100644 index 000000000..5ddc4a153 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala @@ -0,0 +1,78 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class InlineConfiguration private ( + validate: Boolean, + ivyScala: Option[sbt.librarymanagement.IvyScala], + val module: sbt.librarymanagement.ModuleID, + val moduleInfo: sbt.librarymanagement.ModuleInfo, + val dependencies: Vector[sbt.librarymanagement.ModuleID], + val overrides: Set[sbt.librarymanagement.ModuleID], + val excludes: Vector[sbt.librarymanagement.InclExclRule], + val ivyXML: scala.xml.NodeSeq, + val configurations: Vector[sbt.librarymanagement.Configuration], + val defaultConfiguration: Option[sbt.librarymanagement.Configuration], + val conflictManager: sbt.librarymanagement.ConflictManager) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { + + private def this(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]) = this(validate, ivyScala, module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) + + override def equals(o: Any): Boolean = o match { + case x: InlineConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.module == x.module) && (this.moduleInfo == x.moduleInfo) && (this.dependencies == x.dependencies) && (this.overrides == x.overrides) && (this.excludes == x.excludes) && (this.ivyXML == x.ivyXML) && (this.configurations == x.configurations) && (this.defaultConfiguration == x.defaultConfiguration) && (this.conflictManager == x.conflictManager) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineConfiguration".##) + validate.##) + ivyScala.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) + } + override def toString: String = { + "InlineConfiguration(" + validate + ", " + ivyScala + ", " + module + ", " + moduleInfo + ", " + dependencies + ", " + overrides + ", " + excludes + ", " + ivyXML + ", " + configurations + ", " + defaultConfiguration + ", " + conflictManager + ")" + } + protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, module: sbt.librarymanagement.ModuleID = module, moduleInfo: sbt.librarymanagement.ModuleInfo = moduleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, overrides: Set[sbt.librarymanagement.ModuleID] = overrides, excludes: Vector[sbt.librarymanagement.InclExclRule] = excludes, ivyXML: scala.xml.NodeSeq = ivyXML, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, defaultConfiguration: Option[sbt.librarymanagement.Configuration] = defaultConfiguration, conflictManager: sbt.librarymanagement.ConflictManager = conflictManager): InlineConfiguration = { + new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + } + def withValidate(validate: Boolean): InlineConfiguration = { + copy(validate = validate) + } + def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): InlineConfiguration = { + copy(ivyScala = ivyScala) + } + def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): InlineConfiguration = { + copy(ivyScala = Option(ivyScala)) + } + def withModule(module: sbt.librarymanagement.ModuleID): InlineConfiguration = { + copy(module = module) + } + def withModuleInfo(moduleInfo: sbt.librarymanagement.ModuleInfo): InlineConfiguration = { + copy(moduleInfo = moduleInfo) + } + def withDependencies(dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = { + copy(dependencies = dependencies) + } + def withOverrides(overrides: Set[sbt.librarymanagement.ModuleID]): InlineConfiguration = { + copy(overrides = overrides) + } + def withExcludes(excludes: Vector[sbt.librarymanagement.InclExclRule]): InlineConfiguration = { + copy(excludes = excludes) + } + def withIvyXML(ivyXML: scala.xml.NodeSeq): InlineConfiguration = { + copy(ivyXML = ivyXML) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): InlineConfiguration = { + copy(configurations = configurations) + } + def withDefaultConfiguration(defaultConfiguration: Option[sbt.librarymanagement.Configuration]): InlineConfiguration = { + copy(defaultConfiguration = defaultConfiguration) + } + def withConflictManager(conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = { + copy(conflictManager = conflictManager) + } +} +object InlineConfiguration extends sbt.internal.librarymanagement.InlineConfigurationFunctions { + + def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) + def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = new InlineConfiguration(validate, Option(ivyScala), module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) + def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Set[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Set[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = new InlineConfiguration(validate, Option(ivyScala), module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala new file mode 100644 index 000000000..0cd006bfa --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala @@ -0,0 +1,92 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class InlineIvyConfiguration private ( + lock: Option[xsbti.GlobalLock], + baseDirectory: java.io.File, + log: xsbti.Logger, + updateOptions: sbt.librarymanagement.UpdateOptions, + val paths: sbt.internal.librarymanagement.IvyPaths, + val resolvers: Vector[sbt.librarymanagement.Resolver], + val otherResolvers: Vector[sbt.librarymanagement.Resolver], + val moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], + val checksums: Vector[String], + val managedChecksums: Boolean, + val resolutionCacheDir: Option[java.io.File]) extends sbt.internal.librarymanagement.IvyConfiguration(lock, baseDirectory, log, updateOptions) with Serializable { + def this( + paths: sbt.internal.librarymanagement.IvyPaths, + resolvers: Vector[sbt.librarymanagement.Resolver], + otherResolvers: Vector[sbt.librarymanagement.Resolver], + moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], + lock: Option[xsbti.GlobalLock], + checksums: Vector[String], + managedChecksums: Boolean, + resolutionCacheDir: Option[java.io.File], + updateOptions: sbt.librarymanagement.UpdateOptions, + log: xsbti.Logger + ) = + this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, + moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + + + override def equals(o: Any): Boolean = o match { + case x: InlineIvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.paths == x.paths) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.moduleConfigurations == x.moduleConfigurations) && (this.checksums == x.checksums) && (this.managedChecksums == x.managedChecksums) && (this.resolutionCacheDir == x.resolutionCacheDir) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineIvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) + } + override def toString: String = { + "InlineIvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ", " + paths + ", " + resolvers + ", " + otherResolvers + ", " + moduleConfigurations + ", " + checksums + ", " + managedChecksums + ", " + resolutionCacheDir + ")" + } + protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, baseDirectory: java.io.File = baseDirectory, log: xsbti.Logger = log, updateOptions: sbt.librarymanagement.UpdateOptions = updateOptions, paths: sbt.internal.librarymanagement.IvyPaths = paths, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration] = moduleConfigurations, checksums: Vector[String] = checksums, managedChecksums: Boolean = managedChecksums, resolutionCacheDir: Option[java.io.File] = resolutionCacheDir): InlineIvyConfiguration = { + new InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + } + def withLock(lock: Option[xsbti.GlobalLock]): InlineIvyConfiguration = { + copy(lock = lock) + } + def withLock(lock: xsbti.GlobalLock): InlineIvyConfiguration = { + copy(lock = Option(lock)) + } + def withBaseDirectory(baseDirectory: java.io.File): InlineIvyConfiguration = { + copy(baseDirectory = baseDirectory) + } + def withLog(log: xsbti.Logger): InlineIvyConfiguration = { + copy(log = log) + } + def withUpdateOptions(updateOptions: sbt.librarymanagement.UpdateOptions): InlineIvyConfiguration = { + copy(updateOptions = updateOptions) + } + def withPaths(paths: sbt.internal.librarymanagement.IvyPaths): InlineIvyConfiguration = { + copy(paths = paths) + } + def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { + copy(resolvers = resolvers) + } + def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { + copy(otherResolvers = otherResolvers) + } + def withModuleConfigurations(moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration]): InlineIvyConfiguration = { + copy(moduleConfigurations = moduleConfigurations) + } + def withChecksums(checksums: Vector[String]): InlineIvyConfiguration = { + copy(checksums = checksums) + } + def withManagedChecksums(managedChecksums: Boolean): InlineIvyConfiguration = { + copy(managedChecksums = managedChecksums) + } + def withResolutionCacheDir(resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = { + copy(resolutionCacheDir = resolutionCacheDir) + } + def withResolutionCacheDir(resolutionCacheDir: java.io.File): InlineIvyConfiguration = { + copy(resolutionCacheDir = Option(resolutionCacheDir)) + } +} +object InlineIvyConfiguration { + + def apply(lock: Option[xsbti.GlobalLock], baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, paths: sbt.internal.librarymanagement.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = new InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + def apply(lock: xsbti.GlobalLock, baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, paths: sbt.internal.librarymanagement.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: java.io.File): InlineIvyConfiguration = new InlineIvyConfiguration(Option(lock), baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, Option(resolutionCacheDir)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala new file mode 100644 index 000000000..a50adcb0a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +abstract class IvyConfiguration( + val lock: Option[xsbti.GlobalLock], + val baseDirectory: java.io.File, + val log: xsbti.Logger, + val updateOptions: sbt.librarymanagement.UpdateOptions) extends Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: IvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "IvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) + } + override def toString: String = { + "IvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ")" + } +} +object IvyConfiguration { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala new file mode 100644 index 000000000..0a5fd35ae --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala @@ -0,0 +1,40 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class IvyPaths private ( + val baseDirectory: java.io.File, + val ivyHome: Option[java.io.File]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: IvyPaths => (this.baseDirectory == x.baseDirectory) && (this.ivyHome == x.ivyHome) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "IvyPaths".##) + baseDirectory.##) + ivyHome.##) + } + override def toString: String = { + "IvyPaths(" + baseDirectory + ", " + ivyHome + ")" + } + protected[this] def copy(baseDirectory: java.io.File = baseDirectory, ivyHome: Option[java.io.File] = ivyHome): IvyPaths = { + new IvyPaths(baseDirectory, ivyHome) + } + def withBaseDirectory(baseDirectory: java.io.File): IvyPaths = { + copy(baseDirectory = baseDirectory) + } + def withIvyHome(ivyHome: Option[java.io.File]): IvyPaths = { + copy(ivyHome = ivyHome) + } + def withIvyHome(ivyHome: java.io.File): IvyPaths = { + copy(ivyHome = Option(ivyHome)) + } +} +object IvyPaths { + + def apply(baseDirectory: java.io.File, ivyHome: Option[java.io.File]): IvyPaths = new IvyPaths(baseDirectory, ivyHome) + def apply(baseDirectory: java.io.File, ivyHome: java.io.File): IvyPaths = new IvyPaths(baseDirectory, Option(ivyHome)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala new file mode 100644 index 000000000..e1be8c9db --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala @@ -0,0 +1,45 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class RetrieveConfiguration private ( + val retrieveDirectory: java.io.File, + val outputPattern: String, + val sync: Boolean, + val configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]) extends Serializable { + + private def this(retrieveDirectory: java.io.File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) + + override def equals(o: Any): Boolean = o match { + case x: RetrieveConfiguration => (this.retrieveDirectory == x.retrieveDirectory) && (this.outputPattern == x.outputPattern) && (this.sync == x.sync) && (this.configurationsToRetrieve == x.configurationsToRetrieve) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) + } + override def toString: String = { + "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" + } + protected[this] def copy(retrieveDirectory: java.io.File = retrieveDirectory, outputPattern: String = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]] = configurationsToRetrieve): RetrieveConfiguration = { + new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + } + def withRetrieveDirectory(retrieveDirectory: java.io.File): RetrieveConfiguration = { + copy(retrieveDirectory = retrieveDirectory) + } + def withOutputPattern(outputPattern: String): RetrieveConfiguration = { + copy(outputPattern = outputPattern) + } + def withSync(sync: Boolean): RetrieveConfiguration = { + copy(sync = sync) + } + def withConfigurationsToRetrieve(configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]): RetrieveConfiguration = { + copy(configurationsToRetrieve = configurationsToRetrieve) + } +} +object RetrieveConfiguration { + + def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, false, None) + def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala new file mode 100644 index 000000000..4d927be08 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala @@ -0,0 +1,32 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class UpdateReportLite private ( + val configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: UpdateReportLite => (this.configurations == x.configurations) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "UpdateReportLite".##) + configurations.##) + } + override def toString: String = { + "UpdateReportLite(" + configurations + ")" + } + protected[this] def copy(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite] = configurations): UpdateReportLite = { + new UpdateReportLite(configurations) + } + def withConfigurations(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite]): UpdateReportLite = { + copy(configurations = configurations) + } +} +object UpdateReportLite { + + def apply(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite]): UpdateReportLite = new UpdateReportLite(configurations) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala new file mode 100644 index 000000000..d1848b1c0 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -0,0 +1,61 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class Artifact private ( + val name: String, + val `type`: String, + val extension: String, + val classifier: Option[String], + val configurations: Vector[sbt.librarymanagement.Configuration], + val url: Option[java.net.URL], + val extraAttributes: Map[String, String], + val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { + + private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) + + override def equals(o: Any): Boolean = o match { + case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + } + override def toString: String = { + "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" + } + protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { + new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + } + def withName(name: String): Artifact = { + copy(name = name) + } + def withType(`type`: String): Artifact = { + copy(`type` = `type`) + } + def withExtension(extension: String): Artifact = { + copy(extension = extension) + } + def withClassifier(classifier: Option[String]): Artifact = { + copy(classifier = classifier) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): Artifact = { + copy(configurations = configurations) + } + def withUrl(url: Option[java.net.URL]): Artifact = { + copy(url = url) + } + def withExtraAttributes(extraAttributes: Map[String, String]): Artifact = { + copy(extraAttributes = extraAttributes) + } + def withChecksum(checksum: Option[sbt.librarymanagement.Checksum]): Artifact = { + copy(checksum = checksum) + } +} +object Artifact extends sbt.librarymanagement.ArtifactFunctions { + + def apply(name: String): Artifact = new Artifact(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.Configuration], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala new file mode 100644 index 000000000..08bd9cadb --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ArtifactFormats { self: sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = new JsonFormat[sbt.librarymanagement.Artifact] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val `type` = unbuilder.readField[String]("type") + val extension = unbuilder.readField[String]("extension") + val classifier = unbuilder.readField[Option[String]]("classifier") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val url = unbuilder.readField[Option[java.net.URL]]("url") + val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") + val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") + unbuilder.endObject() + sbt.librarymanagement.Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Artifact, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("type", obj.`type`) + builder.addField("extension", obj.extension) + builder.addField("classifier", obj.classifier) + builder.addField("configurations", obj.configurations) + builder.addField("url", obj.url) + builder.addField("extraAttributes", obj.extraAttributes) + builder.addField("checksum", obj.checksum) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala new file mode 100644 index 000000000..9b64bf71d --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) */ +final class ArtifactTypeFilter private ( + /** + * Represents the artifact types that we should try to resolve for (as in the allowed values of + * `artifact[type]` from a dependency `` section). One can use this to filter + * source / doc artifacts. + */ + val types: Set[String], + /** Whether to invert the types filter (i.e. allow only types NOT in the set) */ + val inverted: Boolean) extends sbt.librarymanagement.ArtifactTypeFilterExtra with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ArtifactTypeFilter => (this.types == x.types) && (this.inverted == x.inverted) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "ArtifactTypeFilter".##) + types.##) + inverted.##) + } + override def toString: String = { + "ArtifactTypeFilter(" + types + ", " + inverted + ")" + } + protected[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter = { + new ArtifactTypeFilter(types, inverted) + } + def withTypes(types: Set[String]): ArtifactTypeFilter = { + copy(types = types) + } + def withInverted(inverted: Boolean): ArtifactTypeFilter = { + copy(inverted = inverted) + } +} +object ArtifactTypeFilter extends sbt.librarymanagement.ArtifactTypeFilterFunctions { + + def apply(types: Set[String], inverted: Boolean): ArtifactTypeFilter = new ArtifactTypeFilter(types, inverted) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala new file mode 100644 index 000000000..ec7a3919e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ArtifactTypeFilterFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ArtifactTypeFilterFormat: JsonFormat[sbt.librarymanagement.ArtifactTypeFilter] = new JsonFormat[sbt.librarymanagement.ArtifactTypeFilter] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ArtifactTypeFilter = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val types = unbuilder.readField[Set[String]]("types") + val inverted = unbuilder.readField[Boolean]("inverted") + unbuilder.endObject() + sbt.librarymanagement.ArtifactTypeFilter(types, inverted) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ArtifactTypeFilter, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("types", obj.types) + builder.addField("inverted", obj.inverted) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala new file mode 100644 index 000000000..323002dd7 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Cross-versions a module using the result of + * prepending `prefix` and appending `suffix` to the binary version. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the binary version is "2.10", + * the module is cross-versioned with "foo_2.10_bar". + */ +final class Binary private ( + val prefix: String, + val suffix: String) extends sbt.librarymanagement.CrossVersion() with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: Binary => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "Binary".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "Binary(" + prefix + ", " + suffix + ")" + } + protected[this] def copy(prefix: String = prefix, suffix: String = suffix): Binary = { + new Binary(prefix, suffix) + } + def withPrefix(prefix: String): Binary = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): Binary = { + copy(suffix = suffix) + } +} +object Binary { + + def apply(): Binary = new Binary("", "") + def apply(prefix: String, suffix: String): Binary = new Binary(prefix, suffix) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala new file mode 100644 index 000000000..95bf74afc --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait BinaryFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val BinaryFormat: JsonFormat[sbt.librarymanagement.Binary] = new JsonFormat[sbt.librarymanagement.Binary] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Binary = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.Binary(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Binary, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala new file mode 100644 index 000000000..0770bc9e7 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -0,0 +1,56 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class Caller private ( + val caller: sbt.librarymanagement.ModuleID, + val callerConfigurations: Vector[String], + val callerExtraAttributes: Map[String, String], + val isForceDependency: Boolean, + val isChangingDependency: Boolean, + val isTransitiveDependency: Boolean, + val isDirectlyForceDependency: Boolean) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Caller => (this.caller == x.caller) && (this.callerConfigurations == x.callerConfigurations) && (this.callerExtraAttributes == x.callerExtraAttributes) && (this.isForceDependency == x.isForceDependency) && (this.isChangingDependency == x.isChangingDependency) && (this.isTransitiveDependency == x.isTransitiveDependency) && (this.isDirectlyForceDependency == x.isDirectlyForceDependency) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "Caller".##) + caller.##) + callerConfigurations.##) + callerExtraAttributes.##) + isForceDependency.##) + isChangingDependency.##) + isTransitiveDependency.##) + isDirectlyForceDependency.##) + } + override def toString: String = { + s"$caller" + } + protected[this] def copy(caller: sbt.librarymanagement.ModuleID = caller, callerConfigurations: Vector[String] = callerConfigurations, callerExtraAttributes: Map[String, String] = callerExtraAttributes, isForceDependency: Boolean = isForceDependency, isChangingDependency: Boolean = isChangingDependency, isTransitiveDependency: Boolean = isTransitiveDependency, isDirectlyForceDependency: Boolean = isDirectlyForceDependency): Caller = { + new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) + } + def withCaller(caller: sbt.librarymanagement.ModuleID): Caller = { + copy(caller = caller) + } + def withCallerConfigurations(callerConfigurations: Vector[String]): Caller = { + copy(callerConfigurations = callerConfigurations) + } + def withCallerExtraAttributes(callerExtraAttributes: Map[String, String]): Caller = { + copy(callerExtraAttributes = callerExtraAttributes) + } + def withIsForceDependency(isForceDependency: Boolean): Caller = { + copy(isForceDependency = isForceDependency) + } + def withIsChangingDependency(isChangingDependency: Boolean): Caller = { + copy(isChangingDependency = isChangingDependency) + } + def withIsTransitiveDependency(isTransitiveDependency: Boolean): Caller = { + copy(isTransitiveDependency = isTransitiveDependency) + } + def withIsDirectlyForceDependency(isDirectlyForceDependency: Boolean): Caller = { + copy(isDirectlyForceDependency = isDirectlyForceDependency) + } +} +object Caller { + + def apply(caller: sbt.librarymanagement.ModuleID, callerConfigurations: Vector[String], callerExtraAttributes: Map[String, String], isForceDependency: Boolean, isChangingDependency: Boolean, isTransitiveDependency: Boolean, isDirectlyForceDependency: Boolean): Caller = new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala new file mode 100644 index 000000000..f0994fef8 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala @@ -0,0 +1,39 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val CallerFormat: JsonFormat[sbt.librarymanagement.Caller] = new JsonFormat[sbt.librarymanagement.Caller] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Caller = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val caller = unbuilder.readField[sbt.librarymanagement.ModuleID]("caller") + val callerConfigurations = unbuilder.readField[Vector[String]]("callerConfigurations") + val callerExtraAttributes = unbuilder.readField[Map[String, String]]("callerExtraAttributes") + val isForceDependency = unbuilder.readField[Boolean]("isForceDependency") + val isChangingDependency = unbuilder.readField[Boolean]("isChangingDependency") + val isTransitiveDependency = unbuilder.readField[Boolean]("isTransitiveDependency") + val isDirectlyForceDependency = unbuilder.readField[Boolean]("isDirectlyForceDependency") + unbuilder.endObject() + sbt.librarymanagement.Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Caller, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("caller", obj.caller) + builder.addField("callerConfigurations", obj.callerConfigurations) + builder.addField("callerExtraAttributes", obj.callerExtraAttributes) + builder.addField("isForceDependency", obj.isForceDependency) + builder.addField("isChangingDependency", obj.isChangingDependency) + builder.addField("isTransitiveDependency", obj.isTransitiveDependency) + builder.addField("isDirectlyForceDependency", obj.isDirectlyForceDependency) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala new file mode 100644 index 000000000..75978cc04 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class ChainedResolver private ( + name: String, + val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ChainedResolver => (this.name == x.name) && (this.resolvers == x.resolvers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "ChainedResolver".##) + name.##) + resolvers.##) + } + override def toString: String = { + "ChainedResolver(" + name + ", " + resolvers + ")" + } + protected[this] def copy(name: String = name, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers): ChainedResolver = { + new ChainedResolver(name, resolvers) + } + def withName(name: String): ChainedResolver = { + copy(name = name) + } + def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): ChainedResolver = { + copy(resolvers = resolvers) + } +} +object ChainedResolver { + + def apply(name: String, resolvers: Vector[sbt.librarymanagement.Resolver]): ChainedResolver = new ChainedResolver(name, resolvers) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala new file mode 100644 index 000000000..3972cb500 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ChainedResolverFormat: JsonFormat[sbt.librarymanagement.ChainedResolver] = new JsonFormat[sbt.librarymanagement.ChainedResolver] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") + unbuilder.endObject() + sbt.librarymanagement.ChainedResolver(name, resolvers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ChainedResolver, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("resolvers", obj.resolvers) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala new file mode 100644 index 000000000..dd2db5902 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class Checksum private ( + val digest: String, + val `type`: String) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Checksum => (this.digest == x.digest) && (this.`type` == x.`type`) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "Checksum".##) + digest.##) + `type`.##) + } + override def toString: String = { + "Checksum(" + digest + ", " + `type` + ")" + } + protected[this] def copy(digest: String = digest, `type`: String = `type`): Checksum = { + new Checksum(digest, `type`) + } + def withDigest(digest: String): Checksum = { + copy(digest = digest) + } + def withType(`type`: String): Checksum = { + copy(`type` = `type`) + } +} +object Checksum { + + def apply(digest: String, `type`: String): Checksum = new Checksum(digest, `type`) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala new file mode 100644 index 000000000..7f674171e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ChecksumFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ChecksumFormat: JsonFormat[sbt.librarymanagement.Checksum] = new JsonFormat[sbt.librarymanagement.Checksum] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Checksum = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val digest = unbuilder.readField[String]("digest") + val `type` = unbuilder.readField[String]("type") + unbuilder.endObject() + sbt.librarymanagement.Checksum(digest, `type`) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Checksum, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("digest", obj.digest) + builder.addField("type", obj.`type`) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala new file mode 100644 index 000000000..a4ab026da --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala @@ -0,0 +1,50 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Represents an Ivy configuration. */ +final class Configuration private ( + val name: String, + val description: String, + val isPublic: Boolean, + val extendsConfigs: Vector[sbt.librarymanagement.Configuration], + val transitive: Boolean) extends sbt.librarymanagement.ConfigurationExtra with Serializable { + + private def this(name: String) = this(name, "", true, Vector.empty, true) + + override def equals(o: Any): Boolean = o match { + case x: Configuration => (this.name == x.name) && (this.description == x.description) && (this.isPublic == x.isPublic) && (this.extendsConfigs == x.extendsConfigs) && (this.transitive == x.transitive) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "Configuration".##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) + } + override def toString: String = { + name + } + protected[this] def copy(name: String = name, description: String = description, isPublic: Boolean = isPublic, extendsConfigs: Vector[sbt.librarymanagement.Configuration] = extendsConfigs, transitive: Boolean = transitive): Configuration = { + new Configuration(name, description, isPublic, extendsConfigs, transitive) + } + def withName(name: String): Configuration = { + copy(name = name) + } + def withDescription(description: String): Configuration = { + copy(description = description) + } + def withIsPublic(isPublic: Boolean): Configuration = { + copy(isPublic = isPublic) + } + def withExtendsConfigs(extendsConfigs: Vector[sbt.librarymanagement.Configuration]): Configuration = { + copy(extendsConfigs = extendsConfigs) + } + def withTransitive(transitive: Boolean): Configuration = { + copy(transitive = transitive) + } +} +object Configuration { + + def apply(name: String): Configuration = new Configuration(name, "", true, Vector.empty, true) + def apply(name: String, description: String, isPublic: Boolean, extendsConfigs: Vector[sbt.librarymanagement.Configuration], transitive: Boolean): Configuration = new Configuration(name, description, isPublic, extendsConfigs, transitive) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala new file mode 100644 index 000000000..70e4b21fc --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = new JsonFormat[sbt.librarymanagement.Configuration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Configuration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val description = unbuilder.readField[String]("description") + val isPublic = unbuilder.readField[Boolean]("isPublic") + val extendsConfigs = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("extendsConfigs") + val transitive = unbuilder.readField[Boolean]("transitive") + unbuilder.endObject() + sbt.librarymanagement.Configuration(name, description, isPublic, extendsConfigs, transitive) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Configuration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("description", obj.description) + builder.addField("isPublic", obj.isPublic) + builder.addField("extendsConfigs", obj.extendsConfigs) + builder.addField("transitive", obj.transitive) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala new file mode 100644 index 000000000..2fa190dea --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -0,0 +1,46 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Provides information about resolution of a single configuration. */ +final class ConfigurationReport private ( + /** the configuration this report is for. */ + val configuration: String, + /** a sequence containing one report for each module resolved for this configuration. */ + val modules: Vector[sbt.librarymanagement.ModuleReport], + /** a sequence containing one report for each org/name, which may or may not be part of the final resolution. */ + val details: Vector[sbt.librarymanagement.OrganizationArtifactReport]) extends sbt.librarymanagement.ConfigurationReportExtra with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ConfigurationReport => (this.configuration == x.configuration) && (this.modules == x.modules) && (this.details == x.details) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "ConfigurationReport".##) + configuration.##) + modules.##) + details.##) + } + override def toString: String = { + s"\t$configuration:\n" + + (if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map("\t\t(EVICTED) " + _ + "\n").mkString + else details.mkString) + } + protected[this] def copy(configuration: String = configuration, modules: Vector[sbt.librarymanagement.ModuleReport] = modules, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReport = { + new ConfigurationReport(configuration, modules, details) + } + def withConfiguration(configuration: String): ConfigurationReport = { + copy(configuration = configuration) + } + def withModules(modules: Vector[sbt.librarymanagement.ModuleReport]): ConfigurationReport = { + copy(modules = modules) + } + def withDetails(details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReport = { + copy(details = details) + } +} +object ConfigurationReport { + + def apply(configuration: String, modules: Vector[sbt.librarymanagement.ModuleReport], details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReport = new ConfigurationReport(configuration, modules, details) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala new file mode 100644 index 000000000..81a1219ad --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConfigurationReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val configuration = unbuilder.readField[String]("configuration") + val modules = unbuilder.readField[Vector[sbt.librarymanagement.ModuleReport]]("modules") + val details = unbuilder.readField[Vector[sbt.librarymanagement.OrganizationArtifactReport]]("details") + unbuilder.endObject() + sbt.librarymanagement.ConfigurationReport(configuration, modules, details) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ConfigurationReport, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("configuration", obj.configuration) + builder.addField("modules", obj.modules) + builder.addField("details", obj.details) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala new file mode 100644 index 000000000..be62807e4 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConfigurationReportLiteFormats { self: sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ConfigurationReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] = new JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ConfigurationReportLite = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val configuration = unbuilder.readField[String]("configuration") + val details = unbuilder.readField[Vector[sbt.librarymanagement.OrganizationArtifactReport]]("details") + unbuilder.endObject() + sbt.internal.librarymanagement.ConfigurationReportLite(configuration, details) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.ConfigurationReportLite, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("configuration", obj.configuration) + builder.addField("details", obj.details) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala new file mode 100644 index 000000000..84cfeefab --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -0,0 +1,42 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** See http://ant.apache.org/ivy/history/latest-milestone/settings/conflict-managers.html for details of the different conflict managers. */ +final class ConflictManager private ( + val name: String, + val organization: String, + val module: String) extends Serializable { + + private def this(name: String) = this(name, "*", "*") + + override def equals(o: Any): Boolean = o match { + case x: ConflictManager => (this.name == x.name) && (this.organization == x.organization) && (this.module == x.module) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "ConflictManager".##) + name.##) + organization.##) + module.##) + } + override def toString: String = { + "ConflictManager(" + name + ", " + organization + ", " + module + ")" + } + protected[this] def copy(name: String = name, organization: String = organization, module: String = module): ConflictManager = { + new ConflictManager(name, organization, module) + } + def withName(name: String): ConflictManager = { + copy(name = name) + } + def withOrganization(organization: String): ConflictManager = { + copy(organization = organization) + } + def withModule(module: String): ConflictManager = { + copy(module = module) + } +} +object ConflictManager extends sbt.librarymanagement.ConflictManagerFunctions { + + def apply(name: String): ConflictManager = new ConflictManager(name, "*", "*") + def apply(name: String, organization: String, module: String): ConflictManager = new ConflictManager(name, organization, module) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala new file mode 100644 index 000000000..40271b940 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConflictManagerFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ConflictManagerFormat: JsonFormat[sbt.librarymanagement.ConflictManager] = new JsonFormat[sbt.librarymanagement.ConflictManager] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConflictManager = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val organization = unbuilder.readField[String]("organization") + val module = unbuilder.readField[String]("module") + unbuilder.endObject() + sbt.librarymanagement.ConflictManager(name, organization, module) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ConflictManager, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("organization", obj.organization) + builder.addField("module", obj.module) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala new file mode 100644 index 000000000..bca95bb25 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala @@ -0,0 +1,34 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Cross-versions a module using the string `value`. */ +final class Constant private ( + val value: String) extends sbt.librarymanagement.CrossVersion() with Serializable { + + private def this() = this("") + + override def equals(o: Any): Boolean = o match { + case x: Constant => (this.value == x.value) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "Constant".##) + value.##) + } + override def toString: String = { + "Constant(" + value + ")" + } + protected[this] def copy(value: String = value): Constant = { + new Constant(value) + } + def withValue(value: String): Constant = { + copy(value = value) + } +} +object Constant { + + def apply(): Constant = new Constant("") + def apply(value: String): Constant = new Constant(value) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala new file mode 100644 index 000000000..752adb674 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConstantFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ConstantFormat: JsonFormat[sbt.librarymanagement.Constant] = new JsonFormat[sbt.librarymanagement.Constant] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Constant = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val value = unbuilder.readField[String]("value") + unbuilder.endObject() + sbt.librarymanagement.Constant(value) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Constant, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("value", obj.value) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala new file mode 100644 index 000000000..c1f658229 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Configures how a module will be cross-versioned. */ +abstract class CrossVersion() extends Serializable { + + + + +override def equals(o: Any): Boolean = o match { + case x: CrossVersion => true + case _ => false +} +override def hashCode: Int = { + 37 * (17 + "CrossVersion".##) +} +override def toString: String = { + "CrossVersion()" +} +} +object CrossVersion extends sbt.librarymanagement.CrossVersionFunctions { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala new file mode 100644 index 000000000..b0b37e916 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait CrossVersionFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats => +implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = flatUnionFormat5[sbt.librarymanagement.CrossVersion, sbt.librarymanagement.Disabled, sbt.librarymanagement.Binary, sbt.librarymanagement.Constant, sbt.librarymanagement.Patch, sbt.librarymanagement.Full]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala new file mode 100644 index 000000000..0689fccf4 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -0,0 +1,44 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class Developer private ( + val id: String, + val name: String, + val email: String, + val url: java.net.URL) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: Developer => (this.id == x.id) && (this.name == x.name) && (this.email == x.email) && (this.url == x.url) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "Developer".##) + id.##) + name.##) + email.##) + url.##) + } + override def toString: String = { + "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" + } + protected[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { + new Developer(id, name, email, url) + } + def withId(id: String): Developer = { + copy(id = id) + } + def withName(name: String): Developer = { + copy(name = name) + } + def withEmail(email: String): Developer = { + copy(email = email) + } + def withUrl(url: java.net.URL): Developer = { + copy(url = url) + } +} +object Developer { + + def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala new file mode 100644 index 000000000..ee1e87e45 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait DeveloperFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = new JsonFormat[sbt.librarymanagement.Developer] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Developer = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val id = unbuilder.readField[String]("id") + val name = unbuilder.readField[String]("name") + val email = unbuilder.readField[String]("email") + val url = unbuilder.readField[java.net.URL]("url") + unbuilder.endObject() + sbt.librarymanagement.Developer(id, name, email, url) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Developer, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("id", obj.id) + builder.addField("name", obj.name) + builder.addField("email", obj.email) + builder.addField("url", obj.url) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala new file mode 100644 index 000000000..c1f3339d1 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala @@ -0,0 +1,30 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Disables cross versioning for a module. */ +final class Disabled private () extends sbt.librarymanagement.CrossVersion() with Serializable { + + + +override def equals(o: Any): Boolean = o match { + case x: Disabled => true + case _ => false +} +override def hashCode: Int = { + 37 * (17 + "Disabled".##) +} +override def toString: String = { + "Disabled()" +} +protected[this] def copy(): Disabled = { + new Disabled() +} + +} +object Disabled { + + def apply(): Disabled = new Disabled() +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala new file mode 100644 index 000000000..7c0602834 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = new JsonFormat[sbt.librarymanagement.Disabled] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.librarymanagement.Disabled() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Disabled, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala new file mode 100644 index 000000000..55de96c3e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.ExternalIvyConfiguration] = new JsonFormat[sbt.internal.librarymanagement.ExternalIvyConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ExternalIvyConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") + val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") + val log = unbuilder.readField[xsbti.Logger]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.UpdateOptions]("updateOptions") + val uri = unbuilder.readField[java.net.URI]("uri") + val extraResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("extraResolvers") + unbuilder.endObject() + sbt.internal.librarymanagement.ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.ExternalIvyConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("lock", obj.lock) + builder.addField("baseDirectory", obj.baseDirectory) + builder.addField("log", obj.log) + builder.addField("updateOptions", obj.updateOptions) + builder.addField("uri", obj.uri) + builder.addField("extraResolvers", obj.extraResolvers) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala new file mode 100644 index 000000000..c74be3197 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Configuration specific to an Ivy filesystem resolver. */ +final class FileConfiguration private ( + val isLocal: Boolean, + val isTransactional: Option[Boolean]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: FileConfiguration => (this.isLocal == x.isLocal) && (this.isTransactional == x.isTransactional) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "FileConfiguration".##) + isLocal.##) + isTransactional.##) + } + override def toString: String = { + "FileConfiguration(" + isLocal + ", " + isTransactional + ")" + } + protected[this] def copy(isLocal: Boolean = isLocal, isTransactional: Option[Boolean] = isTransactional): FileConfiguration = { + new FileConfiguration(isLocal, isTransactional) + } + def withIsLocal(isLocal: Boolean): FileConfiguration = { + copy(isLocal = isLocal) + } + def withIsTransactional(isTransactional: Option[Boolean]): FileConfiguration = { + copy(isTransactional = isTransactional) + } + def withIsTransactional(isTransactional: Boolean): FileConfiguration = { + copy(isTransactional = Option(isTransactional)) + } +} +object FileConfiguration { + + def apply(isLocal: Boolean, isTransactional: Option[Boolean]): FileConfiguration = new FileConfiguration(isLocal, isTransactional) + def apply(isLocal: Boolean, isTransactional: Boolean): FileConfiguration = new FileConfiguration(isLocal, Option(isTransactional)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala new file mode 100644 index 000000000..8117d6b15 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait FileConfigurationFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val FileConfigurationFormat: JsonFormat[sbt.librarymanagement.FileConfiguration] = new JsonFormat[sbt.librarymanagement.FileConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val isLocal = unbuilder.readField[Boolean]("isLocal") + val isTransactional = unbuilder.readField[Option[Boolean]]("isTransactional") + unbuilder.endObject() + sbt.librarymanagement.FileConfiguration(isLocal, isTransactional) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.FileConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("isLocal", obj.isLocal) + builder.addField("isTransactional", obj.isTransactional) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala new file mode 100644 index 000000000..77d2d3068 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** sbt interface for an Ivy filesystem repository. More convenient construction is done using Resolver.file. */ +final class FileRepository private ( + name: String, + patterns: sbt.librarymanagement.Patterns, + val configuration: sbt.librarymanagement.FileConfiguration) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { + def this(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = + this(name, patterns, configuration) + + + override def equals(o: Any): Boolean = o match { + case x: FileRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.configuration == x.configuration) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "FileRepository".##) + name.##) + patterns.##) + configuration.##) + } + override def toString: String = { + "FileRepository(" + name + ", " + patterns + ", " + configuration + ")" + } + protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, configuration: sbt.librarymanagement.FileConfiguration = configuration): FileRepository = { + new FileRepository(name, patterns, configuration) + } + def withName(name: String): FileRepository = { + copy(name = name) + } + def withPatterns(patterns: sbt.librarymanagement.Patterns): FileRepository = { + copy(patterns = patterns) + } + def withConfiguration(configuration: sbt.librarymanagement.FileConfiguration): FileRepository = { + copy(configuration = configuration) + } +} +object FileRepository { + def apply(name: String, configuration: sbt.librarymanagement.FileConfiguration, patterns: sbt.librarymanagement.Patterns) = + new FileRepository(name, patterns, configuration) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, configuration: sbt.librarymanagement.FileConfiguration): FileRepository = new FileRepository(name, patterns, configuration) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala new file mode 100644 index 000000000..31a282b3b --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait FileRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val FileRepositoryFormat: JsonFormat[sbt.librarymanagement.FileRepository] = new JsonFormat[sbt.librarymanagement.FileRepository] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileRepository = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + val configuration = unbuilder.readField[sbt.librarymanagement.FileConfiguration]("configuration") + unbuilder.endObject() + sbt.librarymanagement.FileRepository(name, patterns, configuration) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.FileRepository, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("patterns", obj.patterns) + builder.addField("configuration", obj.configuration) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala new file mode 100644 index 000000000..3ad99a43e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Cross-versions a module with the result of + * prepending `prefix` and appending `suffix` to the full version. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the full version is "2.12.1", + * the module is cross-versioned with "foo_2.12.1_bar". + */ +final class Full private ( + val prefix: String, + val suffix: String) extends sbt.librarymanagement.CrossVersion() with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: Full => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "Full".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "Full(" + prefix + ", " + suffix + ")" + } + protected[this] def copy(prefix: String = prefix, suffix: String = suffix): Full = { + new Full(prefix, suffix) + } + def withPrefix(prefix: String): Full = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): Full = { + copy(suffix = suffix) + } +} +object Full { + + def apply(): Full = new Full("", "") + def apply(prefix: String, suffix: String): Full = new Full(prefix, suffix) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala new file mode 100644 index 000000000..c44b95ef3 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait FullFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val FullFormat: JsonFormat[sbt.librarymanagement.Full] = new JsonFormat[sbt.librarymanagement.Full] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Full = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.Full(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Full, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala new file mode 100644 index 000000000..cd2032c80 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -0,0 +1,58 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Defines a rule to either: + *
    + *
  • Exclude unwanted dependencies pulled in transitively by a module, or to
  • + *
  • Include and merge artifacts coming from the ModuleDescriptor if "dependencyArtifacts" are also provided.
  • + *
+ * The use case that is applied depends on the parameter name which it is passed to, but the + * filter has the same fields in both cases. + */ +final class InclExclRule private ( + val organization: String, + val name: String, + val artifact: String, + val configurations: Vector[String], + val crossVersion: sbt.librarymanagement.CrossVersion) extends Serializable { + + private def this() = this("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) + + override def equals(o: Any): Boolean = o match { + case x: InclExclRule => (this.organization == x.organization) && (this.name == x.name) && (this.artifact == x.artifact) && (this.configurations == x.configurations) && (this.crossVersion == x.crossVersion) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "InclExclRule".##) + organization.##) + name.##) + artifact.##) + configurations.##) + crossVersion.##) + } + override def toString: String = { + "InclExclRule(" + organization + ", " + name + ", " + artifact + ", " + configurations + ", " + crossVersion + ")" + } + protected[this] def copy(organization: String = organization, name: String = name, artifact: String = artifact, configurations: Vector[String] = configurations, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion): InclExclRule = { + new InclExclRule(organization, name, artifact, configurations, crossVersion) + } + def withOrganization(organization: String): InclExclRule = { + copy(organization = organization) + } + def withName(name: String): InclExclRule = { + copy(name = name) + } + def withArtifact(artifact: String): InclExclRule = { + copy(artifact = artifact) + } + def withConfigurations(configurations: Vector[String]): InclExclRule = { + copy(configurations = configurations) + } + def withCrossVersion(crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = { + copy(crossVersion = crossVersion) + } +} +object InclExclRule extends sbt.librarymanagement.InclExclRuleFunctions { + + def apply(): InclExclRule = new InclExclRule("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) + def apply(organization: String, name: String, artifact: String, configurations: Vector[String], crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = new InclExclRule(organization, name, artifact, configurations, crossVersion) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala new file mode 100644 index 000000000..76a3c49b8 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InclExclRuleFormats { self: sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclRule] = new JsonFormat[sbt.librarymanagement.InclExclRule] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val organization = unbuilder.readField[String]("organization") + val name = unbuilder.readField[String]("name") + val artifact = unbuilder.readField[String]("artifact") + val configurations = unbuilder.readField[Vector[String]]("configurations") + val crossVersion = unbuilder.readField[sbt.librarymanagement.CrossVersion]("crossVersion") + unbuilder.endObject() + sbt.librarymanagement.InclExclRule(organization, name, artifact, configurations, crossVersion) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.InclExclRule, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("organization", obj.organization) + builder.addField("name", obj.name) + builder.addField("artifact", obj.artifact) + builder.addField("configurations", obj.configurations) + builder.addField("crossVersion", obj.crossVersion) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala new file mode 100644 index 000000000..13cc67247 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala @@ -0,0 +1,47 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InlineConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InlineConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.InlineConfiguration] = new JsonFormat[sbt.internal.librarymanagement.InlineConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.InlineConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val validate = unbuilder.readField[Boolean]("validate") + val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val module = unbuilder.readField[sbt.librarymanagement.ModuleID]("module") + val moduleInfo = unbuilder.readField[sbt.librarymanagement.ModuleInfo]("moduleInfo") + val dependencies = unbuilder.readField[Vector[sbt.librarymanagement.ModuleID]]("dependencies") + val overrides = unbuilder.readField[Set[sbt.librarymanagement.ModuleID]]("overrides") + val excludes = unbuilder.readField[Vector[sbt.librarymanagement.InclExclRule]]("excludes") + val ivyXML = unbuilder.readField[scala.xml.NodeSeq]("ivyXML") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val defaultConfiguration = unbuilder.readField[Option[sbt.librarymanagement.Configuration]]("defaultConfiguration") + val conflictManager = unbuilder.readField[sbt.librarymanagement.ConflictManager]("conflictManager") + unbuilder.endObject() + sbt.internal.librarymanagement.InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.InlineConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("validate", obj.validate) + builder.addField("ivyScala", obj.ivyScala) + builder.addField("module", obj.module) + builder.addField("moduleInfo", obj.moduleInfo) + builder.addField("dependencies", obj.dependencies) + builder.addField("overrides", obj.overrides) + builder.addField("excludes", obj.excludes) + builder.addField("ivyXML", obj.ivyXML) + builder.addField("configurations", obj.configurations) + builder.addField("defaultConfiguration", obj.defaultConfiguration) + builder.addField("conflictManager", obj.conflictManager) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala new file mode 100644 index 000000000..8adfd3620 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala @@ -0,0 +1,47 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.InlineIvyConfiguration] = new JsonFormat[sbt.internal.librarymanagement.InlineIvyConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.InlineIvyConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") + val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") + val log = unbuilder.readField[xsbti.Logger]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.UpdateOptions]("updateOptions") + val paths = unbuilder.readField[sbt.internal.librarymanagement.IvyPaths]("paths") + val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") + val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") + val moduleConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ModuleConfiguration]]("moduleConfigurations") + val checksums = unbuilder.readField[Vector[String]]("checksums") + val managedChecksums = unbuilder.readField[Boolean]("managedChecksums") + val resolutionCacheDir = unbuilder.readField[Option[java.io.File]]("resolutionCacheDir") + unbuilder.endObject() + sbt.internal.librarymanagement.InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.InlineIvyConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("lock", obj.lock) + builder.addField("baseDirectory", obj.baseDirectory) + builder.addField("log", obj.log) + builder.addField("updateOptions", obj.updateOptions) + builder.addField("paths", obj.paths) + builder.addField("resolvers", obj.resolvers) + builder.addField("otherResolvers", obj.otherResolvers) + builder.addField("moduleConfigurations", obj.moduleConfigurations) + builder.addField("checksums", obj.checksums) + builder.addField("managedChecksums", obj.managedChecksums) + builder.addField("resolutionCacheDir", obj.resolutionCacheDir) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala new file mode 100644 index 000000000..405edbbad --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InlineIvyConfigurationFormats with sbt.librarymanagement.ExternalIvyConfigurationFormats => +implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.IvyConfiguration] = flatUnionFormat2[sbt.internal.librarymanagement.IvyConfiguration, sbt.internal.librarymanagement.InlineIvyConfiguration, sbt.internal.librarymanagement.ExternalIvyConfiguration]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala new file mode 100644 index 000000000..2939baaa8 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -0,0 +1,48 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class IvyFileConfiguration private ( + validate: Boolean, + ivyScala: Option[sbt.librarymanagement.IvyScala], + val file: java.io.File, + val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: IvyFileConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "IvyFileConfiguration".##) + validate.##) + ivyScala.##) + file.##) + autoScalaTools.##) + } + override def toString: String = { + "IvyFileConfiguration(" + validate + ", " + ivyScala + ", " + file + ", " + autoScalaTools + ")" + } + protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): IvyFileConfiguration = { + new IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) + } + def withValidate(validate: Boolean): IvyFileConfiguration = { + copy(validate = validate) + } + def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): IvyFileConfiguration = { + copy(ivyScala = ivyScala) + } + def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): IvyFileConfiguration = { + copy(ivyScala = Option(ivyScala)) + } + def withFile(file: java.io.File): IvyFileConfiguration = { + copy(file = file) + } + def withAutoScalaTools(autoScalaTools: Boolean): IvyFileConfiguration = { + copy(autoScalaTools = autoScalaTools) + } +} +object IvyFileConfiguration { + + def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) + def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, Option(ivyScala), file, autoScalaTools) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala new file mode 100644 index 000000000..c675f4427 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait IvyFileConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val IvyFileConfigurationFormat: JsonFormat[sbt.librarymanagement.IvyFileConfiguration] = new JsonFormat[sbt.librarymanagement.IvyFileConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyFileConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val validate = unbuilder.readField[Boolean]("validate") + val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val file = unbuilder.readField[java.io.File]("file") + val autoScalaTools = unbuilder.readField[Boolean]("autoScalaTools") + unbuilder.endObject() + sbt.librarymanagement.IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.IvyFileConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("validate", obj.validate) + builder.addField("ivyScala", obj.ivyScala) + builder.addField("file", obj.file) + builder.addField("autoScalaTools", obj.autoScalaTools) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala new file mode 100644 index 000000000..506047e1e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait IvyPathsFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val IvyPathsFormat: JsonFormat[sbt.internal.librarymanagement.IvyPaths] = new JsonFormat[sbt.internal.librarymanagement.IvyPaths] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.IvyPaths = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") + val ivyHome = unbuilder.readField[Option[java.io.File]]("ivyHome") + unbuilder.endObject() + sbt.internal.librarymanagement.IvyPaths(baseDirectory, ivyHome) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.IvyPaths, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("baseDirectory", obj.baseDirectory) + builder.addField("ivyHome", obj.ivyHome) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala new file mode 100644 index 000000000..4bbde0dee --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala @@ -0,0 +1,61 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class IvyScala private ( + val scalaFullVersion: String, + val scalaBinaryVersion: String, + val configurations: Vector[sbt.librarymanagement.Configuration], + val checkExplicit: Boolean, + val filterImplicit: Boolean, + val overrideScalaVersion: Boolean, + val scalaOrganization: String, + val scalaArtifacts: scala.Vector[String]) extends Serializable { + + private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) + + override def equals(o: Any): Boolean = o match { + case x: IvyScala => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "IvyScala".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) + } + override def toString: String = { + "IvyScala(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" + } + protected[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): IvyScala = { + new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + } + def withScalaFullVersion(scalaFullVersion: String): IvyScala = { + copy(scalaFullVersion = scalaFullVersion) + } + def withScalaBinaryVersion(scalaBinaryVersion: String): IvyScala = { + copy(scalaBinaryVersion = scalaBinaryVersion) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): IvyScala = { + copy(configurations = configurations) + } + def withCheckExplicit(checkExplicit: Boolean): IvyScala = { + copy(checkExplicit = checkExplicit) + } + def withFilterImplicit(filterImplicit: Boolean): IvyScala = { + copy(filterImplicit = filterImplicit) + } + def withOverrideScalaVersion(overrideScalaVersion: Boolean): IvyScala = { + copy(overrideScalaVersion = overrideScalaVersion) + } + def withScalaOrganization(scalaOrganization: String): IvyScala = { + copy(scalaOrganization = scalaOrganization) + } + def withScalaArtifacts(scalaArtifacts: scala.Vector[String]): IvyScala = { + copy(scalaArtifacts = scalaArtifacts) + } +} +object IvyScala extends sbt.librarymanagement.IvyScalaFunctions { + + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): IvyScala = new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]): IvyScala = new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala new file mode 100644 index 000000000..b12207105 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait IvyScalaFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val IvyScalaFormat: JsonFormat[sbt.librarymanagement.IvyScala] = new JsonFormat[sbt.librarymanagement.IvyScala] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyScala = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val scalaFullVersion = unbuilder.readField[String]("scalaFullVersion") + val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val checkExplicit = unbuilder.readField[Boolean]("checkExplicit") + val filterImplicit = unbuilder.readField[Boolean]("filterImplicit") + val overrideScalaVersion = unbuilder.readField[Boolean]("overrideScalaVersion") + val scalaOrganization = unbuilder.readField[String]("scalaOrganization") + val scalaArtifacts = unbuilder.readField[scala.Vector[String]]("scalaArtifacts") + unbuilder.endObject() + sbt.librarymanagement.IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.IvyScala, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("scalaFullVersion", obj.scalaFullVersion) + builder.addField("scalaBinaryVersion", obj.scalaBinaryVersion) + builder.addField("configurations", obj.configurations) + builder.addField("checkExplicit", obj.checkExplicit) + builder.addField("filterImplicit", obj.filterImplicit) + builder.addField("overrideScalaVersion", obj.overrideScalaVersion) + builder.addField("scalaOrganization", obj.scalaOrganization) + builder.addField("scalaArtifacts", obj.scalaArtifacts) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala new file mode 100644 index 000000000..33742d372 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala @@ -0,0 +1,44 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class KeyFileAuthentication private ( + val user: String, + val keyfile: java.io.File, + val password: Option[String]) extends sbt.librarymanagement.SshAuthentication() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: KeyFileAuthentication => (this.user == x.user) && (this.keyfile == x.keyfile) && (this.password == x.password) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "KeyFileAuthentication".##) + user.##) + keyfile.##) + password.##) + } + override def toString: String = { + "KeyFileAuthentication(" + user + ", " + keyfile + ", " + password + ")" + } + protected[this] def copy(user: String = user, keyfile: java.io.File = keyfile, password: Option[String] = password): KeyFileAuthentication = { + new KeyFileAuthentication(user, keyfile, password) + } + def withUser(user: String): KeyFileAuthentication = { + copy(user = user) + } + def withKeyfile(keyfile: java.io.File): KeyFileAuthentication = { + copy(keyfile = keyfile) + } + def withPassword(password: Option[String]): KeyFileAuthentication = { + copy(password = password) + } + def withPassword(password: String): KeyFileAuthentication = { + copy(password = Option(password)) + } +} +object KeyFileAuthentication { + + def apply(user: String, keyfile: java.io.File, password: Option[String]): KeyFileAuthentication = new KeyFileAuthentication(user, keyfile, password) + def apply(user: String, keyfile: java.io.File, password: String): KeyFileAuthentication = new KeyFileAuthentication(user, keyfile, Option(password)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala new file mode 100644 index 000000000..965c48625 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait KeyFileAuthenticationFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val KeyFileAuthenticationFormat: JsonFormat[sbt.librarymanagement.KeyFileAuthentication] = new JsonFormat[sbt.librarymanagement.KeyFileAuthentication] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.KeyFileAuthentication = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val user = unbuilder.readField[String]("user") + val keyfile = unbuilder.readField[java.io.File]("keyfile") + val password = unbuilder.readField[Option[String]]("password") + unbuilder.endObject() + sbt.librarymanagement.KeyFileAuthentication(user, keyfile, password) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.KeyFileAuthentication, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("user", obj.user) + builder.addField("keyfile", obj.keyfile) + builder.addField("password", obj.password) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala new file mode 100644 index 000000000..9745a4d1a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -0,0 +1,66 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.ConfigurationFormats + with sbt.librarymanagement.ChecksumFormats + with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.ArtifactTypeFilterFormats + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.CrossVersionFormats + with sbt.librarymanagement.InclExclRuleFormats + with sbt.librarymanagement.ModuleIDFormats + with sbt.librarymanagement.CallerFormats + with sbt.librarymanagement.ModuleReportFormats + with sbt.librarymanagement.OrganizationArtifactReportFormats + with sbt.librarymanagement.ConfigurationReportFormats + with sbt.librarymanagement.ConflictManagerFormats + with sbt.librarymanagement.DeveloperFormats + with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.IvyScalaFormats + with sbt.librarymanagement.ChainedResolverFormats + with sbt.librarymanagement.MavenRepoFormats + with sbt.librarymanagement.MavenCacheFormats + with sbt.librarymanagement.PatternsFormats + with sbt.librarymanagement.FileRepositoryFormats + with sbt.librarymanagement.URLRepositoryFormats + with sbt.librarymanagement.PasswordAuthenticationFormats + with sbt.librarymanagement.KeyFileAuthenticationFormats + with sbt.librarymanagement.SshAuthenticationFormats + with sbt.librarymanagement.SshConnectionFormats + with sbt.librarymanagement.SshRepositoryFormats + with sbt.librarymanagement.SftpRepositoryFormats + with sbt.librarymanagement.ResolverFormats + with sbt.librarymanagement.ModuleConfigurationFormats + with sbt.librarymanagement.ScmInfoFormats + with sbt.librarymanagement.ModuleInfoFormats + with sbt.librarymanagement.IvyFileConfigurationFormats + with sbt.librarymanagement.PomConfigurationFormats + with sbt.internal.librarymanagement.formats.NodeSeqFormat + with sbt.librarymanagement.InlineConfigurationFormats + with sbt.librarymanagement.ModuleSettingsFormats + with sbt.librarymanagement.MavenRepositoryFormats + with sbt.librarymanagement.PatternsBasedRepositoryFormats + with sbt.librarymanagement.SshBasedRepositoryFormats + with sbt.librarymanagement.RetrieveConfigurationFormats + with sbt.librarymanagement.UpdateLoggingFormats + with sbt.librarymanagement.UpdateConfigurationFormats + with sbt.librarymanagement.UpdateStatsFormats + with sbt.librarymanagement.UpdateReportFormats + with sbt.librarymanagement.ConfigurationReportLiteFormats + with sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.internal.librarymanagement.formats.UpdateOptionsFormat + with sbt.librarymanagement.IvyPathsFormats + with sbt.librarymanagement.InlineIvyConfigurationFormats + with sbt.librarymanagement.ExternalIvyConfigurationFormats + with sbt.librarymanagement.IvyConfigurationFormats + with sbt.librarymanagement.UpdateReportLiteFormats +object LibraryManagementCodec extends LibraryManagementCodec \ No newline at end of file diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala new file mode 100644 index 000000000..5ecbb9173 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -0,0 +1,50 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * An instance of maven CACHE directory. You cannot treat a cache directory the same as a a remote repository because + * the metadata is different (see Aether ML discussion). + */ +final class MavenCache private ( + name: String, + root: String, + localIfFile: Boolean, + val rootFile: java.io.File) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { + def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile) + def isCache: Boolean = true + private def this(name: String, root: String, rootFile: java.io.File) = this(name, root, true, rootFile) + + override def equals(o: Any): Boolean = o match { + case x: MavenCache => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) && (this.rootFile == x.rootFile) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "MavenCache".##) + name.##) + root.##) + localIfFile.##) + rootFile.##) + } + override def toString: String = { + s"cache:$name: ${rootFile.getAbsolutePath}" + } + protected[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile, rootFile: java.io.File = rootFile): MavenCache = { + new MavenCache(name, root, localIfFile, rootFile) + } + def withName(name: String): MavenCache = { + copy(name = name) + } + def withRoot(root: String): MavenCache = { + copy(root = root) + } + def withLocalIfFile(localIfFile: Boolean): MavenCache = { + copy(localIfFile = localIfFile) + } + def withRootFile(rootFile: java.io.File): MavenCache = { + copy(rootFile = rootFile) + } +} +object MavenCache { + def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile) + def apply(name: String, root: String, rootFile: java.io.File): MavenCache = new MavenCache(name, root, true, rootFile) + def apply(name: String, root: String, localIfFile: Boolean, rootFile: java.io.File): MavenCache = new MavenCache(name, root, localIfFile, rootFile) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala new file mode 100644 index 000000000..4079ded96 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait MavenCacheFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val MavenCacheFormat: JsonFormat[sbt.librarymanagement.MavenCache] = new JsonFormat[sbt.librarymanagement.MavenCache] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenCache = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val root = unbuilder.readField[String]("root") + val localIfFile = unbuilder.readField[Boolean]("localIfFile") + val rootFile = unbuilder.readField[java.io.File]("rootFile") + unbuilder.endObject() + sbt.librarymanagement.MavenCache(name, root, localIfFile, rootFile) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.MavenCache, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("root", obj.root) + builder.addField("localIfFile", obj.localIfFile) + builder.addField("rootFile", obj.rootFile) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala new file mode 100644 index 000000000..1374e2d0b --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -0,0 +1,41 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class MavenRepo private ( + name: String, + root: String, + localIfFile: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { + def isCache: Boolean = false + private def this(name: String, root: String) = this(name, root, true) + + override def equals(o: Any): Boolean = o match { + case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "MavenRepo".##) + name.##) + root.##) + localIfFile.##) + } + override def toString: String = { + s"$name: $root" + } + protected[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile): MavenRepo = { + new MavenRepo(name, root, localIfFile) + } + def withName(name: String): MavenRepo = { + copy(name = name) + } + def withRoot(root: String): MavenRepo = { + copy(root = root) + } + def withLocalIfFile(localIfFile: Boolean): MavenRepo = { + copy(localIfFile = localIfFile) + } +} +object MavenRepo { + + def apply(name: String, root: String): MavenRepo = new MavenRepo(name, root, true) + def apply(name: String, root: String, localIfFile: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala new file mode 100644 index 000000000..235de9643 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait MavenRepoFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = new JsonFormat[sbt.librarymanagement.MavenRepo] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenRepo = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val root = unbuilder.readField[String]("root") + val localIfFile = unbuilder.readField[Boolean]("localIfFile") + unbuilder.endObject() + sbt.librarymanagement.MavenRepo(name, root, localIfFile) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.MavenRepo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("root", obj.root) + builder.addField("localIfFile", obj.localIfFile) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala new file mode 100644 index 000000000..b3487a7d4 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** An instance of a remote maven repository. Note: This will use Aether/Maven to resolve artifacts. */ +abstract class MavenRepository( + name: String, + val root: String, + val localIfFile: Boolean) extends sbt.librarymanagement.Resolver(name) with Serializable { + def isCache: Boolean + def this(name: String, root: String) = this(name, root, true) + + + override def equals(o: Any): Boolean = o match { + case x: MavenRepository => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "MavenRepository".##) + name.##) + root.##) + localIfFile.##) + } + override def toString: String = { + "MavenRepository(" + name + ", " + root + ", " + localIfFile + ")" + } +} +object MavenRepository extends sbt.librarymanagement.MavenRepositoryFunctions { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala new file mode 100644 index 000000000..6e8a14d3c --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait MavenRepositoryFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats => +implicit lazy val MavenRepositoryFormat: JsonFormat[sbt.librarymanagement.MavenRepository] = flatUnionFormat2[sbt.librarymanagement.MavenRepository, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala new file mode 100644 index 000000000..7198727a9 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala @@ -0,0 +1,45 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class ModuleConfiguration private ( + val organization: String, + val name: String, + val revision: String, + val resolver: sbt.librarymanagement.Resolver) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ModuleConfiguration => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.resolver == x.resolver) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "ModuleConfiguration".##) + organization.##) + name.##) + revision.##) + resolver.##) + } + override def toString: String = { + "ModuleConfiguration(" + organization + ", " + name + ", " + revision + ", " + resolver + ")" + } + protected[this] def copy(organization: String = organization, name: String = name, revision: String = revision, resolver: sbt.librarymanagement.Resolver = resolver): ModuleConfiguration = { + new ModuleConfiguration(organization, name, revision, resolver) + } + def withOrganization(organization: String): ModuleConfiguration = { + copy(organization = organization) + } + def withName(name: String): ModuleConfiguration = { + copy(name = name) + } + def withRevision(revision: String): ModuleConfiguration = { + copy(revision = revision) + } + def withResolver(resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = { + copy(resolver = resolver) + } +} +object ModuleConfiguration { + def apply(org: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = apply(org, "*", "*", resolver) + def apply(org: String, name: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = ModuleConfiguration(org, name, "*", resolver) + def apply(organization: String, name: String, revision: String, resolver: sbt.librarymanagement.Resolver): ModuleConfiguration = new ModuleConfiguration(organization, name, revision, resolver) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala new file mode 100644 index 000000000..8ac48ea5c --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ModuleConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val organization = unbuilder.readField[String]("organization") + val name = unbuilder.readField[String]("name") + val revision = unbuilder.readField[String]("revision") + val resolver = unbuilder.readField[sbt.librarymanagement.Resolver]("resolver") + unbuilder.endObject() + sbt.librarymanagement.ModuleConfiguration(organization, name, revision, resolver) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ModuleConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("organization", obj.organization) + builder.addField("name", obj.name) + builder.addField("revision", obj.revision) + builder.addField("resolver", obj.resolver) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala new file mode 100644 index 000000000..4e117921e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -0,0 +1,81 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class ModuleID private ( + val organization: String, + val name: String, + val revision: String, + val configurations: Option[String], + val isChanging: Boolean, + val isTransitive: Boolean, + val isForce: Boolean, + val explicitArtifacts: Vector[sbt.librarymanagement.Artifact], + val inclusions: Vector[sbt.librarymanagement.InclExclRule], + val exclusions: Vector[sbt.librarymanagement.InclExclRule], + val extraAttributes: Map[String, String], + val crossVersion: sbt.librarymanagement.CrossVersion, + val branchName: Option[String]) extends sbt.librarymanagement.ModuleIDExtra with Serializable { + + private def this(organization: String, name: String, revision: String) = this(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None) + + override def equals(o: Any): Boolean = o match { + case x: ModuleID => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.configurations == x.configurations) && (this.isChanging == x.isChanging) && (this.isTransitive == x.isTransitive) && (this.isForce == x.isForce) && (this.explicitArtifacts == x.explicitArtifacts) && (this.inclusions == x.inclusions) && (this.exclusions == x.exclusions) && (this.extraAttributes == x.extraAttributes) && (this.crossVersion == x.crossVersion) && (this.branchName == x.branchName) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) + } + override def toString: String = { + this.toStringImpl + } + protected[this] def copy(organization: String = organization, name: String = name, revision: String = revision, configurations: Option[String] = configurations, isChanging: Boolean = isChanging, isTransitive: Boolean = isTransitive, isForce: Boolean = isForce, explicitArtifacts: Vector[sbt.librarymanagement.Artifact] = explicitArtifacts, inclusions: Vector[sbt.librarymanagement.InclExclRule] = inclusions, exclusions: Vector[sbt.librarymanagement.InclExclRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion, branchName: Option[String] = branchName): ModuleID = { + new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) + } + def withOrganization(organization: String): ModuleID = { + copy(organization = organization) + } + def withName(name: String): ModuleID = { + copy(name = name) + } + def withRevision(revision: String): ModuleID = { + copy(revision = revision) + } + def withConfigurations(configurations: Option[String]): ModuleID = { + copy(configurations = configurations) + } + def withIsChanging(isChanging: Boolean): ModuleID = { + copy(isChanging = isChanging) + } + def withIsTransitive(isTransitive: Boolean): ModuleID = { + copy(isTransitive = isTransitive) + } + def withIsForce(isForce: Boolean): ModuleID = { + copy(isForce = isForce) + } + def withExplicitArtifacts(explicitArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleID = { + copy(explicitArtifacts = explicitArtifacts) + } + def withInclusions(inclusions: Vector[sbt.librarymanagement.InclExclRule]): ModuleID = { + copy(inclusions = inclusions) + } + def withExclusions(exclusions: Vector[sbt.librarymanagement.InclExclRule]): ModuleID = { + copy(exclusions = exclusions) + } + def withExtraAttributes(extraAttributes: Map[String, String]): ModuleID = { + copy(extraAttributes = extraAttributes) + } + def withCrossVersion(crossVersion: sbt.librarymanagement.CrossVersion): ModuleID = { + copy(crossVersion = crossVersion) + } + def withBranchName(branchName: Option[String]): ModuleID = { + copy(branchName = branchName) + } +} +object ModuleID extends sbt.librarymanagement.ModuleIDFunctions { + + def apply(organization: String, name: String, revision: String): ModuleID = new ModuleID(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None) + def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, isForce: Boolean, explicitArtifacts: Vector[sbt.librarymanagement.Artifact], inclusions: Vector[sbt.librarymanagement.InclExclRule], exclusions: Vector[sbt.librarymanagement.InclExclRule], extraAttributes: Map[String, String], crossVersion: sbt.librarymanagement.CrossVersion, branchName: Option[String]): ModuleID = new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala new file mode 100644 index 000000000..55d0d2fc4 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -0,0 +1,51 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = new JsonFormat[sbt.librarymanagement.ModuleID] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val organization = unbuilder.readField[String]("organization") + val name = unbuilder.readField[String]("name") + val revision = unbuilder.readField[String]("revision") + val configurations = unbuilder.readField[Option[String]]("configurations") + val isChanging = unbuilder.readField[Boolean]("isChanging") + val isTransitive = unbuilder.readField[Boolean]("isTransitive") + val isForce = unbuilder.readField[Boolean]("isForce") + val explicitArtifacts = unbuilder.readField[Vector[sbt.librarymanagement.Artifact]]("explicitArtifacts") + val inclusions = unbuilder.readField[Vector[sbt.librarymanagement.InclExclRule]]("inclusions") + val exclusions = unbuilder.readField[Vector[sbt.librarymanagement.InclExclRule]]("exclusions") + val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") + val crossVersion = unbuilder.readField[sbt.librarymanagement.CrossVersion]("crossVersion") + val branchName = unbuilder.readField[Option[String]]("branchName") + unbuilder.endObject() + sbt.librarymanagement.ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ModuleID, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("organization", obj.organization) + builder.addField("name", obj.name) + builder.addField("revision", obj.revision) + builder.addField("configurations", obj.configurations) + builder.addField("isChanging", obj.isChanging) + builder.addField("isTransitive", obj.isTransitive) + builder.addField("isForce", obj.isForce) + builder.addField("explicitArtifacts", obj.explicitArtifacts) + builder.addField("inclusions", obj.inclusions) + builder.addField("exclusions", obj.exclusions) + builder.addField("extraAttributes", obj.extraAttributes) + builder.addField("crossVersion", obj.crossVersion) + builder.addField("branchName", obj.branchName) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala new file mode 100644 index 000000000..ef9dc5ac1 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -0,0 +1,66 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Additional information about a project module */ +final class ModuleInfo private ( + val nameFormal: String, + val description: String, + val homepage: Option[java.net.URL], + val startYear: Option[Int], + val licenses: Vector[scala.Tuple2[String, java.net.URL]], + val organizationName: String, + val organizationHomepage: Option[java.net.URL], + val scmInfo: Option[sbt.librarymanagement.ScmInfo], + val developers: Vector[sbt.librarymanagement.Developer]) extends Serializable { + + private def this(nameFormal: String) = this(nameFormal, "", None, None, Vector.empty, "", None, None, Vector.empty) + + override def equals(o: Any): Boolean = o match { + case x: ModuleInfo => (this.nameFormal == x.nameFormal) && (this.description == x.description) && (this.homepage == x.homepage) && (this.startYear == x.startYear) && (this.licenses == x.licenses) && (this.organizationName == x.organizationName) && (this.organizationHomepage == x.organizationHomepage) && (this.scmInfo == x.scmInfo) && (this.developers == x.developers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleInfo".##) + nameFormal.##) + description.##) + homepage.##) + startYear.##) + licenses.##) + organizationName.##) + organizationHomepage.##) + scmInfo.##) + developers.##) + } + override def toString: String = { + "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" + } + protected[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { + new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) + } + def withNameFormal(nameFormal: String): ModuleInfo = { + copy(nameFormal = nameFormal) + } + def withDescription(description: String): ModuleInfo = { + copy(description = description) + } + def withHomepage(homepage: Option[java.net.URL]): ModuleInfo = { + copy(homepage = homepage) + } + def withStartYear(startYear: Option[Int]): ModuleInfo = { + copy(startYear = startYear) + } + def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URL]]): ModuleInfo = { + copy(licenses = licenses) + } + def withOrganizationName(organizationName: String): ModuleInfo = { + copy(organizationName = organizationName) + } + def withOrganizationHomepage(organizationHomepage: Option[java.net.URL]): ModuleInfo = { + copy(organizationHomepage = organizationHomepage) + } + def withScmInfo(scmInfo: Option[sbt.librarymanagement.ScmInfo]): ModuleInfo = { + copy(scmInfo = scmInfo) + } + def withDevelopers(developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = { + copy(developers = developers) + } +} +object ModuleInfo { + + def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal, "", None, None, Vector.empty, "", None, None, Vector.empty) + def apply(nameFormal: String, description: String, homepage: Option[java.net.URL], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URL]], organizationName: String, organizationHomepage: Option[java.net.URL], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala new file mode 100644 index 000000000..8d9c1c8b0 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ModuleInfoFormats { self: sbt.librarymanagement.ScmInfoFormats with sbt.librarymanagement.DeveloperFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ModuleInfoFormat: JsonFormat[sbt.librarymanagement.ModuleInfo] = new JsonFormat[sbt.librarymanagement.ModuleInfo] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleInfo = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val nameFormal = unbuilder.readField[String]("nameFormal") + val description = unbuilder.readField[String]("description") + val homepage = unbuilder.readField[Option[java.net.URL]]("homepage") + val startYear = unbuilder.readField[Option[Int]]("startYear") + val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URL]]]("licenses") + val organizationName = unbuilder.readField[String]("organizationName") + val organizationHomepage = unbuilder.readField[Option[java.net.URL]]("organizationHomepage") + val scmInfo = unbuilder.readField[Option[sbt.librarymanagement.ScmInfo]]("scmInfo") + val developers = unbuilder.readField[Vector[sbt.librarymanagement.Developer]]("developers") + unbuilder.endObject() + sbt.librarymanagement.ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ModuleInfo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("nameFormal", obj.nameFormal) + builder.addField("description", obj.description) + builder.addField("homepage", obj.homepage) + builder.addField("startYear", obj.startYear) + builder.addField("licenses", obj.licenses) + builder.addField("organizationName", obj.organizationName) + builder.addField("organizationHomepage", obj.organizationHomepage) + builder.addField("scmInfo", obj.scmInfo) + builder.addField("developers", obj.developers) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala new file mode 100644 index 000000000..625b142f2 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -0,0 +1,106 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Provides information about the resolution of a module. + * This information is in the context of a specific configuration. + */ +final class ModuleReport private ( + val module: sbt.librarymanagement.ModuleID, + val artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], + val missingArtifacts: Vector[sbt.librarymanagement.Artifact], + val status: Option[String], + val publicationDate: Option[java.util.Calendar], + val resolver: Option[String], + val artifactResolver: Option[String], + val evicted: Boolean, + val evictedData: Option[String], + val evictedReason: Option[String], + val problem: Option[String], + val homepage: Option[String], + val extraAttributes: Map[String, String], + val isDefault: Option[Boolean], + val branch: Option[String], + val configurations: Vector[String], + val licenses: Vector[scala.Tuple2[String, Option[String]]], + val callers: Vector[sbt.librarymanagement.Caller]) extends sbt.librarymanagement.ModuleReportExtra with Serializable { + + private def this(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]) = this(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map.empty, None, None, Vector.empty, Vector.empty, Vector.empty) + + override def equals(o: Any): Boolean = o match { + case x: ModuleReport => (this.module == x.module) && (this.artifacts == x.artifacts) && (this.missingArtifacts == x.missingArtifacts) && (this.status == x.status) && (this.publicationDate == x.publicationDate) && (this.resolver == x.resolver) && (this.artifactResolver == x.artifactResolver) && (this.evicted == x.evicted) && (this.evictedData == x.evictedData) && (this.evictedReason == x.evictedReason) && (this.problem == x.problem) && (this.homepage == x.homepage) && (this.extraAttributes == x.extraAttributes) && (this.isDefault == x.isDefault) && (this.branch == x.branch) && (this.configurations == x.configurations) && (this.licenses == x.licenses) && (this.callers == x.callers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleReport".##) + module.##) + artifacts.##) + missingArtifacts.##) + status.##) + publicationDate.##) + resolver.##) + artifactResolver.##) + evicted.##) + evictedData.##) + evictedReason.##) + problem.##) + homepage.##) + extraAttributes.##) + isDefault.##) + branch.##) + configurations.##) + licenses.##) + callers.##) + } + override def toString: String = { + s"\t\t$module: " + + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" + } + protected[this] def copy(module: sbt.librarymanagement.ModuleID = module, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, missingArtifacts: Vector[sbt.librarymanagement.Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[java.util.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, evictedData: Option[String] = evictedData, evictedReason: Option[String] = evictedReason, problem: Option[String] = problem, homepage: Option[String] = homepage, extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Vector[String] = configurations, licenses: Vector[scala.Tuple2[String, Option[String]]] = licenses, callers: Vector[sbt.librarymanagement.Caller] = callers): ModuleReport = { + new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) + } + def withModule(module: sbt.librarymanagement.ModuleID): ModuleReport = { + copy(module = module) + } + def withArtifacts(artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]]): ModuleReport = { + copy(artifacts = artifacts) + } + def withMissingArtifacts(missingArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleReport = { + copy(missingArtifacts = missingArtifacts) + } + def withStatus(status: Option[String]): ModuleReport = { + copy(status = status) + } + def withPublicationDate(publicationDate: Option[java.util.Calendar]): ModuleReport = { + copy(publicationDate = publicationDate) + } + def withResolver(resolver: Option[String]): ModuleReport = { + copy(resolver = resolver) + } + def withArtifactResolver(artifactResolver: Option[String]): ModuleReport = { + copy(artifactResolver = artifactResolver) + } + def withEvicted(evicted: Boolean): ModuleReport = { + copy(evicted = evicted) + } + def withEvictedData(evictedData: Option[String]): ModuleReport = { + copy(evictedData = evictedData) + } + def withEvictedReason(evictedReason: Option[String]): ModuleReport = { + copy(evictedReason = evictedReason) + } + def withProblem(problem: Option[String]): ModuleReport = { + copy(problem = problem) + } + def withHomepage(homepage: Option[String]): ModuleReport = { + copy(homepage = homepage) + } + def withExtraAttributes(extraAttributes: Map[String, String]): ModuleReport = { + copy(extraAttributes = extraAttributes) + } + def withIsDefault(isDefault: Option[Boolean]): ModuleReport = { + copy(isDefault = isDefault) + } + def withBranch(branch: Option[String]): ModuleReport = { + copy(branch = branch) + } + def withConfigurations(configurations: Vector[String]): ModuleReport = { + copy(configurations = configurations) + } + def withLicenses(licenses: Vector[scala.Tuple2[String, Option[String]]]): ModuleReport = { + copy(licenses = licenses) + } + def withCallers(callers: Vector[sbt.librarymanagement.Caller]): ModuleReport = { + copy(callers = callers) + } +} +object ModuleReport { + + def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map.empty, None, None, Vector.empty, Vector.empty, Vector.empty) + def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact], status: Option[String], publicationDate: Option[java.util.Calendar], resolver: Option[String], artifactResolver: Option[String], evicted: Boolean, evictedData: Option[String], evictedReason: Option[String], problem: Option[String], homepage: Option[String], extraAttributes: Map[String, String], isDefault: Option[Boolean], branch: Option[String], configurations: Vector[String], licenses: Vector[scala.Tuple2[String, Option[String]]], callers: Vector[sbt.librarymanagement.Caller]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala new file mode 100644 index 000000000..fedf5b263 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala @@ -0,0 +1,61 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.CallerFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ModuleReportFormat: JsonFormat[sbt.librarymanagement.ModuleReport] = new JsonFormat[sbt.librarymanagement.ModuleReport] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleReport = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val module = unbuilder.readField[sbt.librarymanagement.ModuleID]("module") + val artifacts = unbuilder.readField[Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]]]("artifacts") + val missingArtifacts = unbuilder.readField[Vector[sbt.librarymanagement.Artifact]]("missingArtifacts") + val status = unbuilder.readField[Option[String]]("status") + val publicationDate = unbuilder.readField[Option[java.util.Calendar]]("publicationDate") + val resolver = unbuilder.readField[Option[String]]("resolver") + val artifactResolver = unbuilder.readField[Option[String]]("artifactResolver") + val evicted = unbuilder.readField[Boolean]("evicted") + val evictedData = unbuilder.readField[Option[String]]("evictedData") + val evictedReason = unbuilder.readField[Option[String]]("evictedReason") + val problem = unbuilder.readField[Option[String]]("problem") + val homepage = unbuilder.readField[Option[String]]("homepage") + val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") + val isDefault = unbuilder.readField[Option[Boolean]]("isDefault") + val branch = unbuilder.readField[Option[String]]("branch") + val configurations = unbuilder.readField[Vector[String]]("configurations") + val licenses = unbuilder.readField[Vector[scala.Tuple2[String, Option[String]]]]("licenses") + val callers = unbuilder.readField[Vector[sbt.librarymanagement.Caller]]("callers") + unbuilder.endObject() + sbt.librarymanagement.ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ModuleReport, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("module", obj.module) + builder.addField("artifacts", obj.artifacts) + builder.addField("missingArtifacts", obj.missingArtifacts) + builder.addField("status", obj.status) + builder.addField("publicationDate", obj.publicationDate) + builder.addField("resolver", obj.resolver) + builder.addField("artifactResolver", obj.artifactResolver) + builder.addField("evicted", obj.evicted) + builder.addField("evictedData", obj.evictedData) + builder.addField("evictedReason", obj.evictedReason) + builder.addField("problem", obj.problem) + builder.addField("homepage", obj.homepage) + builder.addField("extraAttributes", obj.extraAttributes) + builder.addField("isDefault", obj.isDefault) + builder.addField("branch", obj.branch) + builder.addField("configurations", obj.configurations) + builder.addField("licenses", obj.licenses) + builder.addField("callers", obj.callers) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala new file mode 100644 index 000000000..e70a3b1f7 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +abstract class ModuleSettings( + val validate: Boolean, + val ivyScala: Option[sbt.librarymanagement.IvyScala]) extends Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: ModuleSettings => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "ModuleSettings".##) + validate.##) + ivyScala.##) + } + override def toString: String = { + "ModuleSettings(" + validate + ", " + ivyScala + ")" + } +} +object ModuleSettings { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala new file mode 100644 index 000000000..66ae6c37f --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait ModuleSettingsFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.InlineConfigurationFormats => +implicit lazy val ModuleSettingsFormat: JsonFormat[sbt.librarymanagement.ModuleSettings] = flatUnionFormat3[sbt.librarymanagement.ModuleSettings, sbt.librarymanagement.IvyFileConfiguration, sbt.librarymanagement.PomConfiguration, sbt.internal.librarymanagement.InlineConfiguration]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala new file mode 100644 index 000000000..daceb5658 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -0,0 +1,51 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * OrganizationArtifactReport represents an organization+name entry in Ivy resolution report. + * In sbt's terminology, "module" consists of organization, name, and version. + * In Ivy's, "module" means just organization and name, and the one including version numbers + * are called revisions. + * + * A sequence of OrganizationArtifactReport called details is newly added to ConfigurationReport, replacing evicted. + * (Note old evicted was just a seq of ModuleIDs). + * OrganizationArtifactReport groups the ModuleReport of both winners and evicted reports by their organization and name, + * which can be used to calculate detailed eviction warning etc. + */ +final class OrganizationArtifactReport private ( + val organization: String, + val name: String, + val modules: Vector[sbt.librarymanagement.ModuleReport]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: OrganizationArtifactReport => (this.organization == x.organization) && (this.name == x.name) && (this.modules == x.modules) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) + } + override def toString: String = { + "OrganizationArtifactReport(" + organization + ", " + name + ", " + modules + ")" + } + protected[this] def copy(organization: String = organization, name: String = name, modules: Vector[sbt.librarymanagement.ModuleReport] = modules): OrganizationArtifactReport = { + new OrganizationArtifactReport(organization, name, modules) + } + def withOrganization(organization: String): OrganizationArtifactReport = { + copy(organization = organization) + } + def withName(name: String): OrganizationArtifactReport = { + copy(name = name) + } + def withModules(modules: Vector[sbt.librarymanagement.ModuleReport]): OrganizationArtifactReport = { + copy(modules = modules) + } +} +object OrganizationArtifactReport { + + def apply(organization: String, name: String, modules: Vector[sbt.librarymanagement.ModuleReport]): OrganizationArtifactReport = new OrganizationArtifactReport(organization, name, modules) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala new file mode 100644 index 000000000..eacd8605c --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait OrganizationArtifactReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val OrganizationArtifactReportFormat: JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] = new JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.OrganizationArtifactReport = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val organization = unbuilder.readField[String]("organization") + val name = unbuilder.readField[String]("name") + val modules = unbuilder.readField[Vector[sbt.librarymanagement.ModuleReport]]("modules") + unbuilder.endObject() + sbt.librarymanagement.OrganizationArtifactReport(organization, name, modules) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.OrganizationArtifactReport, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("organization", obj.organization) + builder.addField("name", obj.name) + builder.addField("modules", obj.modules) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala new file mode 100644 index 000000000..ff71e1e0a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala @@ -0,0 +1,40 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class PasswordAuthentication private ( + val user: String, + val password: Option[String]) extends sbt.librarymanagement.SshAuthentication() with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: PasswordAuthentication => (this.user == x.user) && (this.password == x.password) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "PasswordAuthentication".##) + user.##) + password.##) + } + override def toString: String = { + "PasswordAuthentication(" + user + ", " + password + ")" + } + protected[this] def copy(user: String = user, password: Option[String] = password): PasswordAuthentication = { + new PasswordAuthentication(user, password) + } + def withUser(user: String): PasswordAuthentication = { + copy(user = user) + } + def withPassword(password: Option[String]): PasswordAuthentication = { + copy(password = password) + } + def withPassword(password: String): PasswordAuthentication = { + copy(password = Option(password)) + } +} +object PasswordAuthentication { + + def apply(user: String, password: Option[String]): PasswordAuthentication = new PasswordAuthentication(user, password) + def apply(user: String, password: String): PasswordAuthentication = new PasswordAuthentication(user, Option(password)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala new file mode 100644 index 000000000..0ece82e2a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PasswordAuthenticationFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val PasswordAuthenticationFormat: JsonFormat[sbt.librarymanagement.PasswordAuthentication] = new JsonFormat[sbt.librarymanagement.PasswordAuthentication] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PasswordAuthentication = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val user = unbuilder.readField[String]("user") + val password = unbuilder.readField[Option[String]]("password") + unbuilder.endObject() + sbt.librarymanagement.PasswordAuthentication(user, password) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.PasswordAuthentication, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("user", obj.user) + builder.addField("password", obj.password) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala new file mode 100644 index 000000000..f6cefff42 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Cross-versions a module by stripping off -bin-suffix. + * This is intended for patch-version compatible alternative replacements. + */ +final class Patch private () extends sbt.librarymanagement.CrossVersion() with Serializable { + + + +override def equals(o: Any): Boolean = o match { + case x: Patch => true + case _ => false +} +override def hashCode: Int = { + 37 * (17 + "Patch".##) +} +override def toString: String = { + "Patch()" +} +protected[this] def copy(): Patch = { + new Patch() +} + +} +object Patch { + + def apply(): Patch = new Patch() +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala new file mode 100644 index 000000000..c419fcb6a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PatchFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val PatchFormat: JsonFormat[sbt.librarymanagement.Patch] = new JsonFormat[sbt.librarymanagement.Patch] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Patch = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.librarymanagement.Patch() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Patch, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala new file mode 100644 index 000000000..5457c8a4a --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -0,0 +1,50 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class Patterns private ( + val ivyPatterns: Vector[String], + val artifactPatterns: Vector[String], + val isMavenCompatible: Boolean, + val descriptorOptional: Boolean, + val skipConsistencyCheck: Boolean) extends Serializable { + + private def this() = this(Vector.empty, Vector.empty, true, false, false) + + override def equals(o: Any): Boolean = o match { + case x: Patterns => (this.ivyPatterns == x.ivyPatterns) && (this.artifactPatterns == x.artifactPatterns) && (this.isMavenCompatible == x.isMavenCompatible) && (this.descriptorOptional == x.descriptorOptional) && (this.skipConsistencyCheck == x.skipConsistencyCheck) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "Patterns".##) + ivyPatterns.##) + artifactPatterns.##) + isMavenCompatible.##) + descriptorOptional.##) + skipConsistencyCheck.##) + } + override def toString: String = { + "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format( + ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + } + protected[this] def copy(ivyPatterns: Vector[String] = ivyPatterns, artifactPatterns: Vector[String] = artifactPatterns, isMavenCompatible: Boolean = isMavenCompatible, descriptorOptional: Boolean = descriptorOptional, skipConsistencyCheck: Boolean = skipConsistencyCheck): Patterns = { + new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + } + def withIvyPatterns(ivyPatterns: Vector[String]): Patterns = { + copy(ivyPatterns = ivyPatterns) + } + def withArtifactPatterns(artifactPatterns: Vector[String]): Patterns = { + copy(artifactPatterns = artifactPatterns) + } + def withIsMavenCompatible(isMavenCompatible: Boolean): Patterns = { + copy(isMavenCompatible = isMavenCompatible) + } + def withDescriptorOptional(descriptorOptional: Boolean): Patterns = { + copy(descriptorOptional = descriptorOptional) + } + def withSkipConsistencyCheck(skipConsistencyCheck: Boolean): Patterns = { + copy(skipConsistencyCheck = skipConsistencyCheck) + } +} +object Patterns extends sbt.librarymanagement.PatternsFunctions { + + def apply(): Patterns = new Patterns(Vector.empty, Vector.empty, true, false, false) + def apply(ivyPatterns: Vector[String], artifactPatterns: Vector[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala new file mode 100644 index 000000000..8354c6b44 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala @@ -0,0 +1,28 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** sbt interface to an Ivy repository based on patterns, which is most Ivy repositories. */ +abstract class PatternsBasedRepository( + name: String, + val patterns: sbt.librarymanagement.Patterns) extends sbt.librarymanagement.Resolver(name) with Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: PatternsBasedRepository => (this.name == x.name) && (this.patterns == x.patterns) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "PatternsBasedRepository".##) + name.##) + patterns.##) + } + override def toString: String = { + "PatternsBasedRepository(" + name + ", " + patterns + ")" + } +} +object PatternsBasedRepository { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala new file mode 100644 index 000000000..a63b8da50 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +implicit lazy val PatternsBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.PatternsBasedRepository] = flatUnionFormat4[sbt.librarymanagement.PatternsBasedRepository, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala new file mode 100644 index 000000000..b530299c2 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PatternsFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val PatternsFormat: JsonFormat[sbt.librarymanagement.Patterns] = new JsonFormat[sbt.librarymanagement.Patterns] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Patterns = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val ivyPatterns = unbuilder.readField[Vector[String]]("ivyPatterns") + val artifactPatterns = unbuilder.readField[Vector[String]]("artifactPatterns") + val isMavenCompatible = unbuilder.readField[Boolean]("isMavenCompatible") + val descriptorOptional = unbuilder.readField[Boolean]("descriptorOptional") + val skipConsistencyCheck = unbuilder.readField[Boolean]("skipConsistencyCheck") + unbuilder.endObject() + sbt.librarymanagement.Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Patterns, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("ivyPatterns", obj.ivyPatterns) + builder.addField("artifactPatterns", obj.artifactPatterns) + builder.addField("isMavenCompatible", obj.isMavenCompatible) + builder.addField("descriptorOptional", obj.descriptorOptional) + builder.addField("skipConsistencyCheck", obj.skipConsistencyCheck) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala new file mode 100644 index 000000000..ff9b16137 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -0,0 +1,48 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class PomConfiguration private ( + validate: Boolean, + ivyScala: Option[sbt.librarymanagement.IvyScala], + val file: java.io.File, + val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: PomConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "PomConfiguration".##) + validate.##) + ivyScala.##) + file.##) + autoScalaTools.##) + } + override def toString: String = { + "PomConfiguration(" + validate + ", " + ivyScala + ", " + file + ", " + autoScalaTools + ")" + } + protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): PomConfiguration = { + new PomConfiguration(validate, ivyScala, file, autoScalaTools) + } + def withValidate(validate: Boolean): PomConfiguration = { + copy(validate = validate) + } + def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): PomConfiguration = { + copy(ivyScala = ivyScala) + } + def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): PomConfiguration = { + copy(ivyScala = Option(ivyScala)) + } + def withFile(file: java.io.File): PomConfiguration = { + copy(file = file) + } + def withAutoScalaTools(autoScalaTools: Boolean): PomConfiguration = { + copy(autoScalaTools = autoScalaTools) + } +} +object PomConfiguration { + + def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, ivyScala, file, autoScalaTools) + def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, Option(ivyScala), file, autoScalaTools) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala new file mode 100644 index 000000000..e8a2a787d --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PomConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val PomConfigurationFormat: JsonFormat[sbt.librarymanagement.PomConfiguration] = new JsonFormat[sbt.librarymanagement.PomConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PomConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val validate = unbuilder.readField[Boolean]("validate") + val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val file = unbuilder.readField[java.io.File]("file") + val autoScalaTools = unbuilder.readField[Boolean]("autoScalaTools") + unbuilder.endObject() + sbt.librarymanagement.PomConfiguration(validate, ivyScala, file, autoScalaTools) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.PomConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("validate", obj.validate) + builder.addField("ivyScala", obj.ivyScala) + builder.addField("file", obj.file) + builder.addField("autoScalaTools", obj.autoScalaTools) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala new file mode 100644 index 000000000..792d0daa6 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -0,0 +1,26 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +abstract class Resolver( + val name: String) extends Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: Resolver => (this.name == x.name) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "Resolver".##) + name.##) + } + override def toString: String = { + "Resolver(" + name + ")" + } +} +object Resolver extends sbt.librarymanagement.ResolverFunctions { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala new file mode 100644 index 000000000..dc1daceea --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +implicit lazy val ResolverFormat: JsonFormat[sbt.librarymanagement.Resolver] = flatUnionFormat7[sbt.librarymanagement.Resolver, sbt.librarymanagement.ChainedResolver, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala new file mode 100644 index 000000000..9fbb51b2d --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait RetrieveConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] = new JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.RetrieveConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val retrieveDirectory = unbuilder.readField[java.io.File]("retrieveDirectory") + val outputPattern = unbuilder.readField[String]("outputPattern") + val sync = unbuilder.readField[Boolean]("sync") + val configurationsToRetrieve = unbuilder.readField[Option[Set[sbt.librarymanagement.Configuration]]]("configurationsToRetrieve") + unbuilder.endObject() + sbt.internal.librarymanagement.RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.RetrieveConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("retrieveDirectory", obj.retrieveDirectory) + builder.addField("outputPattern", obj.outputPattern) + builder.addField("sync", obj.sync) + builder.addField("configurationsToRetrieve", obj.configurationsToRetrieve) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala new file mode 100644 index 000000000..701bfc4b1 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -0,0 +1,46 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** Basic SCM information for a project module */ +final class ScmInfo private ( + val browseUrl: java.net.URL, + val connection: String, + val devConnection: Option[String]) extends Serializable { + + private def this(browseUrl: java.net.URL, connection: String) = this(browseUrl, connection, None) + + override def equals(o: Any): Boolean = o match { + case x: ScmInfo => (this.browseUrl == x.browseUrl) && (this.connection == x.connection) && (this.devConnection == x.devConnection) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "ScmInfo".##) + browseUrl.##) + connection.##) + devConnection.##) + } + override def toString: String = { + "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" + } + protected[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { + new ScmInfo(browseUrl, connection, devConnection) + } + def withBrowseUrl(browseUrl: java.net.URL): ScmInfo = { + copy(browseUrl = browseUrl) + } + def withConnection(connection: String): ScmInfo = { + copy(connection = connection) + } + def withDevConnection(devConnection: Option[String]): ScmInfo = { + copy(devConnection = devConnection) + } + def withDevConnection(devConnection: String): ScmInfo = { + copy(devConnection = Option(devConnection)) + } +} +object ScmInfo { + + def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection, None) + def apply(browseUrl: java.net.URL, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) + def apply(browseUrl: java.net.URL, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala new file mode 100644 index 000000000..38e04f37d --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ScmInfoFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ScmInfoFormat: JsonFormat[sbt.librarymanagement.ScmInfo] = new JsonFormat[sbt.librarymanagement.ScmInfo] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScmInfo = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val browseUrl = unbuilder.readField[java.net.URL]("browseUrl") + val connection = unbuilder.readField[String]("connection") + val devConnection = unbuilder.readField[Option[String]]("devConnection") + unbuilder.endObject() + sbt.librarymanagement.ScmInfo(browseUrl, connection, devConnection) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ScmInfo, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("browseUrl", obj.browseUrl) + builder.addField("connection", obj.connection) + builder.addField("devConnection", obj.devConnection) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala new file mode 100644 index 000000000..b2a4fe6fc --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** sbt interface for an Ivy repository over sftp. More convenient construction is done using Resolver.sftp. */ +final class SftpRepository private ( + name: String, + patterns: sbt.librarymanagement.Patterns, + connection: sbt.librarymanagement.SshConnection) extends sbt.librarymanagement.SshBasedRepository(name, patterns, connection) with sbt.librarymanagement.SftpRepositoryExtra with Serializable { + def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = + this(name, patterns, connection) + + + override def equals(o: Any): Boolean = o match { + case x: SftpRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "SftpRepository".##) + name.##) + patterns.##) + connection.##) + } + override def toString: String = { + "SftpRepository(" + name + ", " + patterns + ", " + connection + ")" + } + protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection): SftpRepository = { + new SftpRepository(name, patterns, connection) + } + def withName(name: String): SftpRepository = { + copy(name = name) + } + def withPatterns(patterns: sbt.librarymanagement.Patterns): SftpRepository = { + copy(patterns = patterns) + } + def withConnection(connection: sbt.librarymanagement.SshConnection): SftpRepository = { + copy(connection = connection) + } +} +object SftpRepository { + def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns) = + new SftpRepository(name, patterns, connection) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, connection: sbt.librarymanagement.SshConnection): SftpRepository = new SftpRepository(name, patterns, connection) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala new file mode 100644 index 000000000..43932f61e --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + val connection = unbuilder.readField[sbt.librarymanagement.SshConnection]("connection") + unbuilder.endObject() + sbt.librarymanagement.SftpRepository(name, patterns, connection) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.SftpRepository, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("patterns", obj.patterns) + builder.addField("connection", obj.connection) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala new file mode 100644 index 000000000..96b0ec553 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala @@ -0,0 +1,25 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +abstract class SshAuthentication() extends Serializable { + + + + +override def equals(o: Any): Boolean = o match { + case x: SshAuthentication => true + case _ => false +} +override def hashCode: Int = { + 37 * (17 + "SshAuthentication".##) +} +override def toString: String = { + "SshAuthentication()" +} +} +object SshAuthentication { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala new file mode 100644 index 000000000..4539a2598 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait SshAuthenticationFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.PasswordAuthenticationFormats with sbt.librarymanagement.KeyFileAuthenticationFormats => +implicit lazy val SshAuthenticationFormat: JsonFormat[sbt.librarymanagement.SshAuthentication] = flatUnionFormat2[sbt.librarymanagement.SshAuthentication, sbt.librarymanagement.PasswordAuthentication, sbt.librarymanagement.KeyFileAuthentication]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala new file mode 100644 index 000000000..484b74778 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** sbt interface for an Ivy ssh-based repository (ssh and sftp). Requires the Jsch library.. */ +abstract class SshBasedRepository( + name: String, + patterns: sbt.librarymanagement.Patterns, + val connection: sbt.librarymanagement.SshConnection) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with sbt.librarymanagement.SshBasedRepositoryExtra with Serializable { + + + + + override def equals(o: Any): Boolean = o match { + case x: SshBasedRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "SshBasedRepository".##) + name.##) + patterns.##) + connection.##) + } + override def toString: String = { + "SshBasedRepository(" + name + ", " + patterns + ", " + connection + ")" + } +} +object SshBasedRepository { + +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala new file mode 100644 index 000000000..c7f0bff21 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +implicit lazy val SshBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.SshBasedRepository] = flatUnionFormat2[sbt.librarymanagement.SshBasedRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala new file mode 100644 index 000000000..185d9b8f5 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala @@ -0,0 +1,50 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class SshConnection private ( + val authentication: Option[sbt.librarymanagement.SshAuthentication], + val hostname: Option[String], + val port: Option[Int]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: SshConnection => (this.authentication == x.authentication) && (this.hostname == x.hostname) && (this.port == x.port) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "SshConnection".##) + authentication.##) + hostname.##) + port.##) + } + override def toString: String = { + "SshConnection(" + authentication + ", " + hostname + ", " + port + ")" + } + protected[this] def copy(authentication: Option[sbt.librarymanagement.SshAuthentication] = authentication, hostname: Option[String] = hostname, port: Option[Int] = port): SshConnection = { + new SshConnection(authentication, hostname, port) + } + def withAuthentication(authentication: Option[sbt.librarymanagement.SshAuthentication]): SshConnection = { + copy(authentication = authentication) + } + def withAuthentication(authentication: sbt.librarymanagement.SshAuthentication): SshConnection = { + copy(authentication = Option(authentication)) + } + def withHostname(hostname: Option[String]): SshConnection = { + copy(hostname = hostname) + } + def withHostname(hostname: String): SshConnection = { + copy(hostname = Option(hostname)) + } + def withPort(port: Option[Int]): SshConnection = { + copy(port = port) + } + def withPort(port: Int): SshConnection = { + copy(port = Option(port)) + } +} +object SshConnection { + + def apply(authentication: Option[sbt.librarymanagement.SshAuthentication], hostname: Option[String], port: Option[Int]): SshConnection = new SshConnection(authentication, hostname, port) + def apply(authentication: sbt.librarymanagement.SshAuthentication, hostname: String, port: Int): SshConnection = new SshConnection(Option(authentication), Option(hostname), Option(port)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala new file mode 100644 index 000000000..ec0e4cb74 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val SshConnectionFormat: JsonFormat[sbt.librarymanagement.SshConnection] = new JsonFormat[sbt.librarymanagement.SshConnection] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val authentication = unbuilder.readField[Option[sbt.librarymanagement.SshAuthentication]]("authentication") + val hostname = unbuilder.readField[Option[String]]("hostname") + val port = unbuilder.readField[Option[Int]]("port") + unbuilder.endObject() + sbt.librarymanagement.SshConnection(authentication, hostname, port) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.SshConnection, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("authentication", obj.authentication) + builder.addField("hostname", obj.hostname) + builder.addField("port", obj.port) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala new file mode 100644 index 000000000..9a65cfeae --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala @@ -0,0 +1,51 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** sbt interface for an Ivy repository over ssh. More convenient construction is done using Resolver.ssh. */ +final class SshRepository private ( + name: String, + patterns: sbt.librarymanagement.Patterns, + connection: sbt.librarymanagement.SshConnection, + val publishPermissions: Option[String]) extends sbt.librarymanagement.SshBasedRepository(name, patterns, connection) with sbt.librarymanagement.SshRepositoryExtra with Serializable { + def this(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = + this(name, patterns, connection, publishPermissions) + + + override def equals(o: Any): Boolean = o match { + case x: SshRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) && (this.publishPermissions == x.publishPermissions) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "SshRepository".##) + name.##) + patterns.##) + connection.##) + publishPermissions.##) + } + override def toString: String = { + "SshRepository(" + name + ", " + patterns + ", " + connection + ", " + publishPermissions + ")" + } + protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection, publishPermissions: Option[String] = publishPermissions): SshRepository = { + new SshRepository(name, patterns, connection, publishPermissions) + } + def withName(name: String): SshRepository = { + copy(name = name) + } + def withPatterns(patterns: sbt.librarymanagement.Patterns): SshRepository = { + copy(patterns = patterns) + } + def withConnection(connection: sbt.librarymanagement.SshConnection): SshRepository = { + copy(connection = connection) + } + def withPublishPermissions(publishPermissions: Option[String]): SshRepository = { + copy(publishPermissions = publishPermissions) + } + def withPublishPermissions(publishPermissions: String): SshRepository = { + copy(publishPermissions = Option(publishPermissions)) + } +} +object SshRepository { + def apply(name: String, connection: sbt.librarymanagement.SshConnection, patterns: sbt.librarymanagement.Patterns, publishPermissions: Option[String]) = + new SshRepository(name, patterns, connection, publishPermissions) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, connection: sbt.librarymanagement.SshConnection, publishPermissions: Option[String]): SshRepository = new SshRepository(name, patterns, connection, publishPermissions) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, connection: sbt.librarymanagement.SshConnection, publishPermissions: String): SshRepository = new SshRepository(name, patterns, connection, Option(publishPermissions)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala new file mode 100644 index 000000000..3f6284b2f --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + val connection = unbuilder.readField[sbt.librarymanagement.SshConnection]("connection") + val publishPermissions = unbuilder.readField[Option[String]]("publishPermissions") + unbuilder.endObject() + sbt.librarymanagement.SshRepository(name, patterns, connection, publishPermissions) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.SshRepository, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("patterns", obj.patterns) + builder.addField("connection", obj.connection) + builder.addField("publishPermissions", obj.publishPermissions) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala new file mode 100644 index 000000000..2120a339b --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -0,0 +1,36 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class URLRepository private ( + name: String, + patterns: sbt.librarymanagement.Patterns) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "URLRepository".##) + name.##) + patterns.##) + } + override def toString: String = { + "URLRepository(" + name + ", " + patterns + ")" + } + protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns): URLRepository = { + new URLRepository(name, patterns) + } + def withName(name: String): URLRepository = { + copy(name = name) + } + def withPatterns(patterns: sbt.librarymanagement.Patterns): URLRepository = { + copy(patterns = patterns) + } +} +object URLRepository { + + def apply(name: String, patterns: sbt.librarymanagement.Patterns): URLRepository = new URLRepository(name, patterns) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala new file mode 100644 index 000000000..dbf9e9cfa --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala @@ -0,0 +1,29 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait URLRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepository] = new JsonFormat[sbt.librarymanagement.URLRepository] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.URLRepository = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + unbuilder.endObject() + sbt.librarymanagement.URLRepository(name, patterns) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.URLRepository, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.addField("patterns", obj.patterns) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala new file mode 100644 index 000000000..de5773eed --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -0,0 +1,56 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class UpdateConfiguration private ( + val retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration], + val missingOk: Boolean, + val logging: sbt.librarymanagement.UpdateLogging, + val artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, + val offline: Boolean, + val frozen: Boolean) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: UpdateConfiguration => (this.retrieve == x.retrieve) && (this.missingOk == x.missingOk) && (this.logging == x.logging) && (this.artifactFilter == x.artifactFilter) && (this.offline == x.offline) && (this.frozen == x.frozen) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "UpdateConfiguration".##) + retrieve.##) + missingOk.##) + logging.##) + artifactFilter.##) + offline.##) + frozen.##) + } + override def toString: String = { + "UpdateConfiguration(" + retrieve + ", " + missingOk + ", " + logging + ", " + artifactFilter + ", " + offline + ", " + frozen + ")" + } + protected[this] def copy(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration] = retrieve, missingOk: Boolean = missingOk, logging: sbt.librarymanagement.UpdateLogging = logging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter = artifactFilter, offline: Boolean = offline, frozen: Boolean = frozen): UpdateConfiguration = { + new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) + } + def withRetrieve(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration]): UpdateConfiguration = { + copy(retrieve = retrieve) + } + def withRetrieve(retrieve: sbt.internal.librarymanagement.RetrieveConfiguration): UpdateConfiguration = { + copy(retrieve = Option(retrieve)) + } + def withMissingOk(missingOk: Boolean): UpdateConfiguration = { + copy(missingOk = missingOk) + } + def withLogging(logging: sbt.librarymanagement.UpdateLogging): UpdateConfiguration = { + copy(logging = logging) + } + def withArtifactFilter(artifactFilter: sbt.librarymanagement.ArtifactTypeFilter): UpdateConfiguration = { + copy(artifactFilter = artifactFilter) + } + def withOffline(offline: Boolean): UpdateConfiguration = { + copy(offline = offline) + } + def withFrozen(frozen: Boolean): UpdateConfiguration = { + copy(frozen = frozen) + } +} +object UpdateConfiguration { + + def apply(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration], missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) + def apply(retrieve: sbt.internal.librarymanagement.RetrieveConfiguration, missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(Option(retrieve), missingOk, logging, artifactFilter, offline, frozen) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala new file mode 100644 index 000000000..fe2d47956 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.librarymanagement.ArtifactTypeFilterFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val UpdateConfigurationFormat: JsonFormat[sbt.librarymanagement.UpdateConfiguration] = new JsonFormat[sbt.librarymanagement.UpdateConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val retrieve = unbuilder.readField[Option[sbt.internal.librarymanagement.RetrieveConfiguration]]("retrieve") + val missingOk = unbuilder.readField[Boolean]("missingOk") + val logging = unbuilder.readField[sbt.librarymanagement.UpdateLogging]("logging") + val artifactFilter = unbuilder.readField[sbt.librarymanagement.ArtifactTypeFilter]("artifactFilter") + val offline = unbuilder.readField[Boolean]("offline") + val frozen = unbuilder.readField[Boolean]("frozen") + unbuilder.endObject() + sbt.librarymanagement.UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.UpdateConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("retrieve", obj.retrieve) + builder.addField("missingOk", obj.missingOk) + builder.addField("logging", obj.logging) + builder.addField("artifactFilter", obj.artifactFilter) + builder.addField("offline", obj.offline) + builder.addField("frozen", obj.frozen) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala new file mode 100644 index 000000000..f749ef9d5 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala @@ -0,0 +1,22 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Configures logging during an 'update'. `level` determines the amount of other information logged. + * `Full` is the default and logs the most. + * `DownloadOnly` only logs what is downloaded. + * `Quiet` only displays errors. + * `Default` uses the current log level of `update` task. + */ +sealed abstract class UpdateLogging extends Serializable +object UpdateLogging { + + + case object Full extends UpdateLogging + case object DownloadOnly extends UpdateLogging + case object Quiet extends UpdateLogging + case object Default extends UpdateLogging +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala new file mode 100644 index 000000000..77e18d19c --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait UpdateLoggingFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val UpdateLoggingFormat: JsonFormat[sbt.librarymanagement.UpdateLogging] = new JsonFormat[sbt.librarymanagement.UpdateLogging] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateLogging = { + jsOpt match { + case Some(js) => + unbuilder.readString(js) match { + case "Full" => sbt.librarymanagement.UpdateLogging.Full + case "DownloadOnly" => sbt.librarymanagement.UpdateLogging.DownloadOnly + case "Quiet" => sbt.librarymanagement.UpdateLogging.Quiet + case "Default" => sbt.librarymanagement.UpdateLogging.Default + } + case None => + deserializationError("Expected JsString but found None") + } + } + override def write[J](obj: sbt.librarymanagement.UpdateLogging, builder: Builder[J]): Unit = { + val str = obj match { + case sbt.librarymanagement.UpdateLogging.Full => "Full" + case sbt.librarymanagement.UpdateLogging.DownloadOnly => "DownloadOnly" + case sbt.librarymanagement.UpdateLogging.Quiet => "Quiet" + case sbt.librarymanagement.UpdateLogging.Default => "Default" + } + builder.writeString(str) + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala new file mode 100644 index 000000000..00b9e8225 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -0,0 +1,52 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Provides information about dependency resolution. + * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. + * This means that for a given configuration, there should only be one revision for a given organization and module name. + */ +final class UpdateReport private ( + /** the location of the resolved module descriptor in the cache */ + val cachedDescriptor: java.io.File, + /** a sequence containing one report for each configuration resolved. */ + val configurations: Vector[sbt.librarymanagement.ConfigurationReport], + /** stats information about the update that produced this report */ + val stats: sbt.librarymanagement.UpdateStats, + val stamps: Map[java.io.File, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: UpdateReport => (this.cachedDescriptor == x.cachedDescriptor) && (this.configurations == x.configurations) && (this.stats == x.stats) && (this.stamps == x.stamps) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "UpdateReport".##) + cachedDescriptor.##) + configurations.##) + stats.##) + stamps.##) + } + override def toString: String = { + "Update report:\n\t" + stats + "\n" + configurations.mkString + } + protected[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { + new UpdateReport(cachedDescriptor, configurations, stats, stamps) + } + def withCachedDescriptor(cachedDescriptor: java.io.File): UpdateReport = { + copy(cachedDescriptor = cachedDescriptor) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigurationReport]): UpdateReport = { + copy(configurations = configurations) + } + def withStats(stats: sbt.librarymanagement.UpdateStats): UpdateReport = { + copy(stats = stats) + } + def withStamps(stamps: Map[java.io.File, Long]): UpdateReport = { + copy(stamps = stamps) + } +} +object UpdateReport { + + def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[java.io.File, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala new file mode 100644 index 000000000..54e858000 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait UpdateReportFormats { self: sbt.librarymanagement.ConfigurationReportFormats with sbt.librarymanagement.UpdateStatsFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateReport] = new JsonFormat[sbt.librarymanagement.UpdateReport] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateReport = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val cachedDescriptor = unbuilder.readField[java.io.File]("cachedDescriptor") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigurationReport]]("configurations") + val stats = unbuilder.readField[sbt.librarymanagement.UpdateStats]("stats") + val stamps = unbuilder.readField[Map[java.io.File, Long]]("stamps") + unbuilder.endObject() + sbt.librarymanagement.UpdateReport(cachedDescriptor, configurations, stats, stamps) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.UpdateReport, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("cachedDescriptor", obj.cachedDescriptor) + builder.addField("configurations", obj.configurations) + builder.addField("stats", obj.stats) + builder.addField("stamps", obj.stamps) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala new file mode 100644 index 000000000..9736e62ca --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait UpdateReportLiteFormats { self: sbt.librarymanagement.ConfigurationReportLiteFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val UpdateReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] = new JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.UpdateReportLite = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val configurations = unbuilder.readField[Vector[sbt.internal.librarymanagement.ConfigurationReportLite]]("configurations") + unbuilder.endObject() + sbt.internal.librarymanagement.UpdateReportLite(configurations) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.internal.librarymanagement.UpdateReportLite, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("configurations", obj.configurations) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala new file mode 100644 index 000000000..6b33803da --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala @@ -0,0 +1,44 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class UpdateStats private ( + val resolveTime: Long, + val downloadTime: Long, + val downloadSize: Long, + val cached: Boolean) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: UpdateStats => (this.resolveTime == x.resolveTime) && (this.downloadTime == x.downloadTime) && (this.downloadSize == x.downloadSize) && (this.cached == x.cached) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "UpdateStats".##) + resolveTime.##) + downloadTime.##) + downloadSize.##) + cached.##) + } + override def toString: String = { + Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") + } + protected[this] def copy(resolveTime: Long = resolveTime, downloadTime: Long = downloadTime, downloadSize: Long = downloadSize, cached: Boolean = cached): UpdateStats = { + new UpdateStats(resolveTime, downloadTime, downloadSize, cached) + } + def withResolveTime(resolveTime: Long): UpdateStats = { + copy(resolveTime = resolveTime) + } + def withDownloadTime(downloadTime: Long): UpdateStats = { + copy(downloadTime = downloadTime) + } + def withDownloadSize(downloadSize: Long): UpdateStats = { + copy(downloadSize = downloadSize) + } + def withCached(cached: Boolean): UpdateStats = { + copy(cached = cached) + } +} +object UpdateStats { + + def apply(resolveTime: Long, downloadTime: Long, downloadSize: Long, cached: Boolean): UpdateStats = new UpdateStats(resolveTime, downloadTime, downloadSize, cached) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala new file mode 100644 index 000000000..21de1bf5c --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala @@ -0,0 +1,33 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait UpdateStatsFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val UpdateStatsFormat: JsonFormat[sbt.librarymanagement.UpdateStats] = new JsonFormat[sbt.librarymanagement.UpdateStats] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateStats = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val resolveTime = unbuilder.readField[Long]("resolveTime") + val downloadTime = unbuilder.readField[Long]("downloadTime") + val downloadSize = unbuilder.readField[Long]("downloadSize") + val cached = unbuilder.readField[Boolean]("cached") + unbuilder.endObject() + sbt.librarymanagement.UpdateStats(resolveTime, downloadTime, downloadSize, cached) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.UpdateStats, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("resolveTime", obj.resolveTime) + builder.addField("downloadTime", obj.downloadTime) + builder.addField("downloadSize", obj.downloadSize) + builder.addField("cached", obj.cached) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 5a17a2d82..9a0044aca 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -19,7 +19,7 @@ import sbt.io.Path import sbt.librarymanagement._ import sbt.util.Logger -import scala.json.ast.unsafe._ +import scalajson.ast.unsafe._ import scala.collection.mutable import jawn.{ SupportParser, MutableFacade } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 0273a2930..0ce279c27 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -5,6 +5,7 @@ import sbt.internal.librarymanagement.cross.CrossVersionUtil final case class ScalaVersion(full: String, binary: String) abstract class CrossVersionFunctions { + /** Compatibility with 0.13 */ final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index 3fb9ae8e2..06c178d8e 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -4,7 +4,7 @@ import java.net.URL import java.io.File import sbt.internal._, librarymanagement._, util.UnitSpec -import scala.json.ast.unsafe._ +import scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ import org.scalatest.Assertion diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 6c618249f..8567c1012 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -1,12 +1,13 @@ import sbt._ import Keys._ +import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.2" - private val ioVersion = "1.0.0-M11" - private val utilVersion = "1.0.0-M23" + private val ioVersion = "1.0.0-M12" + private val utilVersion = "1.0.0-M25" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -55,8 +56,8 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") - val sjsonnewVersion = "0.8.0-M1" - val sjsonnewScalaJson = "com.eed3si9n" %% "sjson-new-scalajson" % sjsonnewVersion + val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } + val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" diff --git a/project/plugins.sbt b/project/plugins.sbt index 64f6761ab..ae33ece34 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M5") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M7") addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0") addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") From f5d66db0a60b089883d761ddb7fb8cf00aa69290 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Jun 2017 13:47:35 +0100 Subject: [PATCH 0635/1030] Format the build --- build.sbt | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/build.sbt b/build.sbt index 8cb4a343f..c4a7dd5b3 100644 --- a/build.sbt +++ b/build.sbt @@ -37,8 +37,9 @@ lazy val lmRoot = (project in file(".")) Seq( homepage := Some(url("https://github.com/sbt/librarymanagement")), description := "Library management module for sbt", - scmInfo := Some(ScmInfo(url("https://github.com/sbt/librarymanagement"), - "git@github.com:sbt/librarymanagement.git")), + scmInfo := Some(ScmInfo( + url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git" + )), bintrayPackage := "librarymanagement", scalafmtOnCompile := true, // scalafmtVersion 1.0.0-RC3 has regression @@ -63,21 +64,16 @@ lazy val lm = (project in file("librarymanagement")) .settings( commonSettings, name := "librarymanagement", - libraryDependencies ++= Seq(ivy, - jsch, - scalaReflect.value, - launcherInterface, - gigahorseOkhttp, - okhttpUrlconnection, - sjsonnewScalaJson.value % Optional), + libraryDependencies ++= Seq( + ivy, jsch, scalaReflect.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection, + sjsonnewScalaJson.value % Optional + ), libraryDependencies ++= scalaXml.value, - resourceGenerators in Compile += Def - .task( - Util.generateVersionFile(version.value, - resourceManaged.value, - streams.value, - (compile in Compile).value)) - .taskValue, + resourceGenerators in Compile += Def.task( + Util.generateVersionFile( + version.value, resourceManaged.value, streams.value, (compile in Compile).value + ) + ).taskValue, // mimaBinaryIssueFilters ++= Seq(), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", @@ -91,12 +87,14 @@ lazy val lm = (project in file("librarymanagement")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) } ) - .configure(addSbtIO, - addSbtUtilLogging, - addSbtUtilTesting, - addSbtUtilCollection, - addSbtUtilCompletion, - addSbtUtilCache) + .configure( + addSbtIO, + addSbtUtilLogging, + addSbtUtilTesting, + addSbtUtilCollection, + addSbtUtilCompletion, + addSbtUtilCache + ) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( From 85cfe4d78cbbe2c1e31842bb097b1f92dd2e8c3b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Jun 2017 13:59:31 +0100 Subject: [PATCH 0636/1030] Drop util-testing --- build.sbt | 4 ++-- .../src/test/scala/CrossVersionTest.scala | 2 +- .../src/test/scala/DMSerializationSpec.scala | 2 +- .../src/test/scala/MergeDescriptorSpec.scala | 2 +- .../src/test/scala/ModuleIdTest.scala | 2 +- .../src/test/scala/OfflineModeSpec.scala | 2 +- .../src/test/scala/ResolverTest.scala | 2 +- .../src/test/scala/ScalaOverrideTest.scala | 2 +- .../src/test/scala/UpdateOptionsSpec.scala | 2 +- .../src/test/scala/VersionNumberSpec.scala | 2 +- project/Dependencies.scala | 16 ++++------------ 11 files changed, 15 insertions(+), 23 deletions(-) diff --git a/build.sbt b/build.sbt index c4a7dd5b3..0251916d7 100644 --- a/build.sbt +++ b/build.sbt @@ -66,7 +66,8 @@ lazy val lm = (project in file("librarymanagement")) name := "librarymanagement", libraryDependencies ++= Seq( ivy, jsch, scalaReflect.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection, - sjsonnewScalaJson.value % Optional + sjsonnewScalaJson.value % Optional, + scalaTest ), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task( @@ -90,7 +91,6 @@ lazy val lm = (project in file("librarymanagement")) .configure( addSbtIO, addSbtUtilLogging, - addSbtUtilTesting, addSbtUtilCollection, addSbtUtilCompletion, addSbtUtilCache diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/librarymanagement/src/test/scala/CrossVersionTest.scala index 376a17cb1..b2c52a732 100644 --- a/librarymanagement/src/test/scala/CrossVersionTest.scala +++ b/librarymanagement/src/test/scala/CrossVersionTest.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec import CrossVersion._ class CrossVersionTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index 06c178d8e..35c0f7c01 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -3,7 +3,7 @@ package sbt.librarymanagement import java.net.URL import java.io.File -import sbt.internal._, librarymanagement._, util.UnitSpec +import sbt.internal._, librarymanagement._ import scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ import org.scalatest.Assertion diff --git a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala index dddeadfdd..b435027bd 100644 --- a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala +++ b/librarymanagement/src/test/scala/MergeDescriptorSpec.scala @@ -1,6 +1,6 @@ package sbt.internal.librarymanagement -import org.apache.ivy.core.module.descriptor.{ DependencyArtifactDescriptor } +import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor import sbt.librarymanagement._ import sbt.internal.librarymanagement.ivyint._ diff --git a/librarymanagement/src/test/scala/ModuleIdTest.scala b/librarymanagement/src/test/scala/ModuleIdTest.scala index 8b1d7d7b7..a9bab61f0 100644 --- a/librarymanagement/src/test/scala/ModuleIdTest.scala +++ b/librarymanagement/src/test/scala/ModuleIdTest.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec class ModuleIdTest extends UnitSpec { "Module Id" should "return cross-disabled module id as equal to a copy" in { diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala index ea6b5f1d7..04d8cf836 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -3,7 +3,7 @@ package sbt.librarymanagement import org.scalatest.Assertion import sbt.internal.librarymanagement._ import sbt.internal.librarymanagement.impl.DependencyBuilders -import sbt.io.{ FileFilter, IO, Path } +import sbt.io.IO class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { private final def targetDir = Some(currentDependency) diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/librarymanagement/src/test/scala/ResolverTest.scala index 2682797fa..d98eab799 100644 --- a/librarymanagement/src/test/scala/ResolverTest.scala +++ b/librarymanagement/src/test/scala/ResolverTest.scala @@ -2,7 +2,7 @@ package sbt.librarymanagement import java.net.URL -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec object ResolverTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/librarymanagement/src/test/scala/ScalaOverrideTest.scala index 2417db786..bb872438d 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/librarymanagement/src/test/scala/ScalaOverrideTest.scala @@ -3,7 +3,7 @@ package sbt.librarymanagement import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec import IvyScala.OverrideScalaMediator import ScalaArtifacts._ diff --git a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala index 8a152bb13..eaf61fe29 100644 --- a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala +++ b/librarymanagement/src/test/scala/UpdateOptionsSpec.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec class UpdateOptionsSpec extends UnitSpec { diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/librarymanagement/src/test/scala/VersionNumberSpec.scala index 66fd96f61..5a1c27a7a 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/librarymanagement/src/test/scala/VersionNumberSpec.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import sbt.internal.util.UnitSpec +import sbt.internal.librarymanagement.UnitSpec // This is a specification to check the version number parsing. class VersionNumberSpec extends UnitSpec { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8567c1012..156539ddd 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,7 +13,6 @@ object Dependencies { private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - private val utilTesting = "org.scala-sbt" %% "util-testing" % utilVersion private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion @@ -28,16 +27,10 @@ object Dependencies { lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io") lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util") - def addSbtModule(p: Project, - path: Option[String], - projectName: String, - m: ModuleID, - c: Option[Configuration] = None) = + def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID) = path match { - case Some(f) => - p dependsOn c.fold[ClasspathDep[ProjectReference]](ProjectRef(file(f), projectName))( - ProjectRef(file(f), projectName) % _) - case None => p settings (libraryDependencies += c.fold(m)(m % _)) + case Some(f) => p dependsOn ProjectRef(file(f), projectName) + case None => p settings (libraryDependencies += m) } def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) @@ -45,8 +38,6 @@ object Dependencies { addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) - def addSbtUtilTesting(p: Project): Project = - addSbtModule(p, sbtUtilPath, "utilTesting", utilTesting, Some(Test)) def addSbtUtilCompletion(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) @@ -56,6 +47,7 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") + val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" From f255894413af0d5efbe1161f4beb437042e58dfd Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Jun 2017 14:16:29 +0100 Subject: [PATCH 0637/1030] Drop RepositoriesParser & therefore util-completion This code originates from a PR against sbt 0.13: https://github.com/sbt/sbt/pull/2576 The sbt/librarymanagement part was forward-ported to sbt/librarymanagement and merged, while the sbt/sbt part wasn't. So let's get rid of this so we can drop the dependency on util-completion. --- build.sbt | 8 +- .../RepositoriesParser.scala | 117 ------------ .../RepositoriesParserSpecification.scala | 175 ------------------ project/Dependencies.scala | 3 - 4 files changed, 1 insertion(+), 302 deletions(-) delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala delete mode 100644 librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala diff --git a/build.sbt b/build.sbt index 0251916d7..bd002a1d2 100644 --- a/build.sbt +++ b/build.sbt @@ -88,13 +88,7 @@ lazy val lm = (project in file("librarymanagement")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) } ) - .configure( - addSbtIO, - addSbtUtilLogging, - addSbtUtilCollection, - addSbtUtilCompletion, - addSbtUtilCache - ) + .configure(addSbtIO, addSbtUtilLogging, addSbtUtilCollection, addSbtUtilCache) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala deleted file mode 100644 index a10741b64..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/RepositoriesParser.scala +++ /dev/null @@ -1,117 +0,0 @@ -package sbt -package internal -package librarymanagement - -import java.io.File -import java.net.URL - -import scala.io.Source -import sbt.internal.util.complete.Parser -import sbt.internal.util.complete.DefaultParsers._ - -private[sbt] object RepositoriesParser { - - private case class AfterPattern(artifactPattern: Option[String], flags: Int) - final case class PredefinedRepository(override val id: xsbti.Predefined) - extends xsbti.PredefinedRepository - final case class MavenRepository(override val id: String, override val url: URL) - extends xsbti.MavenRepository - final case class IvyRepository( - override val id: String, - override val url: URL, - override val ivyPattern: String, - override val artifactPattern: String, - override val mavenCompatible: Boolean, - override val skipConsistencyCheck: Boolean, - override val descriptorOptional: Boolean, - val bootOnly: Boolean - ) extends xsbti.IvyRepository - - // Predefined repositories - def local: Parser[xsbti.Repository] = - "local" ^^^ new PredefinedRepository(xsbti.Predefined.Local) - def mavenLocal: Parser[xsbti.Repository] = - "maven-local" ^^^ new PredefinedRepository(xsbti.Predefined.MavenLocal) - def mavenCentral: Parser[xsbti.Repository] = - "maven-central" ^^^ new PredefinedRepository(xsbti.Predefined.MavenCentral) - def predefinedResolver: Parser[xsbti.Repository] = local | mavenLocal | mavenCentral - - // Options - def descriptorOptional: Parser[Int] = "descriptorOptional" ^^^ Flags.descriptorOptionalFlag - def skipConsistencyCheck: Parser[Int] = "skipConsistencyCheck" ^^^ Flags.skipConsistencyCheckFlag - def bootOnly: Parser[Int] = "bootOnly" ^^^ Flags.bootOnlyFlag - def mavenCompatible: Parser[Int] = "mavenCompatible" ^^^ Flags.mavenCompatibleFlag - - def option: Parser[Int] = descriptorOptional | skipConsistencyCheck | bootOnly | mavenCompatible - def options: Parser[Int] = rep1sep(option, separator) map (_ reduce (_ | _)) - - def name: Parser[String] = ID - def separator: Parser[String] = "," ~> charClass(c => c == ' ' || c == '\t').*.string - def nonComma: Parser[String] = charClass(_ != ',').*.string - def ivyPattern: Parser[String] = nonComma - def artifactPattern: Parser[String] = nonComma - private def afterPattern: Parser[AfterPattern] = { - def onlyOptions = options map (AfterPattern(None, _)) - def both = artifactPattern ~ (separator ~> options).? map { - case ap ~ opts => AfterPattern(Some(ap), opts getOrElse 0) - } - onlyOptions | both - } - - def customResolver: Parser[xsbti.Repository] = - name ~ ": " ~ basicUri ~ (separator ~> ivyPattern).? ~ (separator ~> afterPattern).? map { - case name ~ ": " ~ uri ~ None ~ _ => - new MavenRepository(name, uri.toURL) - case name ~ ": " ~ uri ~ Some(ivy) ~ ap => - // scalac complains about the recursion depth if we pattern match over `ap` directly. - ap match { - case Some(AfterPattern(artifactPattern, Flags(dOpt, sc, bo, mc))) => - new IvyRepository( - name, - uri.toURL, - ivy, - artifactPattern getOrElse ivy, - mc, - sc, - dOpt, - bo - ) - case None => - new IvyRepository(name, uri.toURL, ivy, ivy, false, false, false, false) - } - } - - def resolver: Parser[xsbti.Repository] = - predefinedResolver | customResolver - - def getResolver[T](in: String)(parser: Parser[T]): Option[T] = - Parser.parse(in.trim, parser).right.toOption - - def apply(lines: Iterator[String]): Seq[xsbti.Repository] = - if (lines.isEmpty) Nil - else { - if (lines.next != "[repositories]") - throw new Exception("Repositories file must start with '[repositories]'") - lines.flatMap(getResolver(_)(resolver)).toList - } - def apply(str: String): Seq[xsbti.Repository] = apply(str.lines) - def apply(file: File): Seq[xsbti.Repository] = { - if (!file.exists) Nil - else apply(Source.fromFile(file).getLines) - } - - object Flags { - val descriptorOptionalFlag = 1 << 0 - val skipConsistencyCheckFlag = 1 << 1 - val bootOnlyFlag = 1 << 2 - val mavenCompatibleFlag = 1 << 3 - - def unapply(flags: Int): Some[(Boolean, Boolean, Boolean, Boolean)] = { - val dOpt = (flags & descriptorOptionalFlag) != 0 - val sc = (flags & skipConsistencyCheckFlag) != 0 - val bo = (flags & bootOnlyFlag) != 0 - val mc = (flags & mavenCompatibleFlag) != 0 - Some((dOpt, sc, bo, mc)) - } - } -} diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala deleted file mode 100644 index 0aec79d39..000000000 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/RepositoriesParserSpecification.scala +++ /dev/null @@ -1,175 +0,0 @@ -package sbt -package internal -package librarymanagement - -import java.net.URL - -/** - * Tests that we can correctly parse repositories definitions. - */ -class RepositoriesParserSpecification extends UnitSpec { - import RepositoriesParser._ - - "The RepositoriesParser" should "check that repositories file starts with [repositories]" in { - val file = """local - |maven-central""".stripMargin - a[Exception] should be thrownBy RepositoriesParser(file) - } - - it should "parse the local repository" in { - val file = """[repositories] - | local""".stripMargin - val repos = RepositoriesParser(file) - repos.size shouldBe 1 - repos(0) shouldBe PredefinedRepository(xsbti.Predefined.Local) - - } - - it should "parse the local maven repository" in { - val file = """[repositories] - | maven-local""".stripMargin - val repos = RepositoriesParser(file) - repos.size shouldBe 1 - repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenLocal) - } - - it should "parse Maven Central repository" in { - val file = """[repositories] - | maven-central""".stripMargin - val repos = RepositoriesParser(file) - repos.size shouldBe 1 - repos(0) shouldBe PredefinedRepository(xsbti.Predefined.MavenCentral) - } - - it should "parse simple Maven repository" in { - val file = """[repositories] - | mavenRepo: https://repo1.maven.org""".stripMargin - val repos = RepositoriesParser(file) - repos.size shouldBe 1 - repos(0) shouldBe MavenRepository("mavenRepo", new URL("https://repo1.maven.org")) - } - - it should "parse `bootOnly` option" in { - val file = """[repositories] - | ivyRepo: https://repo1.maven.org, [orgPath], bootOnly""".stripMargin - val repos = RepositoriesParser(file) - val expected = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[orgPath]", - mavenCompatible = false, - skipConsistencyCheck = false, - descriptorOptional = false, - bootOnly = true - ) - repos.size shouldBe 1 - repos(0) shouldBe expected - } - - it should "parse `mavenCompatible` option" in { - val file = """[repositories] - | ivyRepo: https://repo1.maven.org, [orgPath], mavenCompatible""".stripMargin - val repos = RepositoriesParser(file) - val expected = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[orgPath]", - mavenCompatible = true, - skipConsistencyCheck = false, - descriptorOptional = false, - bootOnly = false - ) - repos.size shouldBe 1 - repos(0) shouldBe expected - } - - it should "parse `skipConsistencyCheck` option" in { - val file = """[repositories] - | ivyRepo: https://repo1.maven.org, [orgPath], skipConsistencyCheck""".stripMargin - val repos = RepositoriesParser(file) - val expected = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[orgPath]", - mavenCompatible = false, - skipConsistencyCheck = true, - descriptorOptional = false, - bootOnly = false - ) - repos.size shouldBe 1 - repos(0) shouldBe expected - } - - it should "parse `descriptorOptional` option" in { - val file = """[repositories] - | ivyRepo: https://repo1.maven.org, [orgPath], descriptorOptional""".stripMargin - val repos = RepositoriesParser(file) - val expected = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[orgPath]", - mavenCompatible = false, - skipConsistencyCheck = false, - descriptorOptional = true, - bootOnly = false - ) - repos.size shouldBe 1 - repos(0) shouldBe expected - } - - it should "parse complex ivy repository definition" in { - val file = - """[repositories] - | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck""".stripMargin - val repos = RepositoriesParser(file) - val expected = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[artPath]", - mavenCompatible = false, - skipConsistencyCheck = true, - descriptorOptional = true, - bootOnly = false - ) - repos.size shouldBe 1 - repos(0) shouldBe expected - } - - it should "parse multiple repositories defined together" in { - val file = - """[repositories] - | local - | ivyRepo: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck - | mavenRepo: https://repo1.maven.org""".stripMargin - val expected0 = PredefinedRepository(xsbti.Predefined.Local) - val expected1 = - IvyRepository( - "ivyRepo", - new URL("https://repo1.maven.org"), - "[orgPath]", - "[artPath]", - mavenCompatible = false, - skipConsistencyCheck = true, - descriptorOptional = true, - bootOnly = false - ) - val expected2 = MavenRepository("mavenRepo", new URL("https://repo1.maven.org")) - - val repos = RepositoriesParser(file) - repos.size shouldBe 3 - repos(0) shouldBe expected0 - repos(1) shouldBe expected1 - repos(2) shouldBe expected2 - } - -} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 156539ddd..290dde04d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -13,7 +13,6 @@ object Dependencies { private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - private val utilCompletion = "org.scala-sbt" %% "util-completion" % utilVersion private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion def getSbtModulePath(key: String, name: String) = { @@ -38,8 +37,6 @@ object Dependencies { addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) - def addSbtUtilCompletion(p: Project): Project = - addSbtModule(p, sbtUtilPath, "utilComplete", utilCompletion) def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" From a375f57101e01bfc63affda3c9cc1366ee3c33b2 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Jun 2017 15:27:23 +0100 Subject: [PATCH 0638/1030] Mini cleanup JsonUtil --- .../internal/librarymanagement/JsonUtil.scala | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 19c835393..2780d5e12 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -1,11 +1,10 @@ package sbt.internal.librarymanagement import java.io.File -import org.apache.ivy.core -import core.module.descriptor.ModuleDescriptor +import org.apache.ivy.core.module.descriptor.ModuleDescriptor +import sbt.io.IO import sbt.util.{ CacheStore, Logger } -import sbt.librarymanagement._ -import sbt.librarymanagement.LibraryManagementCodec._ +import sbt.librarymanagement._, LibraryManagementCodec._ private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" @@ -22,14 +21,17 @@ private[sbt] object JsonUtil { fromLite(lite, cachedDescriptor) } catch { case e: Throwable => - log.error("Unable to parse mini graph: " + path.toString) + log.error(s"Unable to parse mini graph: $path") throw e } } + def writeUpdateReport(ur: UpdateReport, graphPath: File): Unit = { - sbt.io.IO.createDirectory(graphPath.getParentFile) - CacheStore(graphPath).write(toLite(ur)) + val updateReportLite = toLite(ur) + IO.createDirectory(graphPath.getParentFile) + CacheStore(graphPath).write(updateReportLite) } + def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite( @@ -65,6 +67,7 @@ private[sbt] object JsonUtil { } ) }) + // #1763/#2030. Caller takes up 97% of space, so we need to shrink it down, // but there are semantics associated with some of them. def filterOutArtificialCallers(callers: Vector[Caller]): Vector[Caller] = From 22df64365b600f30df79f182975c41d7d530ed2b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 21 Jun 2017 16:22:56 +0100 Subject: [PATCH 0639/1030] Replace util-collection dep with util-position With Position being extracted to its own dependency we can drop this dependency, allowing util-collection to move (back) to sbt/sbt! --- build.sbt | 2 +- project/Dependencies.scala | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index bd002a1d2..7036bdb8f 100644 --- a/build.sbt +++ b/build.sbt @@ -88,7 +88,7 @@ lazy val lm = (project in file("librarymanagement")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) } ) - .configure(addSbtIO, addSbtUtilLogging, addSbtUtilCollection, addSbtUtilCache) + .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) def customCommands: Seq[Setting[_]] = Seq( diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 290dde04d..73f3d42c3 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,11 +7,11 @@ object Dependencies { val scala212 = "2.12.2" private val ioVersion = "1.0.0-M12" - private val utilVersion = "1.0.0-M25" + private val utilVersion = "1.0.0-M26" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion - private val utilCollection = "org.scala-sbt" %% "util-collection" % utilVersion + private val utilPosition = "org.scala-sbt" %% "util-position" % utilVersion private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion @@ -33,8 +33,8 @@ object Dependencies { } def addSbtIO(p: Project): Project = addSbtModule(p, sbtIoPath, "io", sbtIO) - def addSbtUtilCollection(p: Project): Project = - addSbtModule(p, sbtUtilPath, "utilCollection", utilCollection) + def addSbtUtilPosition(p: Project): Project = + addSbtModule(p, sbtUtilPath, "utilPosition", utilPosition) def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) From 178b079f4019850edcea11595c5386a65bc254bb Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 6 Jul 2017 14:05:04 +0100 Subject: [PATCH 0640/1030] No sbt-doge in sbt 1, switch back to + --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 7036bdb8f..33a410a47 100644 --- a/build.sbt +++ b/build.sbt @@ -94,8 +94,8 @@ lazy val lm = (project in file("librarymanagement")) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => // "clean" :: - "so compile" :: - "so publishSigned" :: + "+compile" :: + "+publishSigned" :: "reload" :: state } From e3891c8732dc248bd3ff3be9d5c796454d66bc3a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 3 Jul 2017 02:13:02 -0400 Subject: [PATCH 0641/1030] Bumping up the threshold for offline mode test Travis CI keeps failing on OfflineModeSpec, so I am going to bump up the threshold. --- librarymanagement/src/test/scala/OfflineModeSpec.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/librarymanagement/src/test/scala/OfflineModeSpec.scala index 04d8cf836..f4747a7f9 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/librarymanagement/src/test/scala/OfflineModeSpec.scala @@ -40,7 +40,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { // Compute an estimate to ensure that the second resolution does indeed use the cache val originalResolveTime = onlineResolution.right.get.stats.resolveTime - val estimatedCachedTime = originalResolveTime * 0.15 + val estimatedCachedTime = originalResolveTime * 0.3 val offlineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) From dddfa251c77738a0d0c55e017c0d0e06e4704715 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 6 Jul 2017 14:58:33 +0100 Subject: [PATCH 0642/1030] Bump Scala versions & add caching to .travis.yml --- .travis.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index dc51710ee..20ffdf8b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,18 @@ language: scala +jdk: oraclejdk8 scala: - - 2.11.8 - - 2.12.1 + - 2.11.11 + - 2.12.2 script: - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" -jdk: - - oraclejdk8 +cache: + directories: + - $HOME/.ivy2/cache + - $HOME/.sbt + +before_cache: + - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete + - find $HOME/.sbt -name "*.lock" -print -delete From bc0ed18308e8eed4a624c01bfacbd34f13557d0f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 10 Jun 2017 04:13:31 -0400 Subject: [PATCH 0643/1030] define def config(...) as a macro to capture the Scala identifier --- build.sbt | 14 +-- .../sbt/librarymanagement/Artifact.scala | 8 +- .../librarymanagement/ArtifactFormats.scala | 4 +- .../LibraryManagementCodec.scala | 2 +- .../main/contraband/librarymanagement.json | 18 +--- .../sbt/internal/librarymanagement/Ivy.scala | 8 +- .../librarymanagement/IvyRetrieve.scala | 2 +- .../sbt/librarymanagement/ArtifactExtra.scala | 8 +- .../sbt/librarymanagement/Configuration.scala | 77 ++++++++++++++++ .../ConfigurationExtra.scala | 89 ++++++++++++++----- .../ConfigurationFormats.scala | 46 ++++++++++ .../src/test/scala/ConfigMacroSpec.scala | 61 +++++++++++++ project/Dependencies.scala | 1 + 13 files changed, 279 insertions(+), 59 deletions(-) create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala create mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala create mode 100644 librarymanagement/src/test/scala/ConfigMacroSpec.scala diff --git a/build.sbt b/build.sbt index 33a410a47..295ce27fe 100644 --- a/build.sbt +++ b/build.sbt @@ -64,11 +64,15 @@ lazy val lm = (project in file("librarymanagement")) .settings( commonSettings, name := "librarymanagement", - libraryDependencies ++= Seq( - ivy, jsch, scalaReflect.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection, - sjsonnewScalaJson.value % Optional, - scalaTest - ), + libraryDependencies ++= Seq(ivy, + jsch, + scalaReflect.value, + scalaCompiler.value, + launcherInterface, + gigahorseOkhttp, + okhttpUrlconnection, + sjsonnewScalaJson.value % Optional, + scalaTest), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task( Util.generateVersionFile( diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index d1848b1c0..42c20e392 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -9,7 +9,7 @@ final class Artifact private ( val `type`: String, val extension: String, val classifier: Option[String], - val configurations: Vector[sbt.librarymanagement.Configuration], + val configurations: Vector[String], val url: Option[java.net.URL], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { @@ -26,7 +26,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" } - protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { + protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[String] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } def withName(name: String): Artifact = { @@ -41,7 +41,7 @@ final class Artifact private ( def withClassifier(classifier: Option[String]): Artifact = { copy(classifier = classifier) } - def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): Artifact = { + def withConfigurations(configurations: Vector[String]): Artifact = { copy(configurations = configurations) } def withUrl(url: Option[java.net.URL]): Artifact = { @@ -57,5 +57,5 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.Configuration], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[String], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 08bd9cadb..514cd83fc 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ArtifactFormats { self: sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => +trait ArtifactFormats { self: sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = new JsonFormat[sbt.librarymanagement.Artifact] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { jsOpt match { @@ -15,7 +15,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val `type` = unbuilder.readField[String]("type") val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") - val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val configurations = unbuilder.readField[Vector[String]]("configurations") val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 9745a4d1a..8d1cf1a46 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -5,7 +5,6 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol - with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ArtifactTypeFilterFormats @@ -24,6 +23,7 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.DeveloperFormats with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.IvyScalaFormats with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 71b18d691..7ceabeb73 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -13,7 +13,7 @@ { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } @@ -61,22 +61,6 @@ ], "toString": "s\"$caller\"" }, - { - "name": "Configuration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": "Represents an Ivy configuration.", - "parents": "sbt.librarymanagement.ConfigurationExtra", - "fields": [ - { "name": "name", "type": "String" }, - { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "isPublic", "type": "boolean", "default": "true", "since": "0.0.1" }, - { "name": "extendsConfigs", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "transitive", "type": "boolean", "default": "true", "since": "0.0.1" } - ], - "toString": "name" - }, { "name": "ConfigurationReport", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e7fcdd204..121e8d929 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -238,9 +238,9 @@ final class IvySbt(val configuration: IvyConfiguration) { self => import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) - val defaultConf = defaultConfiguration getOrElse Configurations.config( - ModuleDescriptor.DEFAULT_CONFIGURATION - ) + val defaultConf = defaultConfiguration getOrElse Configuration( + "Default", + ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug( "Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." else " and XML.") @@ -859,7 +859,7 @@ private[sbt] object IvySbt { ): Unit = { val confs = if (artifact.configurations.isEmpty) allConfigurations - else artifact.configurations.map(_.name) + else artifact.configurations confs foreach addConfiguration } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index d76f7556d..85eb001c2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -217,7 +217,7 @@ object IvyRetrieve { getType, getExt, Option(getExtraAttribute("classifier")), - getConfigurations.toVector map Configurations.config, + getConfigurations.toVector, Option(getUrl) ) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index d3f7a6e7e..92b9fdf1c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -11,7 +11,7 @@ abstract class ArtifactExtra { def `type`: String def extension: String def classifier: Option[String] - def configurations: Vector[Configuration] + def configurations: Vector[String] def url: Option[URL] def extraAttributes: Map[String, String] def checksum: Option[Checksum] @@ -21,7 +21,7 @@ abstract class ArtifactExtra { `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, - configurations: Vector[Configuration] = configurations, + configurations: Vector[String] = configurations, url: Option[URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[Checksum] = checksum @@ -58,7 +58,7 @@ abstract class ArtifactFunctions { `type`: String, extension: String, classifier: Option[String], - configurations: Vector[Configuration], + configurations: Vector[String], url: Option[URL] ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) @@ -67,7 +67,7 @@ abstract class ArtifactFunctions { def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None) + def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom.name), None) // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs val DefaultSourceTypes = Set("src", "source", "sources") diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala new file mode 100644 index 000000000..7527f085a --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -0,0 +1,77 @@ +package sbt +package librarymanagement + +/** Represents an Ivy configuration. */ +final class Configuration private[sbt] ( + val id: String, + val name: String, + val description: String, + val isPublic: Boolean, + val extendsConfigs: Vector[sbt.librarymanagement.Configuration], + val transitive: Boolean) + extends sbt.librarymanagement.ConfigurationExtra + with Serializable { + + require(name != null, "name cannot be null") + require(name.size > 0, "name cannot be empty") + require(id != null, "id cannot be null") + require(id.size > 0, "id cannot be empty") + require(id.head.isUpper, s"id must be capitalized: $id") + + private def this(id: String, name: String) = + this(id, name, "", true, Vector.empty, true) + + override def equals(o: Any): Boolean = o match { + case x: Configuration => + (this.id == x.id) && + (this.name == x.name) && + (this.description == x.description) && + (this.isPublic == x.isPublic) && + (this.extendsConfigs == x.extendsConfigs) && + (this.transitive == x.transitive) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + id.##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) + } + override def toString: String = { + name + } + protected[this] def copy(id: String = id, + name: String = name, + description: String = description, + isPublic: Boolean = isPublic, + extendsConfigs: Vector[sbt.librarymanagement.Configuration] = + extendsConfigs, + transitive: Boolean = transitive): Configuration = { + new Configuration(id, name, description, isPublic, extendsConfigs, transitive) + } + + def withDescription(description: String): Configuration = { + copy(description = description) + } + + def withIsPublic(isPublic: Boolean): Configuration = { + copy(isPublic = isPublic) + } + + def withExtendsConfigs( + extendsConfigs: Vector[sbt.librarymanagement.Configuration]): Configuration = { + copy(extendsConfigs = extendsConfigs) + } + + def withTransitive(transitive: Boolean): Configuration = { + copy(transitive = transitive) + } +} +object Configuration { + private[sbt] def apply(id: String, name: String): Configuration = + new Configuration(id, name, "", true, Vector.empty, true) + private[sbt] def apply(id: String, + name: String, + description: String, + isPublic: Boolean, + extendsConfigs: Vector[sbt.librarymanagement.Configuration], + transitive: Boolean): Configuration = + new Configuration(id, name, description, isPublic, extendsConfigs, transitive) +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 9795ff70a..4d019ffff 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -3,8 +3,11 @@ */ package sbt.librarymanagement +import scala.annotation.tailrec +import scala.language.experimental.macros + object Configurations { - def config(name: String) = Configuration(name) + def config(name: String) = macro ConfigurationMacro.configMacroImpl def default: Seq[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Seq[Configuration] = Seq(Compile, Runtime, Test, Provided, Optional) @@ -25,24 +28,26 @@ object Configurations { case _ => c } - def internal(base: Configuration, ext: Configuration*) = - config(base.name + "-internal").extend(ext: _*).hide - def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) - def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) + private[sbt] def internal(base: Configuration, ext: Configuration*) = + Configuration(base.id + "Internal", base.name + "-internal").extend(ext: _*).hide + private[sbt] def fullInternal(base: Configuration): Configuration = + internal(base, base, Optional, Provided) + private[sbt] def optionalInternal(base: Configuration): Configuration = + internal(base, base, Optional) - lazy val Default = config("default") - lazy val Compile = config("compile") - lazy val IntegrationTest = config("it") extend (Runtime) - lazy val Provided = config("provided") - lazy val Runtime = config("runtime") extend (Compile) - lazy val Test = config("test") extend (Runtime) - lazy val System = config("system") - lazy val Optional = config("optional") - lazy val Pom = config("pom") + lazy val Default = Configuration("Default", "default") + lazy val Compile = Configuration("Compile", "compile") + lazy val IntegrationTest = Configuration("IntegrationTest", "it") extend (Runtime) + lazy val Provided = Configuration("Provided", "provided") + lazy val Runtime = Configuration("Runtime", "runtime") extend (Compile) + lazy val Test = Configuration("Test", "test") extend (Runtime) + lazy val System = Configuration("System", "system") + lazy val Optional = Configuration("Optional", "optional") + lazy val Pom = Configuration("Pom", "pom") - lazy val ScalaTool = config("scala-tool").hide - lazy val CompilerPlugin = config("plugin").hide - lazy val Component = config("component").hide + lazy val ScalaTool = Configuration("ScalaTool", "scala-tool").hide + lazy val CompilerPlugin = Configuration("CompilerPlugin", "plugin").hide + lazy val Component = Configuration("Component", "component").hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) @@ -70,6 +75,7 @@ object Configurations { } abstract class ConfigurationExtra { + def id: String def name: String def description: String def isPublic: Boolean @@ -80,10 +86,51 @@ abstract class ConfigurationExtra { require(description != null) def describedAs(newDescription: String) = - Configuration(name, newDescription, isPublic, extendsConfigs, transitive) + Configuration(id, name, newDescription, isPublic, extendsConfigs, transitive) def extend(configs: Configuration*) = - Configuration(name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) + Configuration(id, name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) def notTransitive = intransitive - def intransitive = Configuration(name, description, isPublic, extendsConfigs, false) - def hide = Configuration(name, description, false, extendsConfigs, transitive) + def intransitive = Configuration(id, name, description, isPublic, extendsConfigs, false) + def hide = Configuration(id, name, description, false, extendsConfigs, transitive) +} + +private[sbt] object ConfigurationMacro { + import scala.reflect.macros._ + + def configMacroImpl(c: Context)(name: c.Expr[String]): c.Expr[Configuration] = { + import c.universe._ + val enclosingValName = definingValName( + c, + methodName => + s"""$methodName must be directly assigned to a val, such as `val x = $methodName`.""") + val id = c.Expr[String](Literal(Constant(enclosingValName))) + reify { Configuration(id.splice, name.splice) } + } + + def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = { + import c.universe.{ Apply => ApplyTree, _ } + val methodName = c.macroApplication.symbol.name + def processName(n: Name): String = + n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary + @tailrec def enclosingVal(trees: List[c.Tree]): String = { + trees match { + case vd @ ValDef(_, name, _, _) :: ts => processName(name) + case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) + // lazy val x: X = has this form for some reason (only when the explicit type is present, though) + case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => + processName(name) + case _ => + c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString)) + "" + } + } + enclosingVal(enclosingTrees(c).toList) + } + + def enclosingTrees(c: blackbox.Context): Seq[c.Tree] = + c.asInstanceOf[reflect.macros.runtime.Context] + .callsiteTyper + .context + .enclosingContextChain + .map(_.tree.asInstanceOf[c.Tree]) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala new file mode 100644 index 000000000..30c09a453 --- /dev/null +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala @@ -0,0 +1,46 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt +package librarymanagement + +import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +trait ConfigurationFormats { + self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => + implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = + new JsonFormat[sbt.librarymanagement.Configuration] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Configuration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val id = unbuilder.readField[String]("id") + val name = unbuilder.readField[String]("name") + val description = unbuilder.readField[String]("description") + val isPublic = unbuilder.readField[Boolean]("isPublic") + val extendsConfigs = + unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("extendsConfigs") + val transitive = unbuilder.readField[Boolean]("transitive") + unbuilder.endObject() + new sbt.librarymanagement.Configuration(id, + name, + description, + isPublic, + extendsConfigs, + transitive) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Configuration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("id", obj.id) + builder.addField("name", obj.name) + builder.addField("description", obj.description) + builder.addField("isPublic", obj.isPublic) + builder.addField("extendsConfigs", obj.extendsConfigs) + builder.addField("transitive", obj.transitive) + builder.endObject() + } + } +} diff --git a/librarymanagement/src/test/scala/ConfigMacroSpec.scala b/librarymanagement/src/test/scala/ConfigMacroSpec.scala new file mode 100644 index 000000000..93810a96a --- /dev/null +++ b/librarymanagement/src/test/scala/ConfigMacroSpec.scala @@ -0,0 +1,61 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement.Configuration +import sbt.librarymanagement.Configurations.config +import scala.util.control.NonFatal +import org.scalacheck._ +import Prop._ + +class ConfigDefs { + lazy val Kompile = config("kompile") + val X = config("x") + val Z = config("z").hide + val A: Configuration = config("a") + lazy val Aa: Configuration = config("aa") +} + +object ConfigMacroSpec extends Properties("ConfigMacroSpec") { + lazy val cd = new ConfigDefs + import cd._ + + def secure(f: => Prop): Prop = + try { + Prop.secure(f) + } catch { + case NonFatal(e) => + e.printStackTrace + throw e + } + + property("Explicit type on lazy val supported") = secure { + check(Aa, "Aa", "aa", true) + } + + property("Explicit type on val supported") = secure { + check(A, "A", "a", true) + } + + property("lazy vals supported") = secure { + check(Kompile, "Kompile", "kompile", true) + } + + property("plain vals supported") = secure { + check(X, "X", "x", true) + } + + property("Directory overridable") = secure { + check(Z, "Z", "z", false) + } + + def check(c: Configuration, id: String, name: String, isPublic: Boolean): Prop = { + s"Expected id: $id" |: + s"Expected name: $name" |: + s"Expected isPublic: $isPublic" |: + s"Actual id: ${c.id}" |: + s"Actual name: ${c.name}" |: + s"Actual isPublic: ${c.isPublic}" |: + (c.id == id) && + (c.name == name) && + (c.isPublic == isPublic) + } +} diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 73f3d42c3..1f8e6f5f2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,6 +43,7 @@ object Dependencies { val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a3314352b638afbf0dca19f127e8263ed6f898bd" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } + val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } From 9f2f7007626c39f79511f51e357d9157fd9d19ce Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 8 Jul 2017 13:01:59 +0200 Subject: [PATCH 0644/1030] Define ConfigRef and use it in Artifact --- .../sbt/librarymanagement/Artifact.scala | 8 ++--- .../librarymanagement/ArtifactFormats.scala | 4 +-- .../sbt/librarymanagement/ConfigRef.scala | 34 +++++++++++++++++++ .../librarymanagement/ConfigRefFormats.scala | 27 +++++++++++++++ .../LibraryManagementCodec.scala | 1 + .../main/contraband/librarymanagement.json | 19 ++++++++++- .../sbt/internal/librarymanagement/Ivy.scala | 18 +++++----- .../librarymanagement/IvyRetrieve.scala | 4 ++- .../sbt/librarymanagement/ArtifactExtra.scala | 8 ++--- .../sbt/librarymanagement/Configuration.scala | 2 ++ .../ConfigurationExtra.scala | 5 +++ 11 files changed, 110 insertions(+), 20 deletions(-) create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala create mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 42c20e392..df5d51f0a 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -9,7 +9,7 @@ final class Artifact private ( val `type`: String, val extension: String, val classifier: Option[String], - val configurations: Vector[String], + val configurations: Vector[sbt.librarymanagement.ConfigRef], val url: Option[java.net.URL], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { @@ -26,7 +26,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" } - protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[String] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { + protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } def withName(name: String): Artifact = { @@ -41,7 +41,7 @@ final class Artifact private ( def withClassifier(classifier: Option[String]): Artifact = { copy(classifier = classifier) } - def withConfigurations(configurations: Vector[String]): Artifact = { + def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): Artifact = { copy(configurations = configurations) } def withUrl(url: Option[java.net.URL]): Artifact = { @@ -57,5 +57,5 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[String], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 514cd83fc..4dfc42b54 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ArtifactFormats { self: sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => +trait ArtifactFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = new JsonFormat[sbt.librarymanagement.Artifact] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { jsOpt match { @@ -15,7 +15,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val `type` = unbuilder.readField[String]("type") val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") - val configurations = unbuilder.readField[Vector[String]]("configurations") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala new file mode 100644 index 000000000..b6e1b12b3 --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -0,0 +1,34 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** A reference to Configuration. */ +final class ConfigRef private ( + /** The name of the configuration that eventually get used by Maven. */ + val name: String) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: ConfigRef => (this.name == x.name) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "ConfigRef".##) + name.##) + } + override def toString: String = { + "ConfigRef(" + name + ")" + } + protected[this] def copy(name: String = name): ConfigRef = { + new ConfigRef(name) + } + def withName(name: String): ConfigRef = { + copy(name = name) + } +} +object ConfigRef extends sbt.librarymanagement.ConfigRefFunctions { + + def apply(name: String): ConfigRef = new ConfigRef(name) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala new file mode 100644 index 000000000..9996bd2db --- /dev/null +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala @@ -0,0 +1,27 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait ConfigRefFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val ConfigRefFormat: JsonFormat[sbt.librarymanagement.ConfigRef] = new JsonFormat[sbt.librarymanagement.ConfigRef] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigRef = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val name = unbuilder.readField[String]("name") + unbuilder.endObject() + sbt.librarymanagement.ConfigRef(name) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ConfigRef, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 8d1cf1a46..08e493b48 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -5,6 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ArtifactTypeFilterFormats diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 7ceabeb73..1f87a59de 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -13,7 +13,7 @@ { "name": "type", "type": "String", "default": "Artifact.DefaultType", "since": "0.0.1" }, { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } @@ -61,6 +61,23 @@ ], "toString": "s\"$caller\"" }, + { + "name": "ConfigRef", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "A reference to Configuration." + ], + "fields": [ + { + "name": "name", + "type": "String", + "doc": [ "The name of the configuration that eventually get used by Maven." ] + } + ], + "parentsCompanion": "sbt.librarymanagement.ConfigRefFunctions" + }, { "name": "ConfigurationReport", "namespace": "sbt.librarymanagement", diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 121e8d929..48f29920e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -603,10 +603,12 @@ private[sbt] object IvySbt { private def toIvyArtifact( moduleID: ModuleDescriptor, a: Artifact, - allConfigurations: Iterable[String] + allConfigurations: Vector[ConfigRef] ): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - copyConfigurations(a, artifact.addConfiguration, allConfigurations) + copyConfigurations(a, + (ref: ConfigRef) => { artifact.addConfiguration(ref.name) }, + allConfigurations) artifact } def getExtraAttributes(revID: ExtendableItem): Map[String, String] = { @@ -816,7 +818,7 @@ private[sbt] object IvySbt { url.orNull, extraMap ) - copyConfigurations(artifact, ivyArtifact.addConfiguration) + copyConfigurations(artifact, (ref: ConfigRef) => { ivyArtifact.addConfiguration(ref.name) }) for (conf <- dependencyDescriptor.getModuleConfigurations) dependencyDescriptor.addDependencyArtifact(conf, ivyArtifact) } @@ -849,13 +851,13 @@ private[sbt] object IvySbt { dependencyDescriptor } - def copyConfigurations(artifact: Artifact, addConfiguration: String => Unit): Unit = - copyConfigurations(artifact, addConfiguration, "*" :: Nil) + def copyConfigurations(artifact: Artifact, addConfiguration: ConfigRef => Unit): Unit = + copyConfigurations(artifact, addConfiguration, Vector(ConfigRef("*"))) private[this] def copyConfigurations( artifact: Artifact, - addConfiguration: String => Unit, - allConfigurations: Iterable[String] + addConfiguration: ConfigRef => Unit, + allConfigurations: Vector[ConfigRef] ): Unit = { val confs = if (artifact.configurations.isEmpty) allConfigurations @@ -923,7 +925,7 @@ private[sbt] object IvySbt { configurations.foreach(config => mod.addConfiguration(toIvyConfiguration(config))) def mapArtifacts(moduleID: ModuleDescriptor, artifacts: Seq[Artifact]): Seq[IArtifact] = { - lazy val allConfigurations = moduleID.getPublicConfigurationsNames + lazy val allConfigurations = moduleID.getPublicConfigurationsNames.toVector map ConfigRef.apply for (artifact <- artifacts) yield toIvyArtifact(moduleID, artifact, allConfigurations) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 85eb001c2..89f81f600 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -217,7 +217,9 @@ object IvyRetrieve { getType, getExt, Option(getExtraAttribute("classifier")), - getConfigurations.toVector, + getConfigurations.toVector map { c: String => + ConfigRef(c) + }, Option(getUrl) ) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 92b9fdf1c..62fac2e6b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -11,7 +11,7 @@ abstract class ArtifactExtra { def `type`: String def extension: String def classifier: Option[String] - def configurations: Vector[String] + def configurations: Vector[ConfigRef] def url: Option[URL] def extraAttributes: Map[String, String] def checksum: Option[Checksum] @@ -21,7 +21,7 @@ abstract class ArtifactExtra { `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, - configurations: Vector[String] = configurations, + configurations: Vector[ConfigRef] = configurations, url: Option[URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[Checksum] = checksum @@ -58,7 +58,7 @@ abstract class ArtifactFunctions { `type`: String, extension: String, classifier: Option[String], - configurations: Vector[String], + configurations: Vector[ConfigRef], url: Option[URL] ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) @@ -67,7 +67,7 @@ abstract class ArtifactFunctions { def sources(name: String) = classified(name, SourceClassifier) def javadoc(name: String) = classified(name, DocClassifier) - def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom.name), None) + def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None) // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs val DefaultSourceTypes = Set("src", "source", "sources") diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index 7527f085a..9a65e8b46 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -63,6 +63,8 @@ final class Configuration private[sbt] ( def withTransitive(transitive: Boolean): Configuration = { copy(transitive = transitive) } + + def toConfigRef: ConfigRef = ConfigRef(name) } object Configuration { private[sbt] def apply(id: String, name: String): Configuration = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 4d019ffff..ae821954c 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -134,3 +134,8 @@ private[sbt] object ConfigurationMacro { .enclosingContextChain .map(_.tree.asInstanceOf[c.Tree]) } + +abstract class ConfigRefFunctions { + implicit def configToConfigRef(c: Configuration): ConfigRef = + c.toConfigRef +} From 13e803d199cf0c9838f6e36386babbc3d98cc41c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 8 Jul 2017 14:57:15 +0200 Subject: [PATCH 0645/1030] Use ConfigRef in reports --- build.sbt | 3 ++- .../RetrieveConfiguration.scala | 8 +++---- .../sbt/librarymanagement/Caller.scala | 8 +++---- .../sbt/librarymanagement/CallerFormats.scala | 4 ++-- .../sbt/librarymanagement/ConfigRef.scala | 2 +- .../ConfigurationReport.scala | 8 +++---- .../ConfigurationReportFormats.scala | 4 ++-- .../sbt/librarymanagement/InclExclRule.scala | 8 +++---- .../InclExclRuleFormats.scala | 4 ++-- .../sbt/librarymanagement/ModuleReport.scala | 8 +++---- .../ModuleReportFormats.scala | 4 ++-- .../RetrieveConfigurationFormats.scala | 4 ++-- .../main/contraband/librarymanagement.json | 15 ++++++------ .../sbt/internal/librarymanagement/Ivy.scala | 6 ++--- .../librarymanagement/IvyActions.scala | 20 +++++++--------- .../librarymanagement/IvyRetrieve.scala | 8 ++++--- .../internal/librarymanagement/JsonUtil.scala | 4 ++-- .../CachedResolutionResolveEngine.scala | 20 +++++++++------- .../ConfigurationExtra.scala | 1 + .../librarymanagement/DependencyFilter.scala | 24 +++++++++---------- .../librarymanagement/EvictionWarning.scala | 10 ++++---- .../librarymanagement/RichUpdateReport.scala | 10 ++++---- .../librarymanagement/UpdateReportExtra.scala | 14 +++++------ .../src/test/scala/DMSerializationSpec.scala | 2 +- .../librarymanagement/IvyRepoSpec.scala | 4 ++-- project/Dependencies.scala | 1 + 26 files changed, 103 insertions(+), 101 deletions(-) diff --git a/build.sbt b/build.sbt index 295ce27fe..890d24ff0 100644 --- a/build.sbt +++ b/build.sbt @@ -72,7 +72,8 @@ lazy val lm = (project in file("librarymanagement")) gigahorseOkhttp, okhttpUrlconnection, sjsonnewScalaJson.value % Optional, - scalaTest), + scalaTest, + scalaCheck), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def.task( Util.generateVersionFile( diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala index e1be8c9db..0a6551f33 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala @@ -8,7 +8,7 @@ final class RetrieveConfiguration private ( val retrieveDirectory: java.io.File, val outputPattern: String, val sync: Boolean, - val configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]) extends Serializable { + val configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]) extends Serializable { private def this(retrieveDirectory: java.io.File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) @@ -22,7 +22,7 @@ final class RetrieveConfiguration private ( override def toString: String = { "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" } - protected[this] def copy(retrieveDirectory: java.io.File = retrieveDirectory, outputPattern: String = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]] = configurationsToRetrieve): RetrieveConfiguration = { + protected[this] def copy(retrieveDirectory: java.io.File = retrieveDirectory, outputPattern: String = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]] = configurationsToRetrieve): RetrieveConfiguration = { new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) } def withRetrieveDirectory(retrieveDirectory: java.io.File): RetrieveConfiguration = { @@ -34,12 +34,12 @@ final class RetrieveConfiguration private ( def withSync(sync: Boolean): RetrieveConfiguration = { copy(sync = sync) } - def withConfigurationsToRetrieve(configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]): RetrieveConfiguration = { + def withConfigurationsToRetrieve(configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = { copy(configurationsToRetrieve = configurationsToRetrieve) } } object RetrieveConfiguration { def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, false, None) - def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[sbt.librarymanagement.Configuration]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala index 0770bc9e7..3cfd92909 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement final class Caller private ( val caller: sbt.librarymanagement.ModuleID, - val callerConfigurations: Vector[String], + val callerConfigurations: Vector[sbt.librarymanagement.ConfigRef], val callerExtraAttributes: Map[String, String], val isForceDependency: Boolean, val isChangingDependency: Boolean, @@ -25,13 +25,13 @@ final class Caller private ( override def toString: String = { s"$caller" } - protected[this] def copy(caller: sbt.librarymanagement.ModuleID = caller, callerConfigurations: Vector[String] = callerConfigurations, callerExtraAttributes: Map[String, String] = callerExtraAttributes, isForceDependency: Boolean = isForceDependency, isChangingDependency: Boolean = isChangingDependency, isTransitiveDependency: Boolean = isTransitiveDependency, isDirectlyForceDependency: Boolean = isDirectlyForceDependency): Caller = { + protected[this] def copy(caller: sbt.librarymanagement.ModuleID = caller, callerConfigurations: Vector[sbt.librarymanagement.ConfigRef] = callerConfigurations, callerExtraAttributes: Map[String, String] = callerExtraAttributes, isForceDependency: Boolean = isForceDependency, isChangingDependency: Boolean = isChangingDependency, isTransitiveDependency: Boolean = isTransitiveDependency, isDirectlyForceDependency: Boolean = isDirectlyForceDependency): Caller = { new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) } def withCaller(caller: sbt.librarymanagement.ModuleID): Caller = { copy(caller = caller) } - def withCallerConfigurations(callerConfigurations: Vector[String]): Caller = { + def withCallerConfigurations(callerConfigurations: Vector[sbt.librarymanagement.ConfigRef]): Caller = { copy(callerConfigurations = callerConfigurations) } def withCallerExtraAttributes(callerExtraAttributes: Map[String, String]): Caller = { @@ -52,5 +52,5 @@ final class Caller private ( } object Caller { - def apply(caller: sbt.librarymanagement.ModuleID, callerConfigurations: Vector[String], callerExtraAttributes: Map[String, String], isForceDependency: Boolean, isChangingDependency: Boolean, isTransitiveDependency: Boolean, isDirectlyForceDependency: Boolean): Caller = new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) + def apply(caller: sbt.librarymanagement.ModuleID, callerConfigurations: Vector[sbt.librarymanagement.ConfigRef], callerExtraAttributes: Map[String, String], isForceDependency: Boolean, isChangingDependency: Boolean, isTransitiveDependency: Boolean, isDirectlyForceDependency: Boolean): Caller = new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala index f0994fef8..a7b863a5a 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala @@ -5,14 +5,14 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sjsonnew.BasicJsonProtocol => +trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => implicit lazy val CallerFormat: JsonFormat[sbt.librarymanagement.Caller] = new JsonFormat[sbt.librarymanagement.Caller] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Caller = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val caller = unbuilder.readField[sbt.librarymanagement.ModuleID]("caller") - val callerConfigurations = unbuilder.readField[Vector[String]]("callerConfigurations") + val callerConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("callerConfigurations") val callerExtraAttributes = unbuilder.readField[Map[String, String]]("callerExtraAttributes") val isForceDependency = unbuilder.readField[Boolean]("isForceDependency") val isChangingDependency = unbuilder.readField[Boolean]("isChangingDependency") diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index b6e1b12b3..2fd00af21 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -19,7 +19,7 @@ final class ConfigRef private ( 37 * (37 * (17 + "ConfigRef".##) + name.##) } override def toString: String = { - "ConfigRef(" + name + ")" + name } protected[this] def copy(name: String = name): ConfigRef = { new ConfigRef(name) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index 2fa190dea..5929ae95d 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement /** Provides information about resolution of a single configuration. */ final class ConfigurationReport private ( /** the configuration this report is for. */ - val configuration: String, + val configuration: sbt.librarymanagement.ConfigRef, /** a sequence containing one report for each module resolved for this configuration. */ val modules: Vector[sbt.librarymanagement.ModuleReport], /** a sequence containing one report for each org/name, which may or may not be part of the final resolution. */ @@ -27,10 +27,10 @@ final class ConfigurationReport private ( (if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map("\t\t(EVICTED) " + _ + "\n").mkString else details.mkString) } - protected[this] def copy(configuration: String = configuration, modules: Vector[sbt.librarymanagement.ModuleReport] = modules, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReport = { + protected[this] def copy(configuration: sbt.librarymanagement.ConfigRef = configuration, modules: Vector[sbt.librarymanagement.ModuleReport] = modules, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReport = { new ConfigurationReport(configuration, modules, details) } - def withConfiguration(configuration: String): ConfigurationReport = { + def withConfiguration(configuration: sbt.librarymanagement.ConfigRef): ConfigurationReport = { copy(configuration = configuration) } def withModules(modules: Vector[sbt.librarymanagement.ModuleReport]): ConfigurationReport = { @@ -42,5 +42,5 @@ final class ConfigurationReport private ( } object ConfigurationReport { - def apply(configuration: String, modules: Vector[sbt.librarymanagement.ModuleReport], details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReport = new ConfigurationReport(configuration, modules, details) + def apply(configuration: sbt.librarymanagement.ConfigRef, modules: Vector[sbt.librarymanagement.ModuleReport], details: Vector[sbt.librarymanagement.OrganizationArtifactReport]): ConfigurationReport = new ConfigurationReport(configuration, modules, details) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index 81a1219ad..d94d09184 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -5,13 +5,13 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => +trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { jsOpt match { case Some(js) => unbuilder.beginObject(js) - val configuration = unbuilder.readField[String]("configuration") + val configuration = unbuilder.readField[sbt.librarymanagement.ConfigRef]("configuration") val modules = unbuilder.readField[Vector[sbt.librarymanagement.ModuleReport]]("modules") val details = unbuilder.readField[Vector[sbt.librarymanagement.OrganizationArtifactReport]]("details") unbuilder.endObject() diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index cd2032c80..dde013ed2 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -17,7 +17,7 @@ final class InclExclRule private ( val organization: String, val name: String, val artifact: String, - val configurations: Vector[String], + val configurations: Vector[sbt.librarymanagement.ConfigRef], val crossVersion: sbt.librarymanagement.CrossVersion) extends Serializable { private def this() = this("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) @@ -32,7 +32,7 @@ final class InclExclRule private ( override def toString: String = { "InclExclRule(" + organization + ", " + name + ", " + artifact + ", " + configurations + ", " + crossVersion + ")" } - protected[this] def copy(organization: String = organization, name: String = name, artifact: String = artifact, configurations: Vector[String] = configurations, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion): InclExclRule = { + protected[this] def copy(organization: String = organization, name: String = name, artifact: String = artifact, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion): InclExclRule = { new InclExclRule(organization, name, artifact, configurations, crossVersion) } def withOrganization(organization: String): InclExclRule = { @@ -44,7 +44,7 @@ final class InclExclRule private ( def withArtifact(artifact: String): InclExclRule = { copy(artifact = artifact) } - def withConfigurations(configurations: Vector[String]): InclExclRule = { + def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): InclExclRule = { copy(configurations = configurations) } def withCrossVersion(crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = { @@ -54,5 +54,5 @@ final class InclExclRule private ( object InclExclRule extends sbt.librarymanagement.InclExclRuleFunctions { def apply(): InclExclRule = new InclExclRule("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) - def apply(organization: String, name: String, artifact: String, configurations: Vector[String], crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = new InclExclRule(organization, name, artifact, configurations, crossVersion) + def apply(organization: String, name: String, artifact: String, configurations: Vector[sbt.librarymanagement.ConfigRef], crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = new InclExclRule(organization, name, artifact, configurations, crossVersion) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala index 76a3c49b8..ed1878b60 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InclExclRuleFormats { self: sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => +trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclRule] = new JsonFormat[sbt.librarymanagement.InclExclRule] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { jsOpt match { @@ -14,7 +14,7 @@ implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclR val organization = unbuilder.readField[String]("organization") val name = unbuilder.readField[String]("name") val artifact = unbuilder.readField[String]("artifact") - val configurations = unbuilder.readField[Vector[String]]("configurations") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") val crossVersion = unbuilder.readField[sbt.librarymanagement.CrossVersion]("crossVersion") unbuilder.endObject() sbt.librarymanagement.InclExclRule(organization, name, artifact, configurations, crossVersion) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 625b142f2..13f44f54e 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -24,7 +24,7 @@ final class ModuleReport private ( val extraAttributes: Map[String, String], val isDefault: Option[Boolean], val branch: Option[String], - val configurations: Vector[String], + val configurations: Vector[sbt.librarymanagement.ConfigRef], val licenses: Vector[scala.Tuple2[String, Option[String]]], val callers: Vector[sbt.librarymanagement.Caller]) extends sbt.librarymanagement.ModuleReportExtra with Serializable { @@ -41,7 +41,7 @@ final class ModuleReport private ( s"\t\t$module: " + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" } - protected[this] def copy(module: sbt.librarymanagement.ModuleID = module, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, missingArtifacts: Vector[sbt.librarymanagement.Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[java.util.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, evictedData: Option[String] = evictedData, evictedReason: Option[String] = evictedReason, problem: Option[String] = problem, homepage: Option[String] = homepage, extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Vector[String] = configurations, licenses: Vector[scala.Tuple2[String, Option[String]]] = licenses, callers: Vector[sbt.librarymanagement.Caller] = callers): ModuleReport = { + protected[this] def copy(module: sbt.librarymanagement.ModuleID = module, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, missingArtifacts: Vector[sbt.librarymanagement.Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[java.util.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, evictedData: Option[String] = evictedData, evictedReason: Option[String] = evictedReason, problem: Option[String] = problem, homepage: Option[String] = homepage, extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, licenses: Vector[scala.Tuple2[String, Option[String]]] = licenses, callers: Vector[sbt.librarymanagement.Caller] = callers): ModuleReport = { new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } def withModule(module: sbt.librarymanagement.ModuleID): ModuleReport = { @@ -89,7 +89,7 @@ final class ModuleReport private ( def withBranch(branch: Option[String]): ModuleReport = { copy(branch = branch) } - def withConfigurations(configurations: Vector[String]): ModuleReport = { + def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): ModuleReport = { copy(configurations = configurations) } def withLicenses(licenses: Vector[scala.Tuple2[String, Option[String]]]): ModuleReport = { @@ -102,5 +102,5 @@ final class ModuleReport private ( object ModuleReport { def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map.empty, None, None, Vector.empty, Vector.empty, Vector.empty) - def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact], status: Option[String], publicationDate: Option[java.util.Calendar], resolver: Option[String], artifactResolver: Option[String], evicted: Boolean, evictedData: Option[String], evictedReason: Option[String], problem: Option[String], homepage: Option[String], extraAttributes: Map[String, String], isDefault: Option[Boolean], branch: Option[String], configurations: Vector[String], licenses: Vector[scala.Tuple2[String, Option[String]]], callers: Vector[sbt.librarymanagement.Caller]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) + def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact], status: Option[String], publicationDate: Option[java.util.Calendar], resolver: Option[String], artifactResolver: Option[String], evicted: Boolean, evictedData: Option[String], evictedReason: Option[String], problem: Option[String], homepage: Option[String], extraAttributes: Map[String, String], isDefault: Option[Boolean], branch: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], licenses: Vector[scala.Tuple2[String, Option[String]]], callers: Vector[sbt.librarymanagement.Caller]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala index fedf5b263..78052a649 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.CallerFormats with sjsonnew.BasicJsonProtocol => +trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CallerFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleReportFormat: JsonFormat[sbt.librarymanagement.ModuleReport] = new JsonFormat[sbt.librarymanagement.ModuleReport] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleReport = { jsOpt match { @@ -26,7 +26,7 @@ implicit lazy val ModuleReportFormat: JsonFormat[sbt.librarymanagement.ModuleRep val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val isDefault = unbuilder.readField[Option[Boolean]]("isDefault") val branch = unbuilder.readField[Option[String]]("branch") - val configurations = unbuilder.readField[Vector[String]]("configurations") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") val licenses = unbuilder.readField[Vector[scala.Tuple2[String, Option[String]]]]("licenses") val callers = unbuilder.readField[Vector[sbt.librarymanagement.Caller]]("callers") unbuilder.endObject() diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala index 9fbb51b2d..158e305cd 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala +++ b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait RetrieveConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +trait RetrieveConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] = new JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.RetrieveConfiguration = { jsOpt match { @@ -14,7 +14,7 @@ implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.internal.libraryma val retrieveDirectory = unbuilder.readField[java.io.File]("retrieveDirectory") val outputPattern = unbuilder.readField[String]("outputPattern") val sync = unbuilder.readField[Boolean]("sync") - val configurationsToRetrieve = unbuilder.readField[Option[Set[sbt.librarymanagement.Configuration]]]("configurationsToRetrieve") + val configurationsToRetrieve = unbuilder.readField[Option[Set[sbt.librarymanagement.ConfigRef]]]("configurationsToRetrieve") unbuilder.endObject() sbt.internal.librarymanagement.RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) case None => diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/librarymanagement/src/main/contraband/librarymanagement.json index 1f87a59de..28422cfdd 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/librarymanagement/src/main/contraband/librarymanagement.json @@ -52,7 +52,7 @@ "type": "record", "fields": [ { "name": "caller", "type": "sbt.librarymanagement.ModuleID" }, - { "name": "callerConfigurations", "type": "String*" }, + { "name": "callerConfigurations", "type": "sbt.librarymanagement.ConfigRef*" }, { "name": "callerExtraAttributes", "type": "Map[String, String]" }, { "name": "isForceDependency", "type": "boolean" }, { "name": "isChangingDependency", "type": "boolean" }, @@ -76,7 +76,8 @@ "doc": [ "The name of the configuration that eventually get used by Maven." ] } ], - "parentsCompanion": "sbt.librarymanagement.ConfigRefFunctions" + "parentsCompanion": "sbt.librarymanagement.ConfigRefFunctions", + "toString": "name" }, { "name": "ConfigurationReport", @@ -88,7 +89,7 @@ ], "parents": "sbt.librarymanagement.ConfigurationReportExtra", "fields": [ - { "name": "configuration", "type": "String", "doc": [ "the configuration this report is for." ] }, + { "name": "configuration", "type": "sbt.librarymanagement.ConfigRef", "doc": [ "the configuration this report is for." ] }, { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*", @@ -233,7 +234,7 @@ { "name": "organization", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "name", "type": "String", "default": "\"*\"", "since": "0.0.1" }, { "name": "artifact", "type": "String", "default": "\"*\"", "since": "0.0.1" }, - { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1"} ], "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" @@ -351,7 +352,7 @@ { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "isDefault", "type": "Option[Boolean]", "default": "None", "since": "0.0.1" }, { "name": "branch", "type": "Option[String]", "default": "None", "since": "0.0.1" }, - { "name": "configurations", "type": "String*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "licenses", "type": "scala.Tuple2[String, Option[String]]*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "callers", "type": "sbt.librarymanagement.Caller*", "default": "Vector.empty", "since": "0.0.1" } ], @@ -805,8 +806,8 @@ "fields": [ { "name": "retrieveDirectory", "type": "java.io.File" }, { "name": "outputPattern", "type": "String" }, - { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "configurationsToRetrieve", "type": "Option[Set[sbt.librarymanagement.Configuration]]", "default": "None", "since": "0.0.1" } + { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, + { "name": "configurationsToRetrieve", "type": "Option[Set[sbt.librarymanagement.ConfigRef]]", "default": "None", "since": "0.0.1" } ] }, { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 48f29920e..ee4977559 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -829,7 +829,7 @@ private[sbt] object IvySbt { IvyScala.excludeRule( excls.organization, excls.name, - excls.configurations, + excls.configurations map { _.name }, excls.artifact ) ) @@ -842,7 +842,7 @@ private[sbt] object IvySbt { IvyScala.includeRule( incls.organization, incls.name, - incls.configurations, + incls.configurations map { _.name }, incls.artifact ) ) @@ -877,7 +877,7 @@ private[sbt] object IvySbt { val exclude = CrossVersion.substituteCross(exclude0, ivyScala) val confs = if (exclude.configurations.isEmpty) moduleID.getConfigurationsNames.toList - else exclude.configurations + else exclude.configurations map { _.name } val excludeRule = IvyScala.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) moduleID.addExcludeRule(excludeRule) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index d989d2cd4..acc8849a5 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -541,19 +541,15 @@ object IvyActions { config: RetrieveConfiguration ): UpdateReport = { val copyChecksums = ivy.getVariable(ConvertResolver.ManagedChecksums).toBoolean - val toRetrieve = config.configurationsToRetrieve + val toRetrieve: Option[Set[ConfigRef]] = config.configurationsToRetrieve val base = config.retrieveDirectory val pattern = config.outputPattern - val configurationNames = toRetrieve match { - case None => None - case Some(configs) => Some(configs.map(_.name)) - } val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] - val retReport = report retrieve { (conf, mid, art, cached) => - configurationNames match { + val retReport = report retrieve { (conf: ConfigRef, mid, art, cached) => + toRetrieve match { case None => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) - case Some(names) if names(conf) => + case Some(refs) if refs(conf) => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) case _ => cached } @@ -572,7 +568,7 @@ object IvyActions { } private def performRetrieve( - conf: String, + conf: ConfigRef, mid: ModuleID, art: Artifact, base: File, @@ -603,7 +599,7 @@ object IvyActions { } private def retrieveTarget( - conf: String, + conf: ConfigRef, mid: ModuleID, art: Artifact, base: File, @@ -611,7 +607,7 @@ object IvyActions { ): File = new File(base, substitute(conf, mid, art, pattern)) - private def substitute(conf: String, mid: ModuleID, art: Artifact, pattern: String): String = { + private def substitute(conf: ConfigRef, mid: ModuleID, art: Artifact, pattern: String): String = { val mextra = IvySbt.javaMap(mid.extraAttributes, true) val aextra = IvySbt.extra(art, true) IvyPatternHelper.substitute( @@ -623,7 +619,7 @@ object IvyActions { art.name, art.`type`, art.extension, - conf, + conf.name, null, mextra, aextra diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 89f81f600..728ffde1b 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -89,7 +89,7 @@ object IvyRetrieve { def toCaller(caller: IvyCaller): Caller = { val m = toModuleID(caller.getModuleRevisionId) val callerConfigurations = caller.getCallerConfigurations.toVector collect { - case x if nonEmptyString(x).isDefined => x + case x if nonEmptyString(x).isDefined => ConfigRef(x) } val ddOpt = Option(caller.getDependencyDescriptor) val (extraAttributes, isForce, isChanging, isTransitive, isDirectlyForce) = ddOpt match { @@ -167,7 +167,9 @@ object IvyRetrieve { case _ => dep.getResolvedId.getExtraAttributes }) val isDefault = Option(dep.getDescriptor) map { _.isDefault } - val configurations = dep.getConfigurations(confReport.getConfiguration).toVector + val configurations = dep.getConfigurations(confReport.getConfiguration).toVector map { + ConfigRef(_) + } val licenses: Vector[(String, Option[String])] = mdOpt match { case Some(md) => md.getLicenses.toVector collect { @@ -235,7 +237,7 @@ object IvyRetrieve { UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = ConfigurationReport( - confReport.getConfiguration, + ConfigRef(confReport.getConfiguration), moduleReports(confReport), organizationArtifactReports(confReport) ) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 2780d5e12..4532b019e 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -35,7 +35,7 @@ private[sbt] object JsonUtil { def toLite(ur: UpdateReport): UpdateReportLite = UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite( - cr.configuration, + cr.configuration.name, cr.details map { oar => OrganizationArtifactReport( @@ -92,7 +92,7 @@ private[sbt] object JsonUtil { !mr.evicted && mr.problem.isEmpty } } - ConfigurationReport(cr.configuration, modules, details) + ConfigurationReport(ConfigRef(cr.configuration), modules, details) } UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index cfb2cc755..e6985e943 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -512,14 +512,16 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { ) val configReports = rootModuleConfigs map { conf => log.debug("::: -----------") - val crs = reports flatMap { _.configurations filter { _.configuration == conf.getName } } - mergeConfigurationReports(conf.getName, crs, os, log) + val crs = reports flatMap { + _.configurations filter { _.configuration.name == conf.getName } + } + mergeConfigurationReports(ConfigRef(conf.getName), crs, os, log) } UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } // memory usage 62%, of which 58% is in mergeOrganizationArtifactReports def mergeConfigurationReports( - rootModuleConf: String, + rootModuleConf: ConfigRef, reports: Vector[ConfigurationReport], os: Vector[IvyOverride], log: Logger @@ -539,7 +541,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * Returns a tuple of (merged org + name combo, newly evicted modules) */ def mergeOrganizationArtifactReports( - rootModuleConf: String, + rootModuleConf: ConfigRef, reports0: Vector[OrganizationArtifactReport], os: Vector[IvyOverride], log: Logger @@ -735,7 +737,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * Returns a touple of (surviving modules ++ non-conflicting modules, newly evicted modules). */ def mergeModuleReports( - rootModuleConf: String, + rootModuleConf: ConfigRef, modules: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger @@ -787,7 +789,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * This transitively evicts any non-evicted modules whose only callers are newly evicted. */ def transitivelyEvict( - rootModuleConf: String, + rootModuleConf: ConfigRef, pairs: List[(String, String)], reports0: Map[(String, String), Vector[OrganizationArtifactReport]], evicted0: Vector[ModuleReport], @@ -833,7 +835,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { * which may be because Ivy makes all Maven dependencies as forced="true". */ def resolveConflict( - rootModuleConf: String, + rootModuleConf: ConfigRef, conflicts: Vector[ModuleReport], os: Vector[IvyOverride], log: Logger @@ -945,7 +947,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } // These are the configurations from the original project we want to resolve. val rootModuleConfs = md0.getConfigurations.toVector - val configurations0 = ur.configurations.toVector + val configurations0: Vector[ConfigurationReport] = ur.configurations.toVector // This is how md looks from md0 via dd's mapping. val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => val remapped @@ -969,7 +971,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val remappedCRs = configurations0 filter { cr => remappedConfigs(conf0.getName) contains cr.configuration } - mergeConfigurationReports(conf0.getName, remappedCRs, os, log) + mergeConfigurationReports(ConfigRef(conf0.getName), remappedCRs, os, log) } UpdateReport(ur.cachedDescriptor, configurations, ur.stats, ur.stamps) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index ae821954c..f6a19955d 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -14,6 +14,7 @@ object Configurations { def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) def auxiliary: Seq[Configuration] = Seq(Pom) def names(cs: Seq[Configuration]) = cs.map(_.name) + def refs(cs: Seq[Configuration]) = cs.map(_.toConfigRef) lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 27900061c..969271fe9 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -28,7 +28,7 @@ trait DependencyFilterExtra { } def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = new ConfigurationFilter { - def apply(c: String): Boolean = name.accept(c) + def apply(c: ConfigRef): Boolean = name.accept(c.name) } } object DependencyFilter extends DependencyFilterExtra { @@ -38,7 +38,7 @@ object DependencyFilter extends DependencyFilterExtra { artifact: ArtifactFilter = artifactFilter() ): DependencyFilter = new DependencyFilter { - def apply(c: String, m: ModuleID, a: Artifact): Boolean = + def apply(c: ConfigRef, m: ModuleID, a: Artifact): Boolean = configuration(c) && module(m) && artifact(a) } def apply( @@ -47,7 +47,7 @@ object DependencyFilter extends DependencyFilterExtra { combine: (Boolean, Boolean) => Boolean ): DependencyFilter = new DependencyFilter { - def apply(c: String, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) + def apply(c: ConfigRef, m: ModuleID, a: Artifact): Boolean = combine(x(c, m, a), y(c, m, a)) } def allPass: DependencyFilter = configurationFilter() implicit def fnToModuleFilter(f: ModuleID => Boolean): ModuleFilter = new ModuleFilter { @@ -56,12 +56,12 @@ object DependencyFilter extends DependencyFilterExtra { implicit def fnToArtifactFilter(f: Artifact => Boolean): ArtifactFilter = new ArtifactFilter { def apply(m: Artifact) = f(m) } - implicit def fnToConfigurationFilter(f: String => Boolean): ConfigurationFilter = - new ConfigurationFilter { def apply(c: String) = f(c) } + implicit def fnToConfigurationFilter(f: ConfigRef => Boolean): ConfigurationFilter = + new ConfigurationFilter { def apply(c: ConfigRef) = f(c) } implicit def subDepFilterToFn[Arg](f: SubDepFilter[Arg, _]): Arg => Boolean = f apply _ } trait DependencyFilter { - def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean + def apply(configuration: ConfigRef, module: ModuleID, artifact: Artifact): Boolean final def &&(o: DependencyFilter) = DependencyFilter(this, o, _ && _) final def ||(o: DependencyFilter) = DependencyFilter(this, o, _ || _) final def --(o: DependencyFilter) = DependencyFilter(this, o, _ && !_) @@ -80,20 +80,20 @@ trait ModuleFilter extends SubDepFilter[ModuleID, ModuleFilter] { protected final def make(f: ModuleID => Boolean) = new ModuleFilter { def apply(m: ModuleID) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + final def apply(configuration: ConfigRef, module: ModuleID, artifact: Artifact): Boolean = apply(module) } trait ArtifactFilter extends SubDepFilter[Artifact, ArtifactFilter] { protected final def make(f: Artifact => Boolean) = new ArtifactFilter { def apply(m: Artifact) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + final def apply(configuration: ConfigRef, module: ModuleID, artifact: Artifact): Boolean = apply(artifact) } -trait ConfigurationFilter extends SubDepFilter[String, ConfigurationFilter] { - protected final def make(f: String => Boolean) = new ConfigurationFilter { - def apply(m: String) = f(m) +trait ConfigurationFilter extends SubDepFilter[ConfigRef, ConfigurationFilter] { + protected final def make(f: ConfigRef => Boolean) = new ConfigurationFilter { + def apply(m: ConfigRef) = f(m) } - final def apply(configuration: String, module: ModuleID, artifact: Artifact): Boolean = + final def apply(configuration: ConfigRef, module: ModuleID, artifact: Artifact): Boolean = apply(configuration) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 66e9d3185..7316be808 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -8,7 +8,7 @@ import sbt.util.ShowLines import sbt.internal.librarymanagement.{ InlineConfiguration, IvySbt } final class EvictionWarningOptions private[sbt] ( - val configurations: Seq[Configuration], + val configurations: Seq[ConfigRef], val warnScalaVersionEviction: Boolean, val warnDirectEvictions: Boolean, val warnTransitiveEvictions: Boolean, @@ -16,9 +16,7 @@ final class EvictionWarningOptions private[sbt] ( val showCallers: Boolean, val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] ) { - private[sbt] def configStrings = configurations map { _.name } - - def withConfigurations(configurations: Seq[Configuration]): EvictionWarningOptions = + def withConfigurations(configurations: Seq[ConfigRef]): EvictionWarningOptions = copy(configurations = configurations) def withWarnScalaVersionEviction(warnScalaVersionEviction: Boolean): EvictionWarningOptions = copy(warnScalaVersionEviction = warnScalaVersionEviction) @@ -36,7 +34,7 @@ final class EvictionWarningOptions private[sbt] ( copy(guessCompatible = guessCompatible) private[sbt] def copy( - configurations: Seq[Configuration] = configurations, + configurations: Seq[ConfigRef] = configurations, warnScalaVersionEviction: Boolean = warnScalaVersionEviction, warnDirectEvictions: Boolean = warnDirectEvictions, warnTransitiveEvictions: Boolean = warnTransitiveEvictions, @@ -193,7 +191,7 @@ object EvictionWarning { ): Seq[OrganizationArtifactReport] = { val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() val confs = report.configurations filter { x => - options.configStrings contains x.configuration + options.configurations contains x.configuration } confs flatMap { confReport => confReport.details map { detail => diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 6d7e1c581..e4b9d1045 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -69,7 +69,7 @@ final class RichUpdateReport(report: UpdateReport) { } private[sbt] def substitute( - f: (String, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)] + f: (ConfigRef, ModuleID, Vector[(Artifact, File)]) => Vector[(Artifact, File)] ): UpdateReport = moduleReportMap { (configuration, modReport) => val newArtifacts = f(configuration, modReport.module, modReport.artifacts) @@ -78,15 +78,15 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts(modReport.missingArtifacts) } - def toSeq: Seq[(String, ModuleID, Artifact, File)] = toVector - def toVector: Vector[(String, ModuleID, Artifact, File)] = + def toSeq: Seq[(ConfigRef, ModuleID, Artifact, File)] = toVector + def toVector: Vector[(ConfigRef, ModuleID, Artifact, File)] = for { confReport <- report.configurations modReport <- confReport.modules (artifact, file) <- modReport.artifacts } yield (confReport.configuration, modReport.module, artifact, file) - def allMissing: Vector[(String, ModuleID, Artifact)] = + def allMissing: Vector[(ConfigRef, ModuleID, Artifact)] = for { confReport <- report.configurations modReport <- confReport.modules @@ -99,7 +99,7 @@ final class RichUpdateReport(report: UpdateReport) { .withMissingArtifacts((modReport.missingArtifacts ++ f(modReport.module)).distinct) } - private[sbt] def moduleReportMap(f: (String, ModuleReport) => ModuleReport): UpdateReport = { + private[sbt] def moduleReportMap(f: (ConfigRef, ModuleReport) => ModuleReport): UpdateReport = { val newConfigurations = report.configurations.map { confReport => import confReport._ val newModules = modules map { modReport => diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 7f2c39fa6..db97688df 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -7,7 +7,7 @@ import java.io.File import java.{ util => ju } abstract class ConfigurationReportExtra { - def configuration: String + def configuration: ConfigRef def modules: Vector[ModuleReport] def details: Vector[OrganizationArtifactReport] @@ -28,7 +28,7 @@ abstract class ConfigurationReportExtra { } else module } - def retrieve(f: (String, ModuleID, Artifact, File) => File): ConfigurationReport = + def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): ConfigurationReport = ConfigurationReport(configuration, modules map { _.retrieve((mid, art, file) => f(configuration, mid, art, file)) }, details) @@ -50,7 +50,7 @@ abstract class ModuleReportExtra { def extraAttributes: Map[String, String] def isDefault: Option[Boolean] def branch: Option[String] - def configurations: Vector[String] + def configurations: Vector[ConfigRef] def licenses: Vector[(String, Option[String])] def callers: Vector[Caller] @@ -115,7 +115,7 @@ abstract class ModuleReportExtra { extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, - configurations: Vector[String] = configurations, + configurations: Vector[ConfigRef] = configurations, licenses: Vector[(String, Option[String])] = licenses, callers: Vector[Caller] = callers ): ModuleReport @@ -144,12 +144,12 @@ abstract class UpdateReportExtra { } } - def retrieve(f: (String, ModuleID, Artifact, File) => File): UpdateReport = + def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ - def configuration(s: String) = configurations.find(_.configuration == s) + def configuration(s: ConfigRef) = configurations.find(_.configuration == s) /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ - def allConfigurations: Seq[String] = configurations.map(_.configuration) + def allConfigurations: Vector[ConfigRef] = configurations.map(_.configuration) } diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/librarymanagement/src/test/scala/DMSerializationSpec.scala index 35c0f7c01..d38c8fcdb 100644 --- a/librarymanagement/src/test/scala/DMSerializationSpec.scala +++ b/librarymanagement/src/test/scala/DMSerializationSpec.scala @@ -57,7 +57,7 @@ class DMSerializationSpec extends UnitSpec { UpdateStats(0, 0, 0, false), Map(new File("./foo") -> 0)) lazy val configurationReportExample = - ConfigurationReport("compile", + ConfigurationReport(ConfigRef("compile"), Vector(moduleReportExample), Vector(organizationArtifactReportExample)) lazy val organizationArtifactReportExample = diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 51be80d06..30965e810 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -28,7 +28,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val report = ivyUpdate(m) import Inside._ - inside(report.configuration("compile").map(_.modules)) { + inside(report.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => @@ -82,7 +82,7 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { log) import Inside._ - inside(report2.configuration("compile").map(_.modules)) { + inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1f8e6f5f2..264d23e13 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -46,6 +46,7 @@ object Dependencies { val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test + val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" % Test val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" From f8c656e74dad00383d933b85c157ca72632234ea Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 Jul 2017 09:55:33 -0400 Subject: [PATCH 0646/1030] Expose Configuration factory apply was hidden, so the config macro failed outside of sbt package. --- .../sbt/internal/librarymanagement/Ivy.scala | 2 +- .../sbt/librarymanagement/Configuration.scala | 15 +++---- .../ConfigurationExtra.scala | 41 +++++++++++-------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index ee4977559..c01576336 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -238,7 +238,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => import ic._ val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) - val defaultConf = defaultConfiguration getOrElse Configuration( + val defaultConf = defaultConfiguration getOrElse Configuration.of( "Default", ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug( diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala index 9a65e8b46..9f642efd6 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -67,13 +67,14 @@ final class Configuration private[sbt] ( def toConfigRef: ConfigRef = ConfigRef(name) } object Configuration { - private[sbt] def apply(id: String, name: String): Configuration = + // Don't call this directly. It's intended to be used from config macro. + def of(id: String, name: String): Configuration = new Configuration(id, name, "", true, Vector.empty, true) - private[sbt] def apply(id: String, - name: String, - description: String, - isPublic: Boolean, - extendsConfigs: Vector[sbt.librarymanagement.Configuration], - transitive: Boolean): Configuration = + def of(id: String, + name: String, + description: String, + isPublic: Boolean, + extendsConfigs: Vector[sbt.librarymanagement.Configuration], + transitive: Boolean): Configuration = new Configuration(id, name, description, isPublic, extendsConfigs, transitive) } diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index f6a19955d..954a3eeae 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -30,25 +30,25 @@ object Configurations { } private[sbt] def internal(base: Configuration, ext: Configuration*) = - Configuration(base.id + "Internal", base.name + "-internal").extend(ext: _*).hide + Configuration.of(base.id + "Internal", base.name + "-internal").extend(ext: _*).hide private[sbt] def fullInternal(base: Configuration): Configuration = internal(base, base, Optional, Provided) private[sbt] def optionalInternal(base: Configuration): Configuration = internal(base, base, Optional) - lazy val Default = Configuration("Default", "default") - lazy val Compile = Configuration("Compile", "compile") - lazy val IntegrationTest = Configuration("IntegrationTest", "it") extend (Runtime) - lazy val Provided = Configuration("Provided", "provided") - lazy val Runtime = Configuration("Runtime", "runtime") extend (Compile) - lazy val Test = Configuration("Test", "test") extend (Runtime) - lazy val System = Configuration("System", "system") - lazy val Optional = Configuration("Optional", "optional") - lazy val Pom = Configuration("Pom", "pom") + lazy val Default = Configuration.of("Default", "default") + lazy val Compile = Configuration.of("Compile", "compile") + lazy val IntegrationTest = Configuration.of("IntegrationTest", "it") extend (Runtime) + lazy val Provided = Configuration.of("Provided", "provided") + lazy val Runtime = Configuration.of("Runtime", "runtime") extend (Compile) + lazy val Test = Configuration.of("Test", "test") extend (Runtime) + lazy val System = Configuration.of("System", "system") + lazy val Optional = Configuration.of("Optional", "optional") + lazy val Pom = Configuration.of("Pom", "pom") - lazy val ScalaTool = Configuration("ScalaTool", "scala-tool").hide - lazy val CompilerPlugin = Configuration("CompilerPlugin", "plugin").hide - lazy val Component = Configuration("Component", "component").hide + lazy val ScalaTool = Configuration.of("ScalaTool", "scala-tool").hide + lazy val CompilerPlugin = Configuration.of("CompilerPlugin", "plugin").hide + lazy val Component = Configuration.of("Component", "component").hide private[sbt] val DefaultMavenConfiguration = defaultConfiguration(true) private[sbt] val DefaultIvyConfiguration = defaultConfiguration(false) @@ -87,12 +87,17 @@ abstract class ConfigurationExtra { require(description != null) def describedAs(newDescription: String) = - Configuration(id, name, newDescription, isPublic, extendsConfigs, transitive) + Configuration.of(id, name, newDescription, isPublic, extendsConfigs, transitive) def extend(configs: Configuration*) = - Configuration(id, name, description, isPublic, configs.toVector ++ extendsConfigs, transitive) + Configuration.of(id, + name, + description, + isPublic, + configs.toVector ++ extendsConfigs, + transitive) def notTransitive = intransitive - def intransitive = Configuration(id, name, description, isPublic, extendsConfigs, false) - def hide = Configuration(id, name, description, false, extendsConfigs, transitive) + def intransitive = Configuration.of(id, name, description, isPublic, extendsConfigs, false) + def hide = Configuration.of(id, name, description, false, extendsConfigs, transitive) } private[sbt] object ConfigurationMacro { @@ -105,7 +110,7 @@ private[sbt] object ConfigurationMacro { methodName => s"""$methodName must be directly assigned to a val, such as `val x = $methodName`.""") val id = c.Expr[String](Literal(Constant(enclosingValName))) - reify { Configuration(id.splice, name.splice) } + reify { Configuration.of(id.splice, name.splice) } } def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = { From 7b22e78fd94094d2eb888a79602a5240135357b2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 11 Jul 2017 18:39:06 -0400 Subject: [PATCH 0647/1030] Library management API This splits the core of LM and Ivy-based implementation. - InlineConfiguration is renamed to ModuleConfiguration - IvyScala is renamed to ScalaModuleInfo - UpdateConfiguration, RetrieveConfiguration, PublishConfiguration are refactored to use builder pattern. - Adds ConfigRef for referencing Configuration - Moves syntax related things into `sbt.librarymagement.syntax` --- README.md | 31 +- build.sbt | 23 +- {librarymanagement => core}/NOTICE | 0 .../ConfigurationReportLite.scala | 0 .../librarymanagement/UpdateReportLite.scala | 0 .../sbt/librarymanagement/Artifact.scala | 0 .../librarymanagement/ArtifactFormats.scala | 0 .../ArtifactTypeFilter.scala | 0 .../ArtifactTypeFilterFormats.scala | 0 .../sbt/librarymanagement/Binary.scala | 0 .../sbt/librarymanagement/BinaryFormats.scala | 0 .../sbt/librarymanagement/Caller.scala | 0 .../sbt/librarymanagement/CallerFormats.scala | 0 .../librarymanagement/ChainedResolver.scala | 0 .../ChainedResolverFormats.scala | 0 .../sbt/librarymanagement/Checksum.scala | 0 .../librarymanagement/ChecksumFormats.scala | 0 .../sbt/librarymanagement/ConfigRef.scala | 0 .../librarymanagement/ConfigRefFormats.scala | 0 .../ConfigurationReport.scala | 0 .../ConfigurationReportFormats.scala | 0 .../ConfigurationReportLiteFormats.scala | 0 .../librarymanagement/ConflictManager.scala | 0 .../ConflictManagerFormats.scala | 0 .../sbt/librarymanagement/Constant.scala | 0 .../librarymanagement/ConstantFormats.scala | 0 .../sbt/librarymanagement/CrossVersion.scala | 0 .../CrossVersionFormats.scala | 0 .../sbt/librarymanagement/Developer.scala | 0 .../librarymanagement/DeveloperFormats.scala | 0 .../sbt/librarymanagement/Disabled.scala | 0 .../librarymanagement/DisabledFormats.scala | 0 .../librarymanagement/FileConfiguration.scala | 0 .../FileConfigurationFormats.scala | 0 .../librarymanagement/FileRepository.scala | 0 .../FileRepositoryFormats.scala | 0 .../sbt/librarymanagement/Full.scala | 0 .../sbt/librarymanagement/FullFormats.scala | 0 .../GetClassifiersConfiguration.scala | 48 +++ .../GetClassifiersConfigurationFormats.scala | 35 ++ .../GetClassifiersModule.scala | 52 +++ .../GetClassifiersModuleFormats.scala | 35 ++ .../sbt/librarymanagement/InclExclRule.scala | 0 .../InclExclRuleFormats.scala | 0 .../IvyFileConfiguration.scala | 49 +++ .../IvyFileConfigurationFormats.scala | 8 +- .../KeyFileAuthentication.scala | 0 .../KeyFileAuthenticationFormats.scala | 0 .../LibraryManagementCodec.scala | 25 +- .../sbt/librarymanagement/MavenCache.scala | 0 .../librarymanagement/MavenCacheFormats.scala | 0 .../sbt/librarymanagement/MavenRepo.scala | 0 .../librarymanagement/MavenRepoFormats.scala | 0 .../librarymanagement/MavenRepository.scala | 0 .../MavenRepositoryFormats.scala | 0 .../ModuleConfiguration.scala | 0 .../ModuleConfigurationFormats.scala | 0 .../ModuleDescriptorConfiguration.scala | 80 ++++ ...ModuleDescriptorConfigurationFormats.scala | 16 +- .../sbt/librarymanagement/ModuleID.scala | 0 .../librarymanagement/ModuleIDFormats.scala | 0 .../sbt/librarymanagement/ModuleInfo.scala | 0 .../librarymanagement/ModuleInfoFormats.scala | 0 .../sbt/librarymanagement/ModuleReport.scala | 0 .../ModuleReportFormats.scala | 0 .../librarymanagement/ModuleSettings.scala | 10 +- .../ModuleSettingsFormats.scala | 11 + .../OrganizationArtifactReport.scala | 0 .../OrganizationArtifactReportFormats.scala | 0 .../PasswordAuthentication.scala | 0 .../PasswordAuthenticationFormats.scala | 0 .../sbt/librarymanagement/Patch.scala | 0 .../sbt/librarymanagement/PatchFormats.scala | 0 .../sbt/librarymanagement/Patterns.scala | 0 .../PatternsBasedRepository.scala | 0 .../PatternsBasedRepositoryFormats.scala | 0 .../librarymanagement/PatternsFormats.scala | 0 .../librarymanagement/PomConfiguration.scala | 49 +++ .../PomConfigurationFormats.scala | 8 +- .../PublishConfiguration.scala | 81 ++++ .../PublishConfigurationFormats.scala | 43 ++ .../sbt/librarymanagement/Resolver.scala | 0 .../librarymanagement/ResolverFormats.scala | 0 .../RetrieveConfiguration.scala | 58 +++ .../RetrieveConfigurationFormats.scala | 14 +- .../librarymanagement/ScalaModuleInfo.scala | 34 +- .../ScalaModuleInfoFormats.scala | 10 +- .../sbt/librarymanagement/ScmInfo.scala | 0 .../librarymanagement/ScmInfoFormats.scala | 0 .../librarymanagement/SftpRepository.scala | 0 .../SftpRepositoryFormats.scala | 0 .../librarymanagement/SshAuthentication.scala | 0 .../SshAuthenticationFormats.scala | 0 .../SshBasedRepository.scala | 0 .../SshBasedRepositoryFormats.scala | 0 .../sbt/librarymanagement/SshConnection.scala | 0 .../SshConnectionFormats.scala | 0 .../sbt/librarymanagement/SshRepository.scala | 0 .../SshRepositoryFormats.scala | 0 .../sbt/librarymanagement/URLRepository.scala | 0 .../URLRepositoryFormats.scala | 0 .../UpdateConfiguration.scala | 82 ++++ .../UpdateConfigurationFormats.scala | 14 +- .../sbt/librarymanagement/UpdateLogging.scala | 0 .../UpdateLoggingFormats.scala | 0 .../sbt/librarymanagement/UpdateReport.scala | 0 .../UpdateReportFormats.scala | 0 .../UpdateReportLiteFormats.scala | 0 .../sbt/librarymanagement/UpdateStats.scala | 0 .../UpdateStatsFormats.scala | 0 .../main/contraband/librarymanagement.json | 288 ++++++++----- .../mavenint/SbtPomExtraProperties.java | 0 .../CompatibilityWarning.scala | 10 +- .../librarymanagement/InternalDefaults.scala | 29 ++ .../librarymanagement/IvyConfigurations.scala | 0 .../internal/librarymanagement/JsonUtil.scala | 4 +- .../librarymanagement/StringUtilities.scala | 0 .../UpdateClassifiersUtil.scala | 79 ++++ .../librarymanagement/VersionRange.scala | 10 +- .../cross/CrossVersionUtil.scala | 0 .../formats/GlobalLockFormat.scala | 0 .../formats/LoggerFormat.scala | 0 .../formats/LogicalClockFormats.scala | 13 + .../formats/NodeSeqFormat.scala | 0 .../sbt/librarymanagement/ArtifactExtra.scala | 7 +- .../sbt/librarymanagement/Configuration.scala | 0 .../ConfigurationExtra.scala | 23 +- .../ConfigurationFormats.scala | 3 +- .../librarymanagement/ConflictWarning.scala | 0 .../librarymanagement/CrossVersionExtra.scala | 7 +- .../DependencyBuilders.scala | 67 +++ .../librarymanagement/DependencyFilter.scala | 0 .../librarymanagement/EvictionWarning.scala | 40 +- .../scala/sbt/librarymanagement/Extra.scala | 20 +- .../scala/sbt/librarymanagement/Http.scala | 0 .../librarymanagement/LibraryManagement.scala | 198 +++++++++ .../LibraryManagementInterface.scala | 84 ++++ .../LibraryManagementSyntax.scala | 24 ++ .../sbt}/librarymanagement/LogicalClock.scala | 2 +- .../MakePomConfiguration.scala | 15 + .../sbt/librarymanagement/ModuleIDExtra.scala | 1 + .../sbt/librarymanagement/ResolverExtra.scala | 51 +-- .../librarymanagement/RichUpdateReport.scala | 2 +- .../librarymanagement/ScalaArtifacts.scala | 42 ++ .../sbt/librarymanagement/TrackLevel.scala | 0 .../librarymanagement/UnresolvedWarning.scala | 88 ++++ .../librarymanagement/UpdateReportExtra.scala | 2 +- .../sbt/librarymanagement/VersionNumber.scala | 3 +- .../src/test/scala/ConfigMacroSpec.scala | 0 .../ivy/ExternalIvyConfiguration.scala | 66 +++ .../ExternalIvyConfigurationFormats.scala | 22 +- .../ivy/InlineIvyConfiguration.scala | 104 +++++ .../ivy}/InlineIvyConfigurationFormats.scala | 20 +- .../ivy/IvyConfiguration.scala | 28 ++ .../ivy/IvyConfigurationFormats.scala | 11 + .../sbt/librarymanagement/ivy}/IvyPaths.scala | 2 +- .../ivy}/IvyPathsFormats.scala | 10 +- ivy/src/main/contraband/lm-ivy.json | 144 +++++++ .../librarymanagement/ResolverAdapter.java | 0 .../ReplaceMavenConfigurationMappings.scala | 0 .../librarymanagement/ComponentManager.scala | 2 +- .../librarymanagement/ConvertResolver.scala | 6 +- .../librarymanagement/CustomPomParser.scala | 0 .../librarymanagement/CustomXmlParser.scala | 0 .../librarymanagement/FakeResolver.scala | 0 .../sbt/internal/librarymanagement/Ivy.scala | 98 +++-- .../librarymanagement/IvyActions.scala | 405 ++++-------------- .../internal/librarymanagement/IvyCache.scala | 18 +- .../IvyInternalDefaults.scala | 28 ++ .../librarymanagement/IvyLogger.scala | 0 .../librarymanagement/IvyRetrieve.scala | 0 .../librarymanagement/IvyScalaUtil.scala | 56 +-- .../internal/librarymanagement/IvyUtil.scala | 0 .../internal/librarymanagement/MakePom.scala | 3 +- .../librarymanagement/ProjectResolver.scala | 0 .../librarymanagement/ResolutionCache.scala | 0 .../CachedResolutionResolveEngine.scala | 10 +- .../ivyint/CustomMavenResolver.scala | 0 .../ivyint/ErrorMessageAuthenticator.scala | 8 +- .../ivyint/GigahorseUrlHandler.scala | 0 .../ivyint/IvyCredentialsLookup.scala | 0 .../ivyint/MergeDescriptors.scala | 0 .../ivyint/ParallelResolveEngine.scala | 0 .../ivyint/SbtChainResolver.scala | 1 + .../SbtDefaultDependencyDescriptor.scala | 0 .../PomExtraDependencyAttributes.scala | 0 .../ivy}/CircularDependencyLevel.scala | 1 + .../librarymanagement/ivy}/Credentials.scala | 1 + .../librarymanagement/ivy/IvyDefaults.scala | 9 + .../ivy/IvyLibraryManagement.scala | 30 ++ .../ivy/IvyLibraryManagementCodec.scala | 17 + .../librarymanagement/ivy/IvyPublisher.scala | 35 ++ .../ivy}/UpdateOptions.scala | 1 + .../ivy}/formats/UpdateOptionsFormat.scala | 2 +- .../src/test/resources/artifact1.jar | Bin .../src/test/resources/artifact2.txt | 0 .../module-with-srcs/0.1.00/ivys/ivy.xml | 0 .../0.1.00/jars/libmodule.jar | Bin .../0.1.00/srcs/libmodule-source.jar | Bin .../test-artifact-1.0.0-SNAPSHOT.jar | 0 .../test-artifact-1.0.0-SNAPSHOT.pom | 0 .../src/test/scala/BaseIvySpecification.scala | 85 ++-- .../src/test/scala/CachedResolutionSpec.scala | 1 + .../src/test/scala/ComponentManagerTest.scala | 0 .../src/test/scala/CrossVersionTest.scala | 0 .../src/test/scala/CustomPomParserTest.scala | 15 +- .../src/test/scala/DMSerializationSpec.scala | 0 .../src/test/scala/EvictionWarningSpec.scala | 0 .../src/test/scala/FrozenModeSpec.scala | 12 +- .../src/test/scala/InclExclSpec.scala | 11 +- .../scala/InconsistentDuplicateSpec.scala | 0 .../src/test/scala/MakePomSpec.scala | 0 .../src/test/scala/MergeDescriptorSpec.scala | 5 +- .../src/test/scala/ModuleIdTest.scala | 0 .../src/test/scala/ModuleResolversTest.scala | 6 +- .../src/test/scala/OfflineModeSpec.scala | 15 +- .../src/test/scala/ResolverTest.scala | 0 .../src/test/scala/ScalaOverrideTest.scala | 2 +- .../src/test/scala/UpdateOptionsSpec.scala | 2 +- .../src/test/scala/VersionNumberSpec.scala | 4 +- .../FakeResolverSpecification.scala | 5 +- .../librarymanagement/IvyRepoSpec.scala | 34 +- .../ManagedChecksumsSpec.scala | 43 +- .../librarymanagement/TestLogger.scala | 0 .../internal/librarymanagement/UnitSpec.scala | 0 .../librarymanagement/VersionRangeSpec.scala | 0 .../ExternalIvyConfiguration.scala | 56 --- .../InlineConfiguration.scala | 78 ---- .../InlineIvyConfiguration.scala | 92 ---- .../librarymanagement/IvyConfiguration.scala | 29 -- .../RetrieveConfiguration.scala | 45 -- .../sbt/librarymanagement/Configuration.scala | 50 --- .../ConfigurationFormats.scala | 35 -- .../IvyConfigurationFormats.scala | 11 - .../IvyFileConfiguration.scala | 48 --- .../ModuleSettingsFormats.scala | 11 - .../librarymanagement/PomConfiguration.scala | 48 --- .../UpdateConfiguration.scala | 56 --- .../formats/DependencyResolverFormat.scala | 8 - .../impl/DependencyBuilders.scala | 58 --- .../DefaultLibraryManagement.scala | 105 ----- .../librarymanagement/LibraryManagement.scala | 8 - .../LibraryManagementSyntax.scala | 7 - .../scala/sbt/librarymanagement/package.scala | 9 - notes/1.0.0.markdown | 5 + project/DatatypeConfig.scala | 8 +- 246 files changed, 2441 insertions(+), 1632 deletions(-) rename {librarymanagement => core}/NOTICE (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Binary.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Caller.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Constant.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Developer.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Full.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala (79%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala (82%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala rename librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala => core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala (60%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala (67%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Patch.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala (75%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala (59%) rename librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala => core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala (54%) rename librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala => core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala (74%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala (100%) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala (63%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala (100%) rename {librarymanagement => core}/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala (100%) rename {librarymanagement => core}/src/main/contraband/librarymanagement.json (84%) rename {librarymanagement => core}/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java (100%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala (86%) create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/InternalDefaults.scala rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala (97%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala (100%) create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala (94%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala (100%) create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/formats/LogicalClockFormats.scala rename {librarymanagement => core}/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala (93%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/Configuration.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala (86%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala (95%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ConflictWarning.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala (96%) create mode 100755 core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/DependencyFilter.scala (100%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/EvictionWarning.scala (90%) rename librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala => core/src/main/scala/sbt/librarymanagement/Extra.scala (71%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/Http.scala (100%) create mode 100644 core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala create mode 100644 core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala create mode 100644 core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala rename {librarymanagement/src/main/scala/sbt/internal => core/src/main/scala/sbt}/librarymanagement/LogicalClock.scala (94%) create mode 100644 core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala (99%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/ResolverExtra.scala (93%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala (98%) create mode 100644 core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/TrackLevel.scala (100%) create mode 100644 core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala (99%) rename {librarymanagement => core}/src/main/scala/sbt/librarymanagement/VersionNumber.scala (98%) rename {librarymanagement => core}/src/test/scala/ConfigMacroSpec.scala (100%) create mode 100644 ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala rename {librarymanagement/src/main/contraband-scala/sbt/librarymanagement => ivy/src/main/contraband-scala/sbt/librarymanagement/ivy}/ExternalIvyConfigurationFormats.scala (58%) create mode 100644 ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala rename {librarymanagement/src/main/contraband-scala/sbt/librarymanagement => ivy/src/main/contraband-scala/sbt/librarymanagement/ivy}/InlineIvyConfigurationFormats.scala (61%) create mode 100644 ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala create mode 100644 ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala rename {librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement => ivy/src/main/contraband-scala/sbt/librarymanagement/ivy}/IvyPaths.scala (97%) rename {librarymanagement/src/main/contraband-scala/sbt/librarymanagement => ivy/src/main/contraband-scala/sbt/librarymanagement/ivy}/IvyPathsFormats.scala (67%) create mode 100644 ivy/src/main/contraband/lm-ivy.json rename {librarymanagement/src/main/java/sbt => ivy/src/main/java}/internal/librarymanagement/ResolverAdapter.java (100%) rename {librarymanagement => ivy}/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala (98%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala (98%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/Ivy.scala (92%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala (53%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala (96%) create mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala (100%) rename librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala => ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala (82%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/MakePom.scala (99%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala (99%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala (93%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala (99%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala (100%) rename {librarymanagement => ivy}/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala (100%) rename {librarymanagement/src/main/scala/sbt/librarymanagement => ivy/src/main/scala/sbt/librarymanagement/ivy}/CircularDependencyLevel.scala (98%) rename {librarymanagement/src/main/scala/sbt/librarymanagement => ivy/src/main/scala/sbt/librarymanagement/ivy}/Credentials.scala (99%) create mode 100644 ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDefaults.scala create mode 100644 ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala create mode 100644 ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagementCodec.scala create mode 100644 ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala rename {librarymanagement/src/main/scala/sbt/librarymanagement => ivy/src/main/scala/sbt/librarymanagement/ivy}/UpdateOptions.scala (99%) rename {librarymanagement/src/main/scala/sbt/internal/librarymanagement => ivy/src/main/scala/sbt/librarymanagement/ivy}/formats/UpdateOptionsFormat.scala (97%) rename {librarymanagement => ivy}/src/test/resources/artifact1.jar (100%) rename {librarymanagement => ivy}/src/test/resources/artifact2.txt (100%) rename {librarymanagement => ivy}/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml (100%) rename {librarymanagement => ivy}/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar (100%) rename {librarymanagement => ivy}/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar (100%) rename {librarymanagement => ivy}/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar (100%) rename {librarymanagement => ivy}/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom (100%) rename {librarymanagement => ivy}/src/test/scala/BaseIvySpecification.scala (55%) rename {librarymanagement => ivy}/src/test/scala/CachedResolutionSpec.scala (98%) rename {librarymanagement => ivy}/src/test/scala/ComponentManagerTest.scala (100%) rename {librarymanagement => ivy}/src/test/scala/CrossVersionTest.scala (100%) rename {librarymanagement => ivy}/src/test/scala/CustomPomParserTest.scala (71%) rename {librarymanagement => ivy}/src/test/scala/DMSerializationSpec.scala (100%) rename {librarymanagement => ivy}/src/test/scala/EvictionWarningSpec.scala (100%) rename {librarymanagement => ivy}/src/test/scala/FrozenModeSpec.scala (84%) rename {librarymanagement => ivy}/src/test/scala/InclExclSpec.scala (84%) rename {librarymanagement => ivy}/src/test/scala/InconsistentDuplicateSpec.scala (100%) rename {librarymanagement => ivy}/src/test/scala/MakePomSpec.scala (100%) rename {librarymanagement => ivy}/src/test/scala/MergeDescriptorSpec.scala (92%) rename {librarymanagement => ivy}/src/test/scala/ModuleIdTest.scala (100%) rename {librarymanagement => ivy}/src/test/scala/ModuleResolversTest.scala (92%) rename {librarymanagement => ivy}/src/test/scala/OfflineModeSpec.scala (88%) rename {librarymanagement => ivy}/src/test/scala/ResolverTest.scala (100%) rename {librarymanagement => ivy}/src/test/scala/ScalaOverrideTest.scala (98%) rename {librarymanagement => ivy}/src/test/scala/UpdateOptionsSpec.scala (95%) rename {librarymanagement => ivy}/src/test/scala/VersionNumberSpec.scala (98%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala (95%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala (75%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala (63%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala (100%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala (100%) rename {librarymanagement => ivy}/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala (100%) delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala delete mode 100644 librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala delete mode 100644 librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala delete mode 100755 librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala delete mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala delete mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala delete mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala delete mode 100644 librarymanagement/src/main/scala/sbt/librarymanagement/package.scala create mode 100644 notes/1.0.0.markdown diff --git a/README.md b/README.md index a265c06e9..d3e7f5c20 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,27 @@ librarymanagement module for sbt ================================ -``` -git clone --no-hardlinks --branch 0.13 sbt sbt-modules/librarymanagement -cd sbt-modules/librarymanagement -git filter-branch --index-filter 'git rm --cached -qr -- . && git reset -q $GIT_COMMIT -- ivy util/cross' --prune-empty -git reset --hard -git gc --aggressive -git prune -git cb 1.0 +```scala +scala> import java.io.File +import java.io.File + +scala> import sbt.librarymanagement._, syntax._ +import sbt.librarymanagement._ +import syntax._ + +scala> val log = sbt.util.LogExchange.logger("test") +log: sbt.internal.util.ManagedLogger = sbt.internal.util.ManagedLogger@c439b0f + +scala> val lm = { + import sbt.librarymanagement.ivy._ + val ivyConfig = InlineIvyConfiguration().withLog(log) + IvyLibraryManagement(ivyConfig) + } +lm: sbt.librarymanagement.LibraryManagement = sbt.librarymanagement.ivy.IvyLibraryManagement@11c07acb + +scala> val module = "commons-io" % "commons-io" % "2.5" +module: sbt.librarymanagement.ModuleID = commons-io:commons-io:2.5 + +scala> lm.retrieve(module, scalaModuleInfo = None, new File("target"), log) +res0: Either[sbt.librarymanagement.UnresolvedWarning,Vector[java.io.File]] = Right(Vector(target/jars/commons-io/commons-io/commons-io-2.5.jar, target/jars/commons-io/commons-io/commons-io-2.5.jar, target/jars/commons-io/commons-io/commons-io-2.5.jar)) ``` diff --git a/build.sbt b/build.sbt index 890d24ff0..9fbe4fa00 100644 --- a/build.sbt +++ b/build.sbt @@ -31,7 +31,7 @@ def commonSettings: Seq[Setting[_]] = Seq( ) lazy val lmRoot = (project in file(".")) - .aggregate(lm) + .aggregate(lmCore, lmIvy) .settings( inThisBuild( Seq( @@ -60,12 +60,12 @@ lazy val lmRoot = (project in file(".")) customCommands ) -lazy val lm = (project in file("librarymanagement")) +lazy val lmCore = (project in file("core")) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .settings( commonSettings, - name := "librarymanagement", - libraryDependencies ++= Seq(ivy, - jsch, + name := "librarymanagement-core", + libraryDependencies ++= Seq(jsch, scalaReflect.value, scalaCompiler.value, launcherInterface, @@ -94,7 +94,20 @@ lazy val lm = (project in file("librarymanagement")) } ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) + +lazy val lmIvy = (project in file("ivy")) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + .dependsOn(lmCore) + .settings( + commonSettings, + name := "librarymanagement-ivy", + libraryDependencies ++= Seq(ivy, scalaTest, scalaCheck), + managedSourceDirectories in Compile += + baseDirectory.value / "src" / "main" / "contraband-scala", + sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", + contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, + scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), + ) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/librarymanagement/NOTICE b/core/NOTICE similarity index 100% rename from librarymanagement/NOTICE rename to core/NOTICE diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala rename to core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala rename to core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Binary.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Caller.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Constant.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Developer.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Full.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Full.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala new file mode 100644 index 000000000..6ef40d2b0 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala @@ -0,0 +1,48 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class GetClassifiersConfiguration private ( + val module: sbt.librarymanagement.GetClassifiersModule, + val excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]], + val updateConfiguration: sbt.librarymanagement.UpdateConfiguration, + val sourceArtifactTypes: Vector[String], + val docArtifactTypes: Vector[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: GetClassifiersConfiguration => (this.module == x.module) && (this.excludes == x.excludes) && (this.updateConfiguration == x.updateConfiguration) && (this.sourceArtifactTypes == x.sourceArtifactTypes) && (this.docArtifactTypes == x.docArtifactTypes) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "GetClassifiersConfiguration".##) + module.##) + excludes.##) + updateConfiguration.##) + sourceArtifactTypes.##) + docArtifactTypes.##) + } + override def toString: String = { + "GetClassifiersConfiguration(" + module + ", " + excludes + ", " + updateConfiguration + ", " + sourceArtifactTypes + ", " + docArtifactTypes + ")" + } + protected[this] def copy(module: sbt.librarymanagement.GetClassifiersModule = module, excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]] = excludes, updateConfiguration: sbt.librarymanagement.UpdateConfiguration = updateConfiguration, sourceArtifactTypes: Vector[String] = sourceArtifactTypes, docArtifactTypes: Vector[String] = docArtifactTypes): GetClassifiersConfiguration = { + new GetClassifiersConfiguration(module, excludes, updateConfiguration, sourceArtifactTypes, docArtifactTypes) + } + def withModule(module: sbt.librarymanagement.GetClassifiersModule): GetClassifiersConfiguration = { + copy(module = module) + } + def withExcludes(excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]]): GetClassifiersConfiguration = { + copy(excludes = excludes) + } + def withUpdateConfiguration(updateConfiguration: sbt.librarymanagement.UpdateConfiguration): GetClassifiersConfiguration = { + copy(updateConfiguration = updateConfiguration) + } + def withSourceArtifactTypes(sourceArtifactTypes: Vector[String]): GetClassifiersConfiguration = { + copy(sourceArtifactTypes = sourceArtifactTypes) + } + def withDocArtifactTypes(docArtifactTypes: Vector[String]): GetClassifiersConfiguration = { + copy(docArtifactTypes = docArtifactTypes) + } +} +object GetClassifiersConfiguration { + + def apply(module: sbt.librarymanagement.GetClassifiersModule, excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]], updateConfiguration: sbt.librarymanagement.UpdateConfiguration, sourceArtifactTypes: Vector[String], docArtifactTypes: Vector[String]): GetClassifiersConfiguration = new GetClassifiersConfiguration(module, excludes, updateConfiguration, sourceArtifactTypes, docArtifactTypes) +} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala new file mode 100644 index 000000000..f93af3a85 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait GetClassifiersConfigurationFormats { self: sbt.librarymanagement.GetClassifiersModuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.UpdateConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val GetClassifiersConfigurationFormat: JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] = new JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val module = unbuilder.readField[sbt.librarymanagement.GetClassifiersModule]("module") + val excludes = unbuilder.readField[Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]]]("excludes") + val updateConfiguration = unbuilder.readField[sbt.librarymanagement.UpdateConfiguration]("updateConfiguration") + val sourceArtifactTypes = unbuilder.readField[Vector[String]]("sourceArtifactTypes") + val docArtifactTypes = unbuilder.readField[Vector[String]]("docArtifactTypes") + unbuilder.endObject() + sbt.librarymanagement.GetClassifiersConfiguration(module, excludes, updateConfiguration, sourceArtifactTypes, docArtifactTypes) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.GetClassifiersConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("module", obj.module) + builder.addField("excludes", obj.excludes) + builder.addField("updateConfiguration", obj.updateConfiguration) + builder.addField("sourceArtifactTypes", obj.sourceArtifactTypes) + builder.addField("docArtifactTypes", obj.docArtifactTypes) + builder.endObject() + } +} +} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala new file mode 100644 index 000000000..22d70c167 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala @@ -0,0 +1,52 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class GetClassifiersModule private ( + val id: sbt.librarymanagement.ModuleID, + val scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], + val dependencies: Vector[sbt.librarymanagement.ModuleID], + val configurations: Vector[sbt.librarymanagement.Configuration], + val classifiers: Vector[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: GetClassifiersModule => (this.id == x.id) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.dependencies == x.dependencies) && (this.configurations == x.configurations) && (this.classifiers == x.classifiers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "GetClassifiersModule".##) + id.##) + scalaModuleInfo.##) + dependencies.##) + configurations.##) + classifiers.##) + } + override def toString: String = { + "GetClassifiersModule(" + id + ", " + scalaModuleInfo + ", " + dependencies + ", " + configurations + ", " + classifiers + ")" + } + protected[this] def copy(id: sbt.librarymanagement.ModuleID = id, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, classifiers: Vector[String] = classifiers): GetClassifiersModule = { + new GetClassifiersModule(id, scalaModuleInfo, dependencies, configurations, classifiers) + } + def withId(id: sbt.librarymanagement.ModuleID): GetClassifiersModule = { + copy(id = id) + } + def withScalaModuleInfo(scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo]): GetClassifiersModule = { + copy(scalaModuleInfo = scalaModuleInfo) + } + def withScalaModuleInfo(scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo): GetClassifiersModule = { + copy(scalaModuleInfo = Option(scalaModuleInfo)) + } + def withDependencies(dependencies: Vector[sbt.librarymanagement.ModuleID]): GetClassifiersModule = { + copy(dependencies = dependencies) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): GetClassifiersModule = { + copy(configurations = configurations) + } + def withClassifiers(classifiers: Vector[String]): GetClassifiersModule = { + copy(classifiers = classifiers) + } +} +object GetClassifiersModule { + + def apply(id: sbt.librarymanagement.ModuleID, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], dependencies: Vector[sbt.librarymanagement.ModuleID], configurations: Vector[sbt.librarymanagement.Configuration], classifiers: Vector[String]): GetClassifiersModule = new GetClassifiersModule(id, scalaModuleInfo, dependencies, configurations, classifiers) + def apply(id: sbt.librarymanagement.ModuleID, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], configurations: Vector[sbt.librarymanagement.Configuration], classifiers: Vector[String]): GetClassifiersModule = new GetClassifiersModule(id, Option(scalaModuleInfo), dependencies, configurations, classifiers) +} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala new file mode 100644 index 000000000..8bedbe9a3 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala @@ -0,0 +1,35 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait GetClassifiersModuleFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val GetClassifiersModuleFormat: JsonFormat[sbt.librarymanagement.GetClassifiersModule] = new JsonFormat[sbt.librarymanagement.GetClassifiersModule] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersModule = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val id = unbuilder.readField[sbt.librarymanagement.ModuleID]("id") + val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") + val dependencies = unbuilder.readField[Vector[sbt.librarymanagement.ModuleID]]("dependencies") + val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") + val classifiers = unbuilder.readField[Vector[String]]("classifiers") + unbuilder.endObject() + sbt.librarymanagement.GetClassifiersModule(id, scalaModuleInfo, dependencies, configurations, classifiers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.GetClassifiersModule, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("id", obj.id) + builder.addField("scalaModuleInfo", obj.scalaModuleInfo) + builder.addField("dependencies", obj.dependencies) + builder.addField("configurations", obj.configurations) + builder.addField("classifiers", obj.classifiers) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala new file mode 100644 index 000000000..1f2c5b652 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -0,0 +1,49 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class IvyFileConfiguration private ( + validate: Boolean, + scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], + val file: java.io.File, + val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, scalaModuleInfo) with Serializable { + + private def this(file: java.io.File, autoScalaTools: Boolean) = this(false, None, file, autoScalaTools) + + override def equals(o: Any): Boolean = o match { + case x: IvyFileConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "IvyFileConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) + } + override def toString: String = { + "IvyFileConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" + } + protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): IvyFileConfiguration = { + new IvyFileConfiguration(validate, scalaModuleInfo, file, autoScalaTools) + } + def withValidate(validate: Boolean): IvyFileConfiguration = { + copy(validate = validate) + } + def withScalaModuleInfo(scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo]): IvyFileConfiguration = { + copy(scalaModuleInfo = scalaModuleInfo) + } + def withScalaModuleInfo(scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo): IvyFileConfiguration = { + copy(scalaModuleInfo = Option(scalaModuleInfo)) + } + def withFile(file: java.io.File): IvyFileConfiguration = { + copy(file = file) + } + def withAutoScalaTools(autoScalaTools: Boolean): IvyFileConfiguration = { + copy(autoScalaTools = autoScalaTools) + } +} +object IvyFileConfiguration { + + def apply(file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(false, None, file, autoScalaTools) + def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, scalaModuleInfo, file, autoScalaTools) + def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, Option(scalaModuleInfo), file, autoScalaTools) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala similarity index 79% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala index c675f4427..1747cef64 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala @@ -5,18 +5,18 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait IvyFileConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol => +trait IvyFileConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => implicit lazy val IvyFileConfigurationFormat: JsonFormat[sbt.librarymanagement.IvyFileConfiguration] = new JsonFormat[sbt.librarymanagement.IvyFileConfiguration] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyFileConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val validate = unbuilder.readField[Boolean]("validate") - val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val file = unbuilder.readField[java.io.File]("file") val autoScalaTools = unbuilder.readField[Boolean]("autoScalaTools") unbuilder.endObject() - sbt.librarymanagement.IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) + sbt.librarymanagement.IvyFileConfiguration(validate, scalaModuleInfo, file, autoScalaTools) case None => deserializationError("Expected JsObject but found None") } @@ -24,7 +24,7 @@ implicit lazy val IvyFileConfigurationFormat: JsonFormat[sbt.librarymanagement.I override def write[J](obj: sbt.librarymanagement.IvyFileConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("validate", obj.validate) - builder.addField("ivyScala", obj.ivyScala) + builder.addField("scalaModuleInfo", obj.scalaModuleInfo) builder.addField("file", obj.file) builder.addField("autoScalaTools", obj.autoScalaTools) builder.endObject() diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala similarity index 82% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 08e493b48..493571edb 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -6,9 +6,13 @@ package sbt.librarymanagement trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ConfigRefFormats + with sbt.librarymanagement.RetrieveConfigurationFormats + with sbt.librarymanagement.UpdateLoggingFormats + with sbt.internal.librarymanagement.formats.LogicalClockFormats + with sbt.librarymanagement.ArtifactTypeFilterFormats + with sbt.librarymanagement.UpdateConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.ArtifactFormats - with sbt.librarymanagement.ArtifactTypeFilterFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats @@ -17,6 +21,11 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.ModuleIDFormats + with sbt.librarymanagement.ConfigurationFormats + with sbt.librarymanagement.ScalaModuleInfoFormats + with sbt.librarymanagement.GetClassifiersModuleFormats + with sbt.librarymanagement.GetClassifiersConfigurationFormats + with sbt.librarymanagement.PublishConfigurationFormats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats @@ -24,8 +33,6 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.DeveloperFormats with sbt.librarymanagement.FileConfigurationFormats - with sbt.librarymanagement.ConfigurationFormats - with sbt.librarymanagement.IvyScalaFormats with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats @@ -45,23 +52,13 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat - with sbt.librarymanagement.InlineConfigurationFormats + with sbt.librarymanagement.ModuleDescriptorConfigurationFormats with sbt.librarymanagement.ModuleSettingsFormats with sbt.librarymanagement.MavenRepositoryFormats with sbt.librarymanagement.PatternsBasedRepositoryFormats with sbt.librarymanagement.SshBasedRepositoryFormats - with sbt.librarymanagement.RetrieveConfigurationFormats - with sbt.librarymanagement.UpdateLoggingFormats - with sbt.librarymanagement.UpdateConfigurationFormats with sbt.librarymanagement.UpdateStatsFormats with sbt.librarymanagement.UpdateReportFormats with sbt.librarymanagement.ConfigurationReportLiteFormats - with sbt.internal.librarymanagement.formats.GlobalLockFormat - with sbt.internal.librarymanagement.formats.LoggerFormat - with sbt.internal.librarymanagement.formats.UpdateOptionsFormat - with sbt.librarymanagement.IvyPathsFormats - with sbt.librarymanagement.InlineIvyConfigurationFormats - with sbt.librarymanagement.ExternalIvyConfigurationFormats - with sbt.librarymanagement.IvyConfigurationFormats with sbt.librarymanagement.UpdateReportLiteFormats object LibraryManagementCodec extends LibraryManagementCodec \ No newline at end of file diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala new file mode 100644 index 000000000..3c1213b4c --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -0,0 +1,80 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class ModuleDescriptorConfiguration private ( + validate: Boolean, + scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], + val module: sbt.librarymanagement.ModuleID, + val moduleInfo: sbt.librarymanagement.ModuleInfo, + val dependencies: Vector[sbt.librarymanagement.ModuleID], + val overrides: Vector[sbt.librarymanagement.ModuleID], + val excludes: Vector[sbt.librarymanagement.InclExclRule], + val ivyXML: scala.xml.NodeSeq, + val configurations: Vector[sbt.librarymanagement.Configuration], + val defaultConfiguration: Option[sbt.librarymanagement.Configuration], + val conflictManager: sbt.librarymanagement.ConflictManager) extends sbt.librarymanagement.ModuleSettings(validate, scalaModuleInfo) with Serializable { + + private def this(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo) = this(false, None, module, moduleInfo, Vector.empty, Vector.empty, Vector.empty, scala.xml.NodeSeq.Empty, sbt.librarymanagement.Configurations.default, Option(sbt.librarymanagement.Configurations.Compile), sbt.librarymanagement.ConflictManager.default) + + override def equals(o: Any): Boolean = o match { + case x: ModuleDescriptorConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.module == x.module) && (this.moduleInfo == x.moduleInfo) && (this.dependencies == x.dependencies) && (this.overrides == x.overrides) && (this.excludes == x.excludes) && (this.ivyXML == x.ivyXML) && (this.configurations == x.configurations) && (this.defaultConfiguration == x.defaultConfiguration) && (this.conflictManager == x.conflictManager) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleDescriptorConfiguration".##) + validate.##) + scalaModuleInfo.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) + } + override def toString: String = { + "ModuleDescriptorConfiguration(" + validate + ", " + scalaModuleInfo + ", " + module + ", " + moduleInfo + ", " + dependencies + ", " + overrides + ", " + excludes + ", " + ivyXML + ", " + configurations + ", " + defaultConfiguration + ", " + conflictManager + ")" + } + protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, module: sbt.librarymanagement.ModuleID = module, moduleInfo: sbt.librarymanagement.ModuleInfo = moduleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, overrides: Vector[sbt.librarymanagement.ModuleID] = overrides, excludes: Vector[sbt.librarymanagement.InclExclRule] = excludes, ivyXML: scala.xml.NodeSeq = ivyXML, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, defaultConfiguration: Option[sbt.librarymanagement.Configuration] = defaultConfiguration, conflictManager: sbt.librarymanagement.ConflictManager = conflictManager): ModuleDescriptorConfiguration = { + new ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + } + def withValidate(validate: Boolean): ModuleDescriptorConfiguration = { + copy(validate = validate) + } + def withScalaModuleInfo(scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo]): ModuleDescriptorConfiguration = { + copy(scalaModuleInfo = scalaModuleInfo) + } + def withScalaModuleInfo(scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo): ModuleDescriptorConfiguration = { + copy(scalaModuleInfo = Option(scalaModuleInfo)) + } + def withModule(module: sbt.librarymanagement.ModuleID): ModuleDescriptorConfiguration = { + copy(module = module) + } + def withModuleInfo(moduleInfo: sbt.librarymanagement.ModuleInfo): ModuleDescriptorConfiguration = { + copy(moduleInfo = moduleInfo) + } + def withDependencies(dependencies: Vector[sbt.librarymanagement.ModuleID]): ModuleDescriptorConfiguration = { + copy(dependencies = dependencies) + } + def withOverrides(overrides: Vector[sbt.librarymanagement.ModuleID]): ModuleDescriptorConfiguration = { + copy(overrides = overrides) + } + def withExcludes(excludes: Vector[sbt.librarymanagement.InclExclRule]): ModuleDescriptorConfiguration = { + copy(excludes = excludes) + } + def withIvyXML(ivyXML: scala.xml.NodeSeq): ModuleDescriptorConfiguration = { + copy(ivyXML = ivyXML) + } + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): ModuleDescriptorConfiguration = { + copy(configurations = configurations) + } + def withDefaultConfiguration(defaultConfiguration: Option[sbt.librarymanagement.Configuration]): ModuleDescriptorConfiguration = { + copy(defaultConfiguration = defaultConfiguration) + } + def withDefaultConfiguration(defaultConfiguration: sbt.librarymanagement.Configuration): ModuleDescriptorConfiguration = { + copy(defaultConfiguration = Option(defaultConfiguration)) + } + def withConflictManager(conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = { + copy(conflictManager = conflictManager) + } +} +object ModuleDescriptorConfiguration extends sbt.internal.librarymanagement.InlineConfigurationFunctions { + + def apply(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(false, None, module, moduleInfo, Vector.empty, Vector.empty, Vector.empty, scala.xml.NodeSeq.Empty, sbt.librarymanagement.Configurations.default, Option(sbt.librarymanagement.Configurations.Compile), sbt.librarymanagement.ConflictManager.default) + def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Vector[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Vector[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: sbt.librarymanagement.Configuration, conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(validate, Option(scalaModuleInfo), module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, Option(defaultConfiguration), conflictManager) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala similarity index 60% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala index 13cc67247..2062ac0f0 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala @@ -5,33 +5,33 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InlineConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val InlineConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.InlineConfiguration] = new JsonFormat[sbt.internal.librarymanagement.InlineConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.InlineConfiguration = { +trait ModuleDescriptorConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ModuleDescriptorConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleDescriptorConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val validate = unbuilder.readField[Boolean]("validate") - val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val module = unbuilder.readField[sbt.librarymanagement.ModuleID]("module") val moduleInfo = unbuilder.readField[sbt.librarymanagement.ModuleInfo]("moduleInfo") val dependencies = unbuilder.readField[Vector[sbt.librarymanagement.ModuleID]]("dependencies") - val overrides = unbuilder.readField[Set[sbt.librarymanagement.ModuleID]]("overrides") + val overrides = unbuilder.readField[Vector[sbt.librarymanagement.ModuleID]]("overrides") val excludes = unbuilder.readField[Vector[sbt.librarymanagement.InclExclRule]]("excludes") val ivyXML = unbuilder.readField[scala.xml.NodeSeq]("ivyXML") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") val defaultConfiguration = unbuilder.readField[Option[sbt.librarymanagement.Configuration]]("defaultConfiguration") val conflictManager = unbuilder.readField[sbt.librarymanagement.ConflictManager]("conflictManager") unbuilder.endObject() - sbt.internal.librarymanagement.InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) + sbt.librarymanagement.ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.internal.librarymanagement.InlineConfiguration, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.ModuleDescriptorConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("validate", obj.validate) - builder.addField("ivyScala", obj.ivyScala) + builder.addField("scalaModuleInfo", obj.scalaModuleInfo) builder.addField("module", obj.module) builder.addField("moduleInfo", obj.moduleInfo) builder.addField("dependencies", obj.dependencies) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala similarity index 67% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala index e70a3b1f7..95f9e8be7 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala @@ -6,20 +6,20 @@ package sbt.librarymanagement abstract class ModuleSettings( val validate: Boolean, - val ivyScala: Option[sbt.librarymanagement.IvyScala]) extends Serializable { - + val scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo]) extends Serializable { + def this() = this(false, None) override def equals(o: Any): Boolean = o match { - case x: ModuleSettings => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) + case x: ModuleSettings => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "ModuleSettings".##) + validate.##) + ivyScala.##) + 37 * (37 * (37 * (17 + "ModuleSettings".##) + validate.##) + scalaModuleInfo.##) } override def toString: String = { - "ModuleSettings(" + validate + ", " + ivyScala + ")" + "ModuleSettings(" + validate + ", " + scalaModuleInfo + ")" } } object ModuleSettings { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala new file mode 100644 index 000000000..09a7a0774 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement + +import _root_.sjsonnew.JsonFormat +trait ModuleSettingsFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.ModuleDescriptorConfigurationFormats => +implicit lazy val ModuleSettingsFormat: JsonFormat[sbt.librarymanagement.ModuleSettings] = flatUnionFormat3[sbt.librarymanagement.ModuleSettings, sbt.librarymanagement.IvyFileConfiguration, sbt.librarymanagement.PomConfiguration, sbt.librarymanagement.ModuleDescriptorConfiguration]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patch.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala new file mode 100644 index 000000000..92b367e95 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -0,0 +1,49 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class PomConfiguration private ( + validate: Boolean, + scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], + val file: java.io.File, + val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, scalaModuleInfo) with Serializable { + + private def this(file: java.io.File, autoScalaTools: Boolean) = this(false, None, file, autoScalaTools) + + override def equals(o: Any): Boolean = o match { + case x: PomConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "PomConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) + } + override def toString: String = { + "PomConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" + } + protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): PomConfiguration = { + new PomConfiguration(validate, scalaModuleInfo, file, autoScalaTools) + } + def withValidate(validate: Boolean): PomConfiguration = { + copy(validate = validate) + } + def withScalaModuleInfo(scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo]): PomConfiguration = { + copy(scalaModuleInfo = scalaModuleInfo) + } + def withScalaModuleInfo(scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo): PomConfiguration = { + copy(scalaModuleInfo = Option(scalaModuleInfo)) + } + def withFile(file: java.io.File): PomConfiguration = { + copy(file = file) + } + def withAutoScalaTools(autoScalaTools: Boolean): PomConfiguration = { + copy(autoScalaTools = autoScalaTools) + } +} +object PomConfiguration { + + def apply(file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(false, None, file, autoScalaTools) + def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, scalaModuleInfo, file, autoScalaTools) + def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, Option(scalaModuleInfo), file, autoScalaTools) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala similarity index 75% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala index e8a2a787d..44c8bb008 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala @@ -5,18 +5,18 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PomConfigurationFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol => +trait PomConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PomConfigurationFormat: JsonFormat[sbt.librarymanagement.PomConfiguration] = new JsonFormat[sbt.librarymanagement.PomConfiguration] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PomConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val validate = unbuilder.readField[Boolean]("validate") - val ivyScala = unbuilder.readField[Option[sbt.librarymanagement.IvyScala]]("ivyScala") + val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val file = unbuilder.readField[java.io.File]("file") val autoScalaTools = unbuilder.readField[Boolean]("autoScalaTools") unbuilder.endObject() - sbt.librarymanagement.PomConfiguration(validate, ivyScala, file, autoScalaTools) + sbt.librarymanagement.PomConfiguration(validate, scalaModuleInfo, file, autoScalaTools) case None => deserializationError("Expected JsObject but found None") } @@ -24,7 +24,7 @@ implicit lazy val PomConfigurationFormat: JsonFormat[sbt.librarymanagement.PomCo override def write[J](obj: sbt.librarymanagement.PomConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("validate", obj.validate) - builder.addField("ivyScala", obj.ivyScala) + builder.addField("scalaModuleInfo", obj.scalaModuleInfo) builder.addField("file", obj.file) builder.addField("autoScalaTools", obj.autoScalaTools) builder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala new file mode 100644 index 000000000..8c6481d07 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -0,0 +1,81 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class PublishConfiguration private ( + val publishMavenStyle: Boolean, + val deliverIvyPattern: Option[String], + val status: Option[String], + val configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]], + val resolverName: Option[String], + val artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], + val checksums: scala.Vector[String], + val logging: Option[sbt.librarymanagement.UpdateLogging], + val overwrite: Boolean) extends Serializable { + + private def this() = this(true, None, None, None, None, Vector(), Vector("sha1", "md5"), None, false) + + override def equals(o: Any): Boolean = o match { + case x: PublishConfiguration => (this.publishMavenStyle == x.publishMavenStyle) && (this.deliverIvyPattern == x.deliverIvyPattern) && (this.status == x.status) && (this.configurations == x.configurations) && (this.resolverName == x.resolverName) && (this.artifacts == x.artifacts) && (this.checksums == x.checksums) && (this.logging == x.logging) && (this.overwrite == x.overwrite) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "PublishConfiguration".##) + publishMavenStyle.##) + deliverIvyPattern.##) + status.##) + configurations.##) + resolverName.##) + artifacts.##) + checksums.##) + logging.##) + overwrite.##) + } + override def toString: String = { + "PublishConfiguration(" + publishMavenStyle + ", " + deliverIvyPattern + ", " + status + ", " + configurations + ", " + resolverName + ", " + artifacts + ", " + checksums + ", " + logging + ", " + overwrite + ")" + } + protected[this] def copy(publishMavenStyle: Boolean = publishMavenStyle, deliverIvyPattern: Option[String] = deliverIvyPattern, status: Option[String] = status, configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurations, resolverName: Option[String] = resolverName, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, checksums: scala.Vector[String] = checksums, logging: Option[sbt.librarymanagement.UpdateLogging] = logging, overwrite: Boolean = overwrite): PublishConfiguration = { + new PublishConfiguration(publishMavenStyle, deliverIvyPattern, status, configurations, resolverName, artifacts, checksums, logging, overwrite) + } + def withPublishMavenStyle(publishMavenStyle: Boolean): PublishConfiguration = { + copy(publishMavenStyle = publishMavenStyle) + } + def withDeliverIvyPattern(deliverIvyPattern: Option[String]): PublishConfiguration = { + copy(deliverIvyPattern = deliverIvyPattern) + } + def withDeliverIvyPattern(deliverIvyPattern: String): PublishConfiguration = { + copy(deliverIvyPattern = Option(deliverIvyPattern)) + } + def withStatus(status: Option[String]): PublishConfiguration = { + copy(status = status) + } + def withStatus(status: String): PublishConfiguration = { + copy(status = Option(status)) + } + def withConfigurations(configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]]): PublishConfiguration = { + copy(configurations = configurations) + } + def withConfigurations(configurations: scala.Vector[sbt.librarymanagement.ConfigRef]): PublishConfiguration = { + copy(configurations = Option(configurations)) + } + def withResolverName(resolverName: Option[String]): PublishConfiguration = { + copy(resolverName = resolverName) + } + def withResolverName(resolverName: String): PublishConfiguration = { + copy(resolverName = Option(resolverName)) + } + def withArtifacts(artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]]): PublishConfiguration = { + copy(artifacts = artifacts) + } + def withChecksums(checksums: scala.Vector[String]): PublishConfiguration = { + copy(checksums = checksums) + } + def withLogging(logging: Option[sbt.librarymanagement.UpdateLogging]): PublishConfiguration = { + copy(logging = logging) + } + def withLogging(logging: sbt.librarymanagement.UpdateLogging): PublishConfiguration = { + copy(logging = Option(logging)) + } + def withOverwrite(overwrite: Boolean): PublishConfiguration = { + copy(overwrite = overwrite) + } +} +object PublishConfiguration { + + def apply(): PublishConfiguration = new PublishConfiguration(true, None, None, None, None, Vector(), Vector("sha1", "md5"), None, false) + def apply(publishMavenStyle: Boolean, deliverIvyPattern: Option[String], status: Option[String], configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]], resolverName: Option[String], artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], checksums: scala.Vector[String], logging: Option[sbt.librarymanagement.UpdateLogging], overwrite: Boolean): PublishConfiguration = new PublishConfiguration(publishMavenStyle, deliverIvyPattern, status, configurations, resolverName, artifacts, checksums, logging, overwrite) + def apply(publishMavenStyle: Boolean, deliverIvyPattern: String, status: String, configurations: scala.Vector[sbt.librarymanagement.ConfigRef], resolverName: String, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], checksums: scala.Vector[String], logging: sbt.librarymanagement.UpdateLogging, overwrite: Boolean): PublishConfiguration = new PublishConfiguration(publishMavenStyle, Option(deliverIvyPattern), Option(status), Option(configurations), Option(resolverName), artifacts, checksums, Option(logging), overwrite) +} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala new file mode 100644 index 000000000..14990899e --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala @@ -0,0 +1,43 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.UpdateLoggingFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val PublishConfigurationFormat: JsonFormat[sbt.librarymanagement.PublishConfiguration] = new JsonFormat[sbt.librarymanagement.PublishConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val publishMavenStyle = unbuilder.readField[Boolean]("publishMavenStyle") + val deliverIvyPattern = unbuilder.readField[Option[String]]("deliverIvyPattern") + val status = unbuilder.readField[Option[String]]("status") + val configurations = unbuilder.readField[Option[scala.Vector[sbt.librarymanagement.ConfigRef]]]("configurations") + val resolverName = unbuilder.readField[Option[String]]("resolverName") + val artifacts = unbuilder.readField[Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]]]("artifacts") + val checksums = unbuilder.readField[scala.Vector[String]]("checksums") + val logging = unbuilder.readField[Option[sbt.librarymanagement.UpdateLogging]]("logging") + val overwrite = unbuilder.readField[Boolean]("overwrite") + unbuilder.endObject() + sbt.librarymanagement.PublishConfiguration(publishMavenStyle, deliverIvyPattern, status, configurations, resolverName, artifacts, checksums, logging, overwrite) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.PublishConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("publishMavenStyle", obj.publishMavenStyle) + builder.addField("deliverIvyPattern", obj.deliverIvyPattern) + builder.addField("status", obj.status) + builder.addField("configurations", obj.configurations) + builder.addField("resolverName", obj.resolverName) + builder.addField("artifacts", obj.artifacts) + builder.addField("checksums", obj.checksums) + builder.addField("logging", obj.logging) + builder.addField("overwrite", obj.overwrite) + builder.endObject() + } +} +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala new file mode 100644 index 000000000..dbd6c9312 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -0,0 +1,58 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class RetrieveConfiguration private ( + val retrieveDirectory: Option[java.io.File], + val outputPattern: Option[String], + val sync: Boolean, + val configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]]) extends Serializable { + + private def this() = this(None, None, false, None) + private def this(retrieveDirectory: Option[java.io.File], outputPattern: Option[String]) = this(retrieveDirectory, outputPattern, false, None) + + override def equals(o: Any): Boolean = o match { + case x: RetrieveConfiguration => (this.retrieveDirectory == x.retrieveDirectory) && (this.outputPattern == x.outputPattern) && (this.sync == x.sync) && (this.configurationsToRetrieve == x.configurationsToRetrieve) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (17 + "RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) + } + override def toString: String = { + "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" + } + protected[this] def copy(retrieveDirectory: Option[java.io.File] = retrieveDirectory, outputPattern: Option[String] = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurationsToRetrieve): RetrieveConfiguration = { + new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + } + def withRetrieveDirectory(retrieveDirectory: Option[java.io.File]): RetrieveConfiguration = { + copy(retrieveDirectory = retrieveDirectory) + } + def withRetrieveDirectory(retrieveDirectory: java.io.File): RetrieveConfiguration = { + copy(retrieveDirectory = Option(retrieveDirectory)) + } + def withOutputPattern(outputPattern: Option[String]): RetrieveConfiguration = { + copy(outputPattern = outputPattern) + } + def withOutputPattern(outputPattern: String): RetrieveConfiguration = { + copy(outputPattern = Option(outputPattern)) + } + def withSync(sync: Boolean): RetrieveConfiguration = { + copy(sync = sync) + } + def withConfigurationsToRetrieve(configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = { + copy(configurationsToRetrieve = configurationsToRetrieve) + } + def withConfigurationsToRetrieve(configurationsToRetrieve: scala.Vector[sbt.librarymanagement.ConfigRef]): RetrieveConfiguration = { + copy(configurationsToRetrieve = Option(configurationsToRetrieve)) + } +} +object RetrieveConfiguration { + + def apply(): RetrieveConfiguration = new RetrieveConfiguration(None, None, false, None) + def apply(retrieveDirectory: Option[java.io.File], outputPattern: Option[String]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, false, None) + def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(Option(retrieveDirectory), Option(outputPattern), false, None) + def apply(retrieveDirectory: Option[java.io.File], outputPattern: Option[String], sync: Boolean, configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: scala.Vector[sbt.librarymanagement.ConfigRef]): RetrieveConfiguration = new RetrieveConfiguration(Option(retrieveDirectory), Option(outputPattern), sync, Option(configurationsToRetrieve)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala similarity index 59% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala index 158e305cd..bd12840f7 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala @@ -6,22 +6,22 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait RetrieveConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] = new JsonFormat[sbt.internal.librarymanagement.RetrieveConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.RetrieveConfiguration = { +implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.librarymanagement.RetrieveConfiguration] = new JsonFormat[sbt.librarymanagement.RetrieveConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.RetrieveConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) - val retrieveDirectory = unbuilder.readField[java.io.File]("retrieveDirectory") - val outputPattern = unbuilder.readField[String]("outputPattern") + val retrieveDirectory = unbuilder.readField[Option[java.io.File]]("retrieveDirectory") + val outputPattern = unbuilder.readField[Option[String]]("outputPattern") val sync = unbuilder.readField[Boolean]("sync") - val configurationsToRetrieve = unbuilder.readField[Option[Set[sbt.librarymanagement.ConfigRef]]]("configurationsToRetrieve") + val configurationsToRetrieve = unbuilder.readField[Option[scala.Vector[sbt.librarymanagement.ConfigRef]]]("configurationsToRetrieve") unbuilder.endObject() - sbt.internal.librarymanagement.RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) + sbt.librarymanagement.RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.internal.librarymanagement.RetrieveConfiguration, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.RetrieveConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("retrieveDirectory", obj.retrieveDirectory) builder.addField("outputPattern", obj.outputPattern) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala similarity index 54% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index 4bbde0dee..f3867aecc 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScala.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -4,7 +4,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement -final class IvyScala private ( +final class ScalaModuleInfo private ( val scalaFullVersion: String, val scalaBinaryVersion: String, val configurations: Vector[sbt.librarymanagement.Configuration], @@ -17,45 +17,45 @@ final class IvyScala private ( private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) override def equals(o: Any): Boolean = o match { - case x: IvyScala => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) + case x: ScalaModuleInfo => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "IvyScala".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) } override def toString: String = { - "IvyScala(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" + "ScalaModuleInfo(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" } - protected[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): IvyScala = { - new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + protected[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): ScalaModuleInfo = { + new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) } - def withScalaFullVersion(scalaFullVersion: String): IvyScala = { + def withScalaFullVersion(scalaFullVersion: String): ScalaModuleInfo = { copy(scalaFullVersion = scalaFullVersion) } - def withScalaBinaryVersion(scalaBinaryVersion: String): IvyScala = { + def withScalaBinaryVersion(scalaBinaryVersion: String): ScalaModuleInfo = { copy(scalaBinaryVersion = scalaBinaryVersion) } - def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): IvyScala = { + def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): ScalaModuleInfo = { copy(configurations = configurations) } - def withCheckExplicit(checkExplicit: Boolean): IvyScala = { + def withCheckExplicit(checkExplicit: Boolean): ScalaModuleInfo = { copy(checkExplicit = checkExplicit) } - def withFilterImplicit(filterImplicit: Boolean): IvyScala = { + def withFilterImplicit(filterImplicit: Boolean): ScalaModuleInfo = { copy(filterImplicit = filterImplicit) } - def withOverrideScalaVersion(overrideScalaVersion: Boolean): IvyScala = { + def withOverrideScalaVersion(overrideScalaVersion: Boolean): ScalaModuleInfo = { copy(overrideScalaVersion = overrideScalaVersion) } - def withScalaOrganization(scalaOrganization: String): IvyScala = { + def withScalaOrganization(scalaOrganization: String): ScalaModuleInfo = { copy(scalaOrganization = scalaOrganization) } - def withScalaArtifacts(scalaArtifacts: scala.Vector[String]): IvyScala = { + def withScalaArtifacts(scalaArtifacts: scala.Vector[String]): ScalaModuleInfo = { copy(scalaArtifacts = scalaArtifacts) } } -object IvyScala extends sbt.librarymanagement.IvyScalaFunctions { +object ScalaModuleInfo { - def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): IvyScala = new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) - def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]): IvyScala = new IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) } diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala similarity index 74% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala index b12207105..c3996cbec 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyScalaFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala @@ -5,9 +5,9 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait IvyScalaFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val IvyScalaFormat: JsonFormat[sbt.librarymanagement.IvyScala] = new JsonFormat[sbt.librarymanagement.IvyScala] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyScala = { +trait ScalaModuleInfoFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ScalaModuleInfoFormat: JsonFormat[sbt.librarymanagement.ScalaModuleInfo] = new JsonFormat[sbt.librarymanagement.ScalaModuleInfo] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScalaModuleInfo = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -20,12 +20,12 @@ implicit lazy val IvyScalaFormat: JsonFormat[sbt.librarymanagement.IvyScala] = n val scalaOrganization = unbuilder.readField[String]("scalaOrganization") val scalaArtifacts = unbuilder.readField[scala.Vector[String]]("scalaArtifacts") unbuilder.endObject() - sbt.librarymanagement.IvyScala(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + sbt.librarymanagement.ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.librarymanagement.IvyScala, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.ScalaModuleInfo, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("scalaFullVersion", obj.scalaFullVersion) builder.addField("scalaBinaryVersion", obj.scalaBinaryVersion) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala new file mode 100644 index 000000000..234d826ad --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -0,0 +1,82 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class UpdateConfiguration private ( + /** + * If set to some RetrieveConfiguration, this enables retrieving dependencies to the specified directory. + * Otherwise, dependencies are used directly from the cache. + */ + val retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration], + /** + * If set to true, it ignores when artifacts are missing. + * This setting could be uses when retrieving source/javadocs jars opportunistically. + */ + val missingOk: Boolean, + /** Logging setting used specifially for library management. */ + val logging: sbt.librarymanagement.UpdateLogging, + /** The clock that may be used for caching. */ + val logicalClock: sbt.librarymanagement.LogicalClock, + /** The base directory that may be used to store metadata. */ + val metadataDirectory: Option[java.io.File], + val artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter], + val offline: Boolean, + val frozen: Boolean) extends Serializable { + + private def this() = this(None, false, sbt.librarymanagement.UpdateLogging.Default, sbt.librarymanagement.LogicalClock.unknown, None, None, false, false) + + override def equals(o: Any): Boolean = o match { + case x: UpdateConfiguration => (this.retrieveManaged == x.retrieveManaged) && (this.missingOk == x.missingOk) && (this.logging == x.logging) && (this.logicalClock == x.logicalClock) && (this.metadataDirectory == x.metadataDirectory) && (this.artifactFilter == x.artifactFilter) && (this.offline == x.offline) && (this.frozen == x.frozen) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "UpdateConfiguration".##) + retrieveManaged.##) + missingOk.##) + logging.##) + logicalClock.##) + metadataDirectory.##) + artifactFilter.##) + offline.##) + frozen.##) + } + override def toString: String = { + "UpdateConfiguration(" + retrieveManaged + ", " + missingOk + ", " + logging + ", " + logicalClock + ", " + metadataDirectory + ", " + artifactFilter + ", " + offline + ", " + frozen + ")" + } + protected[this] def copy(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration] = retrieveManaged, missingOk: Boolean = missingOk, logging: sbt.librarymanagement.UpdateLogging = logging, logicalClock: sbt.librarymanagement.LogicalClock = logicalClock, metadataDirectory: Option[java.io.File] = metadataDirectory, artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter] = artifactFilter, offline: Boolean = offline, frozen: Boolean = frozen): UpdateConfiguration = { + new UpdateConfiguration(retrieveManaged, missingOk, logging, logicalClock, metadataDirectory, artifactFilter, offline, frozen) + } + def withRetrieveManaged(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration]): UpdateConfiguration = { + copy(retrieveManaged = retrieveManaged) + } + def withRetrieveManaged(retrieveManaged: sbt.librarymanagement.RetrieveConfiguration): UpdateConfiguration = { + copy(retrieveManaged = Option(retrieveManaged)) + } + def withMissingOk(missingOk: Boolean): UpdateConfiguration = { + copy(missingOk = missingOk) + } + def withLogging(logging: sbt.librarymanagement.UpdateLogging): UpdateConfiguration = { + copy(logging = logging) + } + def withLogicalClock(logicalClock: sbt.librarymanagement.LogicalClock): UpdateConfiguration = { + copy(logicalClock = logicalClock) + } + def withMetadataDirectory(metadataDirectory: Option[java.io.File]): UpdateConfiguration = { + copy(metadataDirectory = metadataDirectory) + } + def withMetadataDirectory(metadataDirectory: java.io.File): UpdateConfiguration = { + copy(metadataDirectory = Option(metadataDirectory)) + } + def withArtifactFilter(artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter]): UpdateConfiguration = { + copy(artifactFilter = artifactFilter) + } + def withArtifactFilter(artifactFilter: sbt.librarymanagement.ArtifactTypeFilter): UpdateConfiguration = { + copy(artifactFilter = Option(artifactFilter)) + } + def withOffline(offline: Boolean): UpdateConfiguration = { + copy(offline = offline) + } + def withFrozen(frozen: Boolean): UpdateConfiguration = { + copy(frozen = frozen) + } +} +object UpdateConfiguration { + + def apply(): UpdateConfiguration = new UpdateConfiguration(None, false, sbt.librarymanagement.UpdateLogging.Default, sbt.librarymanagement.LogicalClock.unknown, None, None, false, false) + def apply(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration], missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, logicalClock: sbt.librarymanagement.LogicalClock, metadataDirectory: Option[java.io.File], artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter], offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(retrieveManaged, missingOk, logging, logicalClock, metadataDirectory, artifactFilter, offline, frozen) + def apply(retrieveManaged: sbt.librarymanagement.RetrieveConfiguration, missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, logicalClock: sbt.librarymanagement.LogicalClock, metadataDirectory: java.io.File, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(Option(retrieveManaged), missingOk, logging, logicalClock, Option(metadataDirectory), Option(artifactFilter), offline, frozen) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala similarity index 63% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala index fe2d47956..bf14c2e99 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala @@ -5,29 +5,33 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.librarymanagement.ArtifactTypeFilterFormats with sjsonnew.BasicJsonProtocol => +trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats with sbt.librarymanagement.ArtifactTypeFilterFormats with sjsonnew.BasicJsonProtocol => implicit lazy val UpdateConfigurationFormat: JsonFormat[sbt.librarymanagement.UpdateConfiguration] = new JsonFormat[sbt.librarymanagement.UpdateConfiguration] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) - val retrieve = unbuilder.readField[Option[sbt.internal.librarymanagement.RetrieveConfiguration]]("retrieve") + val retrieveManaged = unbuilder.readField[Option[sbt.librarymanagement.RetrieveConfiguration]]("retrieveManaged") val missingOk = unbuilder.readField[Boolean]("missingOk") val logging = unbuilder.readField[sbt.librarymanagement.UpdateLogging]("logging") - val artifactFilter = unbuilder.readField[sbt.librarymanagement.ArtifactTypeFilter]("artifactFilter") + val logicalClock = unbuilder.readField[sbt.librarymanagement.LogicalClock]("logicalClock") + val metadataDirectory = unbuilder.readField[Option[java.io.File]]("metadataDirectory") + val artifactFilter = unbuilder.readField[Option[sbt.librarymanagement.ArtifactTypeFilter]]("artifactFilter") val offline = unbuilder.readField[Boolean]("offline") val frozen = unbuilder.readField[Boolean]("frozen") unbuilder.endObject() - sbt.librarymanagement.UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) + sbt.librarymanagement.UpdateConfiguration(retrieveManaged, missingOk, logging, logicalClock, metadataDirectory, artifactFilter, offline, frozen) case None => deserializationError("Expected JsObject but found None") } } override def write[J](obj: sbt.librarymanagement.UpdateConfiguration, builder: Builder[J]): Unit = { builder.beginObject() - builder.addField("retrieve", obj.retrieve) + builder.addField("retrieveManaged", obj.retrieveManaged) builder.addField("missingOk", obj.missingOk) builder.addField("logging", obj.logging) + builder.addField("logicalClock", obj.logicalClock) + builder.addField("metadataDirectory", obj.metadataDirectory) builder.addField("artifactFilter", obj.artifactFilter) builder.addField("offline", obj.offline) builder.addField("frozen", obj.frozen) diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala similarity index 100% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala rename to core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala diff --git a/librarymanagement/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json similarity index 84% rename from librarymanagement/src/main/contraband/librarymanagement.json rename to core/src/main/contraband/librarymanagement.json index 28422cfdd..fa7506f95 100644 --- a/librarymanagement/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -2,6 +2,133 @@ "codecNamespace": "sbt.librarymanagement", "fullCodec": "LibraryManagementCodec", "types": [ + { + "name": "UpdateConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { + "name": "retrieveManaged", + "doc": [ + "If set to some RetrieveConfiguration, this enables retrieving dependencies to the specified directory.", + "Otherwise, dependencies are used directly from the cache." + ], + "type": "sbt.librarymanagement.RetrieveConfiguration?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "missingOk", + "doc": [ + "If set to true, it ignores when artifacts are missing.", + "This setting could be uses when retrieving source/javadocs jars opportunistically." + ], + "type": "boolean", + "default": "false", + "since": "0.0.1" + }, + { + "name": "logging", + "doc": [ + "Logging setting used specifially for library management." + ], + "type": "sbt.librarymanagement.UpdateLogging", + "default": "sbt.librarymanagement.UpdateLogging.Default", + "since": "0.0.1" + }, + { + "name": "logicalClock", + "doc": [ + "The clock that may be used for caching." + ], + "type": "sbt.librarymanagement.LogicalClock", + "default": "sbt.librarymanagement.LogicalClock.unknown", + "since": "0.0.1" + }, + { + "name": "metadataDirectory", + "doc": [ + "The base directory that may be used to store metadata." + ], + "type": "java.io.File?", + "default": "None", + "since": "0.0.1" + }, + { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter?", "default": "None", "since": "0.0.1" }, + { + "name": "offline", + "type": "boolean", + "default": "false", + "since": "0.0.1" + }, + { + "name": "frozen", + "type": "boolean", + "default": "false", + "since": "0.0.1" + } + ] + }, + { + "name": "RetrieveConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "retrieveDirectory", "type": "java.io.File?", "default": "None", "since": "0.0.1" }, + { "name": "outputPattern", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.2" }, + { "name": "configurationsToRetrieve", "type": "scala.Vector[sbt.librarymanagement.ConfigRef]?", "default": "None", "since": "0.0.2" } + ] + }, + { + "name": "GetClassifiersConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "module", "type": "sbt.librarymanagement.GetClassifiersModule" }, + { "name": "excludes", "type": "scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]*" }, + { "name": "updateConfiguration", "type": "sbt.librarymanagement.UpdateConfiguration" }, + { "name": "sourceArtifactTypes", "type": "String*" }, + { "name": "docArtifactTypes", "type": "String*" } + ] + }, + { + "name": "GetClassifiersModule", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "id", "type": "sbt.librarymanagement.ModuleID" }, + { "name": "scalaModuleInfo", "type": "sbt.librarymanagement.ScalaModuleInfo?" }, + { "name": "dependencies", "type": "sbt.librarymanagement.ModuleID*" }, + { "name": "configurations", "type": "sbt.librarymanagement.Configuration*" }, + { "name": "classifiers", "type": "String*" } + ] + }, + { + "name": "PublishConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "publishMavenStyle", "type": "boolean", "default": "true", "since": "0.0.1" }, + { "name": "deliverIvyPattern", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "status", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "configurations", "type": "scala.Vector[sbt.librarymanagement.ConfigRef]?", "default": "None", "since": "0.0.1" }, + { "name": "resolverName", "type": "String?", "default": "None", "since": "0.0.1" }, + { "name": "artifacts", "type": "scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]*", "default": "Vector()", "since": "0.0.1" }, + { + "name": "checksums", + "type": "scala.Vector[String]", + "default": "Vector(\"sha1\", \"md5\")", + "since": "0.0.1" }, + { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging?", "default": "None", "since": "0.0.1" }, + { "name": "overwrite", "type": "boolean", "default": "false", "since": "0.0.1" } + ] + }, { "name": "Artifact", "namespace": "sbt.librarymanagement", @@ -240,7 +367,7 @@ "parentsCompanion": "sbt.librarymanagement.InclExclRuleFunctions" }, { - "name": "IvyScala", + "name": "ScalaModuleInfo", "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", @@ -253,8 +380,7 @@ { "name": "overrideScalaVersion", "type": "boolean" }, { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, { "name": "scalaArtifacts", "type": "scala.Vector[String]", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } - ], - "parentsCompanion": "sbt.librarymanagement.IvyScalaFunctions" + ] }, { "name": "ModuleConfiguration", @@ -367,8 +493,18 @@ "target": "Scala", "type": "interface", "fields": [ - { "name": "validate", "type": "boolean" }, - { "name": "ivyScala", "type": "sbt.librarymanagement.IvyScala?" } + { + "name": "validate", + "type": "boolean", + "default": "false", + "since": "0.0.1" + }, + { + "name": "scalaModuleInfo", + "type": "sbt.librarymanagement.ScalaModuleInfo?", + "default": "None", + "since": "0.0.1" + } ], "types": [ { @@ -392,20 +528,49 @@ ] }, { - "name": "InlineConfiguration", - "namespace": "sbt.internal.librarymanagement", + "name": "ModuleDescriptorConfiguration", + "docs": [ + "A module descriptor that represents a subproject, formerly known as an InlineConfiguration." + ], + "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", "fields": [ - { "name": "module", "type": "sbt.librarymanagement.ModuleID" }, - { "name": "moduleInfo", "type": "sbt.librarymanagement.ModuleInfo" }, - { "name": "dependencies", "type": "sbt.librarymanagement.ModuleID*" }, - { "name": "overrides", "type": "Set[sbt.librarymanagement.ModuleID]", "default": "Set.empty", "since": "0.0.1" }, - { "name": "excludes", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" }, - { "name": "configurations", "type": "sbt.librarymanagement.Configuration*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "defaultConfiguration", "type": "Option[sbt.librarymanagement.Configuration]", "default": "None", "since": "0.0.1" }, - { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } + { + "name": "module", + "type": "sbt.librarymanagement.ModuleID" + }, + { + "name": "moduleInfo", + "type": "sbt.librarymanagement.ModuleInfo" + }, + { + "name": "dependencies", + "type": "sbt.librarymanagement.ModuleID*", + "default": "Vector.empty", + "since": "0.0.1" + }, + { + "name": "overrides", + "type": "sbt.librarymanagement.ModuleID*", + "default": "Vector.empty", + "since": "0.0.1" + }, + { "name": "excludes", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "ivyXML", "type": "scala.xml.NodeSeq", "default": "scala.xml.NodeSeq.Empty", "since": "0.0.1" }, + { + "name": "configurations", + "type": "sbt.librarymanagement.Configuration*", + "default": "sbt.librarymanagement.Configurations.default", + "since": "0.0.1" + }, + { + "name": "defaultConfiguration", + "type": "sbt.librarymanagement.Configuration?", + "default": "Option(sbt.librarymanagement.Configurations.Compile)", + "since": "0.0.1" + }, + { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } ], "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationFunctions" } @@ -650,20 +815,6 @@ { "name": "port", "type": "int?" } ] }, - { - "name": "UpdateConfiguration", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "retrieve", "type": "sbt.internal.librarymanagement.RetrieveConfiguration?" }, - { "name": "missingOk", "type": "boolean" }, - { "name": "logging", "type": "sbt.librarymanagement.UpdateLogging" }, - { "name": "artifactFilter", "type": "sbt.librarymanagement.ArtifactTypeFilter" }, - { "name": "offline", "type": "boolean" }, - { "name": "frozen", "type": "boolean" } - ] - }, { "name": "UpdateLogging", "namespace": "sbt.librarymanagement", @@ -733,83 +884,6 @@ { "name": "details", "type": "sbt.librarymanagement.OrganizationArtifactReport*" } ] }, - { - "name": "IvyConfiguration", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "interface", - "fields": [ - { "name": "lock", "type": "xsbti.GlobalLock?" }, - { "name": "baseDirectory", "type": "java.io.File" }, - { "name": "log", "type": "xsbti.Logger" }, - { "name": "updateOptions", "type": "sbt.librarymanagement.UpdateOptions" } - ], - "types": [ - { - "name": "InlineIvyConfiguration", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "paths", "type": "sbt.internal.librarymanagement.IvyPaths" }, - { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" }, - { "name": "otherResolvers", "type": "sbt.librarymanagement.Resolver*" }, - { "name": "moduleConfigurations", "type": "sbt.librarymanagement.ModuleConfiguration*" }, - { "name": "checksums", "type": "String*" }, - { "name": "managedChecksums", "type": "Boolean" }, - { "name": "resolutionCacheDir", "type": "java.io.File?" } - ], - "extra": [ - "def this(", - " paths: sbt.internal.librarymanagement.IvyPaths,", - " resolvers: Vector[sbt.librarymanagement.Resolver],", - " otherResolvers: Vector[sbt.librarymanagement.Resolver],", - " moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],", - " lock: Option[xsbti.GlobalLock],", - " checksums: Vector[String],", - " managedChecksums: Boolean,", - " resolutionCacheDir: Option[java.io.File],", - " updateOptions: sbt.librarymanagement.UpdateOptions,", - " log: xsbti.Logger", - ") =", - " this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers,", - " moduleConfigurations, checksums, managedChecksums, resolutionCacheDir)" - ] - }, - { - "name": "ExternalIvyConfiguration", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "uri", "type": "java.net.URI" }, - { "name": "extraResolvers", "type": "sbt.librarymanagement.Resolver*" } - ] - } - ] - }, - { - "name": "IvyPaths", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "baseDirectory", "type": "java.io.File" }, - { "name": "ivyHome", "type": "java.io.File?" } - ] - }, - { - "name": "RetrieveConfiguration", - "namespace": "sbt.internal.librarymanagement", - "target": "Scala", - "type": "record", - "fields": [ - { "name": "retrieveDirectory", "type": "java.io.File" }, - { "name": "outputPattern", "type": "String" }, - { "name": "sync", "type": "boolean", "default": "false", "since": "0.0.1" }, - { "name": "configurationsToRetrieve", "type": "Option[Set[sbt.librarymanagement.ConfigRef]]", "default": "None", "since": "0.0.1" } - ] - }, { "name": "UpdateReportLite", "namespace": "sbt.internal.librarymanagement", diff --git a/librarymanagement/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java similarity index 100% rename from librarymanagement/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java rename to core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala b/core/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala similarity index 86% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala rename to core/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala index 42d3e6ca3..3ad192577 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/CompatibilityWarning.scala @@ -26,7 +26,7 @@ object CompatibilityWarningOptions { private[sbt] object CompatibilityWarning { def run( config: CompatibilityWarningOptions, - module: IvySbt#Module, + module: ModuleDescriptor, mavenStyle: Boolean, log: Logger ): Unit = { @@ -36,20 +36,16 @@ private[sbt] object CompatibilityWarning { } def processIntransitive( config: CompatibilityWarningOptions, - module: IvySbt#Module, + module: ModuleDescriptor, log: Logger ): Unit = { val monitoredConfigsStr: Set[String] = (config.configurations map { _.name }).toSet - val directDependencies: Seq[ModuleID] = module.moduleSettings match { - case x: InlineConfiguration => x.dependencies - case _ => Seq() - } def inMonitoredConfigs(configOpt: Option[String]): Boolean = configOpt match { case Some(c) => (c.split(",").toSet intersect monitoredConfigsStr).nonEmpty case None => monitoredConfigsStr contains "compile" } - directDependencies foreach { m => + module.directDependencies foreach { m => if (!m.isTransitive && inMonitoredConfigs(m.configurations)) { log.warn( s"""Found intransitive dependency ($m) while publishMavenStyle is true, but Maven repositories diff --git a/core/src/main/scala/sbt/internal/librarymanagement/InternalDefaults.scala b/core/src/main/scala/sbt/internal/librarymanagement/InternalDefaults.scala new file mode 100644 index 000000000..277d54dba --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/InternalDefaults.scala @@ -0,0 +1,29 @@ +package sbt +package internal.librarymanagement + +import java.io.File +import sbt.librarymanagement._ +import sbt.io.syntax._ + +/** + * This is a list of functions with default values. + */ +object InternalDefaults { + val sbtOrgTemp = JsonUtil.sbtOrgTemp + val modulePrefixTemp = "temp-module-" + + def getArtifactTypeFilter(opt: Option[ArtifactTypeFilter]): ArtifactTypeFilter = + opt.getOrElse(Artifact.defaultArtifactTypeFilter) + + def defaultRetrieveDirectory: File = + (new File(".")).getAbsoluteFile / "lib_managed" + + def getRetrieveDirectory(opt: Option[File]): File = + opt.getOrElse(defaultRetrieveDirectory) + + def getRetrievePattern(opt: Option[String]): String = + opt.getOrElse(Resolver.defaultRetrievePattern) + + def getDeliverStatus(opt: Option[String]): String = + opt.getOrElse("release") +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala rename to core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala rename to core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 4532b019e..85f5c387f 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -1,17 +1,15 @@ package sbt.internal.librarymanagement import java.io.File -import org.apache.ivy.core.module.descriptor.ModuleDescriptor -import sbt.io.IO import sbt.util.{ CacheStore, Logger } import sbt.librarymanagement._, LibraryManagementCodec._ +import sbt.io.IO private[sbt] object JsonUtil { def sbtOrgTemp = "org.scala-sbt.temp" def fakeCallerOrganization = "org.scala-sbt.temp-callers" def parseUpdateReport( - md: ModuleDescriptor, path: File, cachedDescriptor: File, log: Logger diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala b/core/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala rename to core/src/main/scala/sbt/internal/librarymanagement/StringUtilities.scala diff --git a/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala new file mode 100644 index 000000000..c01e781af --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala @@ -0,0 +1,79 @@ +package sbt.internal.librarymanagement + +import java.io.File +import sbt.librarymanagement._ + +object UpdateClassifiersUtil { + + def restrictedCopy(m: ModuleID, confs: Boolean) = + ModuleID(m.organization, m.name, m.revision) + .withCrossVersion(m.crossVersion) + .withExtraAttributes(m.extraAttributes) + .withConfigurations(if (confs) m.configurations else None) + .branch(m.branchName) + + // This version adds explicit artifact + def classifiedArtifacts( + classifiers: Vector[String], + exclude: Map[ModuleID, Set[ConfigRef]], + artifacts: Vector[(String, ModuleID, Artifact, File)] + )(m: ModuleID): Option[ModuleID] = { + def sameModule(m1: ModuleID, m2: ModuleID): Boolean = + m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision + def explicitArtifacts = { + val arts = (artifacts collect { + case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art + }).distinct + if (arts.isEmpty) None + else Some(intransitiveModuleWithExplicitArts(m, arts)) + } + def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) + explicitArtifacts orElse hardcodedArtifacts + } + + def classifiedArtifacts( + classifiers: Vector[String], + exclude: Map[ModuleID, Set[ConfigRef]] + )(m: ModuleID): Option[ModuleID] = { + val excluded: Set[ConfigRef] = exclude getOrElse (restrictedCopy(m, false), Set.empty) + val exls = excluded map { _.name } + val included = classifiers filterNot exls + if (included.isEmpty) None + else { + Some( + intransitiveModuleWithExplicitArts( + module = m, + arts = classifiedArtifacts(m.name, included) + ) + ) + } + } + + def classifiedArtifacts(name: String, classifiers: Vector[String]): Vector[Artifact] = + classifiers map { c => + Artifact.classified(name, c) + } + + /** + * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, + * [[org.apache.ivy.core.resolve.IvyNode#getArtifacts]] (in Ivy 2.3.0-rc1) will not merge in the descriptor's + * artifacts and will only keep the explicitArtifacts. + *
+ * Look for the comment saying {{{ + * // and now we filter according to include rules + * }}} + * in `IvyNode`, which iterates on `includes`, which will ordinarily be empty because higher up, in {{{ + * addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf)); + * }}} + * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. + */ + private def intransitiveModuleWithExplicitArts( + module: ModuleID, + arts: Vector[Artifact] + ): ModuleID = + module + .withIsTransitive(false) + .withExplicitArtifacts(arts) + .withInclusions(Vector(InclExclRule.everything)) + +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala similarity index 94% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala rename to core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index 38c5661b6..eed2eebb0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -20,14 +20,14 @@ object VersionRange { if (isVersionRange(version)) { val noSpace = version.replaceAllLiterally(" ", "") noSpace match { - case MavenVersionSetPattern(open1, x1, comma, x2, close1, rest) => + case MavenVersionSetPattern(open1, x1, comma, x2, close1, _) => // http://maven.apache.org/components/enforcer/enforcer-rules/versionRanges.html (open1, Option(x1), Option(comma), Option(x2), close1) match { case (_, None, _, Some(x2), "]") => Some(x2) // a good upper bound is unknown - case (_, None, _, Some(x2), ")") => None - case (_, Some(x1), _, None, _) => Some(x1) - case _ => None + case (_, None, _, Some(_), ")") => None + case (_, Some(x1), _, None, _) => Some(x1) + case _ => None } case _ => None } @@ -68,7 +68,7 @@ object VersionRange { case _ => revision } } catch { - case e: NumberFormatException => + case _: NumberFormatException => // TODO - if the version doesn't meet our expectations, maybe we just issue a hard // error instead of softly ignoring the attempt to rewrite. //sys.error(s"Could not fix version [$revision] into maven style version") diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala rename to core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala rename to core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala rename to core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/LogicalClockFormats.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/LogicalClockFormats.scala new file mode 100644 index 000000000..9daca4a93 --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/LogicalClockFormats.scala @@ -0,0 +1,13 @@ +package sbt.internal.librarymanagement.formats + +import sjsonnew._ + +import sbt.librarymanagement.LogicalClock + +trait LogicalClockFormats { self: BasicJsonProtocol => + implicit lazy val LogicalClockFormat: JsonFormat[LogicalClock] = + projectFormat[LogicalClock, String]( + cl => cl.toString, + str => LogicalClock(str) + ) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala rename to core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala similarity index 93% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala rename to core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 62fac2e6b..3bd58fe53 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -70,8 +70,11 @@ abstract class ArtifactFunctions { def pom(name: String) = Artifact(name, PomType, PomType, None, Vector(Pom), None) // Possible ivy artifact types such that sbt will treat those artifacts at sources / docs - val DefaultSourceTypes = Set("src", "source", "sources") - val DefaultDocTypes = Set("doc", "docs", "javadoc", "javadocs") + val DefaultSourceTypes: Set[String] = Set("src", "source", "sources") + val DefaultDocTypes: Set[String] = Set("doc", "docs", "javadoc", "javadocs") + val specialArtifactTypes: Set[String] = DefaultSourceTypes union DefaultDocTypes + val defaultArtifactTypeFilter: ArtifactTypeFilter = + ArtifactTypeFilter.forbid(specialArtifactTypes) val DocClassifier = "javadoc" val SourceClassifier = "sources" diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Configuration.scala rename to core/src/main/scala/sbt/librarymanagement/Configuration.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala similarity index 86% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala rename to core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 954a3eeae..6f19e572b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -7,14 +7,15 @@ import scala.annotation.tailrec import scala.language.experimental.macros object Configurations { - def config(name: String) = macro ConfigurationMacro.configMacroImpl - def default: Seq[Configuration] = defaultMavenConfigurations - def defaultMavenConfigurations: Seq[Configuration] = - Seq(Compile, Runtime, Test, Provided, Optional) - def defaultInternal: Seq[Configuration] = Seq(CompileInternal, RuntimeInternal, TestInternal) - def auxiliary: Seq[Configuration] = Seq(Pom) - def names(cs: Seq[Configuration]) = cs.map(_.name) - def refs(cs: Seq[Configuration]) = cs.map(_.toConfigRef) + def config(name: String): Configuration = macro ConfigurationMacro.configMacroImpl + def default: Vector[Configuration] = defaultMavenConfigurations + def defaultMavenConfigurations: Vector[Configuration] = + Vector(Compile, Runtime, Test, Provided, Optional) + def defaultInternal: Vector[Configuration] = + Vector(CompileInternal, RuntimeInternal, TestInternal) + def auxiliary: Vector[Configuration] = Vector(Pom) + def names(cs: Vector[Configuration]): Vector[String] = cs.map(_.name) + def refs(cs: Vector[Configuration]): Vector[ConfigRef] = cs.map(_.toConfigRef) lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) @@ -103,7 +104,7 @@ abstract class ConfigurationExtra { private[sbt] object ConfigurationMacro { import scala.reflect.macros._ - def configMacroImpl(c: Context)(name: c.Expr[String]): c.Expr[Configuration] = { + def configMacroImpl(c: blackbox.Context)(name: c.Expr[String]): c.Expr[Configuration] = { import c.universe._ val enclosingValName = definingValName( c, @@ -120,10 +121,10 @@ private[sbt] object ConfigurationMacro { n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary @tailrec def enclosingVal(trees: List[c.Tree]): String = { trees match { - case vd @ ValDef(_, name, _, _) :: ts => processName(name) + case ValDef(_, name, _, _) :: _ => processName(name) case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) // lazy val x: X = has this form for some reason (only when the explicit type is present, though) - case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: xs if mods.hasFlag(Flag.LAZY) => + case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: _ if mods.hasFlag(Flag.LAZY) => processName(name) case _ => c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString)) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala similarity index 95% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala rename to core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala index 30c09a453..c292cbc29 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala @@ -4,7 +4,8 @@ package sbt package librarymanagement -import _root_.sjsonnew.{ deserializationError, serializationError, Builder, JsonFormat, Unbuilder } +import _root_.sjsonnew.{ deserializationError, Builder, JsonFormat, Unbuilder } + trait ConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ConflictWarning.scala rename to core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala similarity index 96% rename from librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala rename to core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 0ce279c27..93c28a199 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -1,6 +1,7 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.cross.CrossVersionUtil +import sbt.librarymanagement.syntax._ final case class ScalaVersion(full: String, binary: String) @@ -79,11 +80,11 @@ abstract class CrossVersionFunctions { } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ - def apply(module: ModuleID, is: IvyScala): Option[String => String] = + def apply(module: ModuleID, is: ScalaModuleInfo): Option[String => String] = CrossVersion(module.crossVersion, is.scalaFullVersion, is.scalaBinaryVersion) /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ - def apply(module: ModuleID, is: Option[IvyScala]): Option[String => String] = + def apply(module: ModuleID, is: Option[ScalaModuleInfo]): Option[String => String] = is.flatMap(i => apply(module, i)) /** Cross-version each `Artifact` in `artifacts` according to cross-version function `cross`. */ @@ -108,7 +109,7 @@ abstract class CrossVersionFunctions { /** Cross-versions `exclude` according to its `crossVersion`. */ private[sbt] def substituteCross( exclude: ExclusionRule, - is: Option[IvyScala] + is: Option[ScalaModuleInfo] ): ExclusionRule = { val fopt: Option[String => String] = is flatMap { i => diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala new file mode 100755 index 000000000..8191cb1bf --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -0,0 +1,67 @@ +/* sbt -- Simple Build Tool + * Copyright 2009,2010 Mark Harrah + */ +package sbt.librarymanagement + +import sbt.internal.librarymanagement.StringUtilities.nonEmpty + +abstract class DependencyBuilders { + import DependencyBuilders._ + + implicit def stringToOrganization(organization: String): Organization = { + nonEmpty(organization, "Organization") + new Organization(organization) + } + + implicit def toRepositoryName(name: String): RepositoryName = { + nonEmpty(name, "Repository name") + new RepositoryName(name) + } + + implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = { + require(m.configurations.isEmpty, "Configurations already specified for module " + m) + new ModuleIDConfigurable(m) + } +} + +object DependencyBuilders { + final class Organization private[sbt] (private[sbt] val organization: String) { + def %(name: String) = organizationArtifact(name, Disabled()) + def %%(name: String): OrganizationArtifactName = + organizationArtifact(name, CrossVersion.binary) + + private def organizationArtifact(name: String, cross: CrossVersion) = { + nonEmpty(name, "Artifact ID") + new OrganizationArtifactName(organization, name, cross) + } + } + + final class OrganizationArtifactName private[sbt] ( + private[sbt] val organization: String, + private[sbt] val name: String, + private[sbt] val crossVersion: CrossVersion + ) { + def %(revision: String): ModuleID = { + nonEmpty(revision, "Revision") + ModuleID(organization, name, revision).cross(crossVersion) + } + } + + final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { + def %(configuration: Configuration): ModuleID = %(configuration.name) + def %(configuration: ConfigRef): ModuleID = %(configuration.name) + + def %(configurations: String): ModuleID = { + nonEmpty(configurations, "Configurations") + val c = configurations + moduleID.withConfigurations(configurations = Some(c)) + } + } + + final class RepositoryName private[sbt] (name: String) { + def at(location: String) = { + nonEmpty(location, "Repository location") + MavenRepository(name, location) + } + } +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/DependencyFilter.scala rename to core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala similarity index 90% rename from librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala rename to core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 7316be808..36aebaccb 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -5,7 +5,6 @@ import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } import sbt.util.Logger import sbt.util.ShowLines -import sbt.internal.librarymanagement.{ InlineConfiguration, IvySbt } final class EvictionWarningOptions private[sbt] ( val configurations: Seq[ConfigRef], @@ -14,7 +13,7 @@ final class EvictionWarningOptions private[sbt] ( val warnTransitiveEvictions: Boolean, val infoAllEvictions: Boolean, val showCallers: Boolean, - val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] + val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] ) { def withConfigurations(configurations: Seq[ConfigRef]): EvictionWarningOptions = copy(configurations = configurations) @@ -29,7 +28,7 @@ final class EvictionWarningOptions private[sbt] ( def withShowCallers(showCallers: Boolean): EvictionWarningOptions = copy(showCallers = showCallers) def withGuessCompatible( - guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] ): EvictionWarningOptions = copy(guessCompatible = guessCompatible) @@ -40,7 +39,7 @@ final class EvictionWarningOptions private[sbt] ( warnTransitiveEvictions: Boolean = warnTransitiveEvictions, infoAllEvictions: Boolean = infoAllEvictions, showCallers: Boolean = showCallers, - guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = + guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessCompatible ): EvictionWarningOptions = new EvictionWarningOptions( @@ -84,13 +83,14 @@ object EvictionWarningOptions { defaultGuess ) - lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = + lazy val defaultGuess + : Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse lazy val guessSecondSegment - : PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { - case (m1, Some(m2), Some(ivyScala)) - if m2.name.endsWith("_" + ivyScala.scalaFullVersion) || m2.name.endsWith( - "_" + ivyScala.scalaBinaryVersion + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (m1, Some(m2), Some(scalaModuleInfo)) + if m2.name.endsWith("_" + scalaModuleInfo.scalaFullVersion) || m2.name.endsWith( + "_" + scalaModuleInfo.scalaBinaryVersion ) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => @@ -100,7 +100,7 @@ object EvictionWarningOptions { } } lazy val guessSemVer - : PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), _) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => @@ -109,7 +109,8 @@ object EvictionWarningOptions { case _ => false } } - lazy val guessFalse: PartialFunction[(ModuleID, Option[ModuleID], Option[IvyScala]), Boolean] = { + lazy val guessFalse + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (_, _, _) => false } } @@ -176,7 +177,7 @@ final class EvictionWarning private[sbt] ( object EvictionWarning { def apply( - module: IvySbt#Module, + module: ModuleDescriptor, options: EvictionWarningOptions, report: UpdateReport, log: Logger @@ -207,11 +208,11 @@ object EvictionWarning { } private[sbt] def isScalaArtifact( - module: IvySbt#Module, + module: ModuleDescriptor, organization: String, name: String ): Boolean = - module.moduleSettings.ivyScala match { + module.scalaModuleInfo match { case Some(s) => organization == s.scalaOrganization && (name == LibraryID) || (name == CompilerID) @@ -219,14 +220,11 @@ object EvictionWarning { } private[sbt] def processEvictions( - module: IvySbt#Module, + module: ModuleDescriptor, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport] ): EvictionWarning = { - val directDependencies = module.moduleSettings match { - case x: InlineConfiguration => x.dependencies - case _ => Vector.empty - } + val directDependencies = module.directDependencies val pairs = reports map { detail => val evicteds = detail.modules filter { _.evicted } val winner = (detail.modules filterNot { _.evicted }).headOption @@ -250,12 +248,12 @@ object EvictionWarning { def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => options.guessCompatible( - (r.module, p.winner map { _.module }, module.moduleSettings.ivyScala) + (r.module, p.winner map { _.module }, module.scalaModuleInfo) ) } pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => - (module.moduleSettings.ivyScala, p.winner) match { + (module.scalaModuleInfo, p.winner) match { case (Some(s), Some(winner)) if (s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction => scalaEvictions += p diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala b/core/src/main/scala/sbt/librarymanagement/Extra.scala similarity index 71% rename from librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala rename to core/src/main/scala/sbt/librarymanagement/Extra.scala index 25eb5bc13..8c6eebf16 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/Extra.scala @@ -3,9 +3,7 @@ */ package sbt.librarymanagement -import org.apache.ivy.core.module.descriptor -import org.apache.ivy.util.filter.{ Filter => IvyFilter } -import sbt.internal.librarymanagement.impl.{ GroupArtifactID, GroupID } +import sbt.librarymanagement.DependencyBuilders.{ Organization, OrganizationArtifactName } abstract class InclExclRuleFunctions { def everything = InclExclRule("*", "*", "*", Vector.empty, Disabled()) @@ -15,12 +13,13 @@ abstract class InclExclRuleFunctions { def apply(organization: String): InclExclRule = apply(organization, "*") - implicit def groupIdToExclusionRule(organization: GroupID): InclExclRule = - apply(organization.groupID) + implicit def organizationToExclusionRule(organization: Organization): InclExclRule = + apply(organization.organization) implicit def stringToExclusionRule(organization: String): InclExclRule = apply(organization) - implicit def groupArtifactIDToExclusionRule(gaid: GroupArtifactID): InclExclRule = - InclExclRule(gaid.groupID, gaid.artifactID, "*", Vector.empty, gaid.crossVersion) + implicit def organizationArtifactNameToExclusionRule( + oa: OrganizationArtifactName): InclExclRule = + InclExclRule(oa.organization, oa.name, "*", Vector.empty, oa.crossVersion) implicit def moduleIDToExclusionRule(moduleID: ModuleID): InclExclRule = { val org = moduleID.organization @@ -41,18 +40,11 @@ abstract class ArtifactTypeFilterExtra { ): ArtifactTypeFilter def invert = copy(inverted = !inverted) - def apply(a: descriptor.Artifact): Boolean = (types contains a.getType) ^ inverted } abstract class ArtifactTypeFilterFunctions { def allow(types: Set[String]) = ArtifactTypeFilter(types, false) def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) - - implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { - case a: descriptor.Artifact => f.apply(a) - } - } } abstract class ConflictManagerFunctions { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Http.scala rename to core/src/main/scala/sbt/librarymanagement/Http.scala diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala new file mode 100644 index 000000000..82401ec4b --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala @@ -0,0 +1,198 @@ +package sbt.librarymanagement + +import java.io.File +import sbt.util.Logger +import sbt.io.Hash +import sbt.librarymanagement.syntax._ + +/** + * Helper mixin to provide methods for library management + */ +abstract class LibraryManagement extends LibraryManagementInterface { + import sbt.internal.librarymanagement.InternalDefaults._ + import sbt.internal.librarymanagement.UpdateClassifiersUtil._ + + /** + * Build a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleId The root module for which to create a `ModuleDescriptor`. + * @param directDependencies The direct dependencies of the module. + * @param scalaModuleInfo The information about the Scala version used, if any. + * @param configurations The configurations that this module has. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + def moduleDescriptor(moduleId: ModuleID, + directDependencies: Vector[ModuleID], + scalaModuleInfo: Option[ScalaModuleInfo]): ModuleDescriptor = { + val moduleSetting = ModuleDescriptorConfiguration(moduleId, ModuleInfo(moduleId.name)) + .withScalaModuleInfo(scalaModuleInfo) + .withDependencies(directDependencies) + moduleDescriptor(moduleSetting) + } + + /** + * Returns a `ModuleDescriptor` that depends on `dependencyId`. + * + * @param dependencyId The module to depend on. + * @return A `ModuleDescriptor` that depends on `dependencyId`. + */ + def wrapDependencyInModule(dependencyId: ModuleID): ModuleDescriptor = + wrapDependencyInModule(dependencyId, None) + + /** + * Returns a `ModuleDescriptor` that depends on `dependencyId`. + * + * @param dependencyId The module to depend on. + * @param scalaModuleInfo The information about the Scala verson used, if any. + * @return A `ModuleDescriptor` that depends on `dependencyId`. + */ + def wrapDependencyInModule(dependencyId: ModuleID, + scalaModuleInfo: Option[ScalaModuleInfo]): ModuleDescriptor = { + val sha1 = Hash.toHex(Hash(dependencyId.name)) + val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, dependencyId.revision) + .withConfigurations(dependencyId.configurations) + moduleDescriptor(dummyID, Vector(dependencyId), scalaModuleInfo) + } + + /** + * Resolves the given dependency, and retrieves the artifacts to a directory. + * + * @param dependencyId The dependency to be resolved. + * @param scalaModuleInfo The module info about Scala. + * @param retrieveDirectory The directory to retrieve the files. + * @param log The logger. + * @return The result, either an unresolved warning or a sequence of files. + */ + def retrieve(dependencyId: ModuleID, + scalaModuleInfo: Option[ScalaModuleInfo], + retrieveDirectory: File, + log: Logger): Either[UnresolvedWarning, Vector[File]] = + retrieve(wrapDependencyInModule(dependencyId, scalaModuleInfo), retrieveDirectory, log) + + /** + * Resolves the given module's dependencies, and retrieves the artifacts to a directory. + * + * @param module The module to be resolved. + * @param retrieveDirectory The directory to retrieve the files. + * @param log The logger. + * @return The result, either an unresolved warning or a sequence of files. + */ + def retrieve(module: ModuleDescriptor, + retrieveDirectory: File, + log: Logger): Either[UnresolvedWarning, Vector[File]] = { + // Using the default artifact type filter here, so sources and docs are excluded. + val retrieveConfiguration = RetrieveConfiguration() + .withRetrieveDirectory(retrieveDirectory) + val updateConfiguration = UpdateConfiguration() + .withRetrieveManaged(retrieveConfiguration) + // .withMissingOk(true) + log.debug(s"Attempting to fetch ${directDependenciesNames(module)}. This operation may fail.") + update( + module, + updateConfiguration, + UnresolvedWarningConfiguration(), + log + ) match { + case Left(unresolvedWarning) => Left(unresolvedWarning) + case Right(updateReport) => + val allFiles = + for { + conf <- updateReport.configurations + m <- conf.modules + (_, f) <- m.artifacts + } yield f + log.debug(s"Files retrieved for ${directDependenciesNames(module)}:") + log.debug(allFiles mkString ", ") + // allFiles filter predicate match { + // case Seq() => None + // case files => Some(files) + // } + Right(allFiles) + } + } + + def transitiveScratch( + label: String, + config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger + ): Either[UnresolvedWarning, UpdateReport] = { + import config.{ updateConfiguration => c, module => mod } + import mod.{ id, dependencies => deps, scalaModuleInfo } + val base = restrictedCopy(id, true).withName(id.name + "$" + label) + val module = moduleDescriptor(base, deps, scalaModuleInfo) + val report = update(module, c, uwconfig, log) match { + case Right(r) => r + case Left(w) => + throw w.resolveException + } + val newConfig = config + .withModule(mod.withDependencies(report.allModules)) + updateClassifiers(newConfig, uwconfig, Vector(), log) + } + + /** + * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This + * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy + * that sbt generates for them either.
+ * Artifacts can be obtained from calling toSeq on UpdateReport.
+ * In addition, retrieves specific Ivy artifacts if they have one of the requested `config.configuration.types`. + * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to + * "classified" artifacts (sources and javadocs). + */ + def updateClassifiers( + config: GetClassifiersConfiguration, + uwconfig: UnresolvedWarningConfiguration, + artifacts: Vector[(String, ModuleID, Artifact, File)], + log: Logger + ): Either[UnresolvedWarning, UpdateReport] = { + import config.{ updateConfiguration => c, module => mod, _ } + import mod.{ configurations => confs, _ } + val artifactFilter = getArtifactTypeFilter(c.artifactFilter) + assert(classifiers.nonEmpty, "classifiers cannot be empty") + assert(artifactFilter.types.nonEmpty, "UpdateConfiguration must filter on some types") + val baseModules = dependencies map { m => + restrictedCopy(m, true) + } + // Adding list of explicit artifacts here. + val exls = Map(excludes map { case (k, v) => (k, v.toSet) }: _*) + val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exls, artifacts) + val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", "")) + val moduleSetting = ModuleDescriptorConfiguration(base, ModuleInfo(base.name)) + .withScalaModuleInfo(scalaModuleInfo) + .withDependencies(deps) + .withConfigurations(confs) + val module = moduleDescriptor(moduleSetting) + + // c.copy ensures c.types is preserved too + val upConf = c.withMissingOk(true) + update(module, upConf, uwconfig, log) match { + case Right(r) => + // The artifacts that came from Ivy don't have their classifier set, let's set it according to + // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They + val typeClassifierMap: Map[String, String] = + ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) + :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap + Right(r.substitute { (conf, mid, artFileSeq) => + artFileSeq map { + case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + } + }) + case Left(w) => Left(w) + } + } + + protected def directDependenciesNames(module: ModuleDescriptor): String = + (module.directDependencies map { + case mID: ModuleID => + import mID._ + s"$organization % $name % $revision" + }).mkString(", ") +} + +/** + * Helper mixin to provide methods for publisher + */ +abstract class Publisher extends PublisherInterface diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala new file mode 100644 index 000000000..6650376b8 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -0,0 +1,84 @@ +package sbt.librarymanagement + +import java.io.File +import sbt.util.Logger + +/** + * Interface for library management + */ +abstract class LibraryManagementInterface { + + /** + * Builds a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleSetting It contains the information about the module including the dependencies. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor + + /** + * Resolves the given module's dependencies performing a retrieval. + * + * @param module The module to be resolved. + * @param configuration The update configuration. + * @param uwconfig The configuration to handle unresolved warnings. + * @param log The logger. + * @return The result, either an unresolved warning or an update report. Note that this + * update report will or will not be successful depending on the `missingOk` option. + */ + def update(module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger): Either[UnresolvedWarning, UpdateReport] +} + +/** + * Interface for publishing modules. + */ +abstract class PublisherInterface { + + /** + * Builds a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleSetting It contains the information about the module including the dependencies. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor + + /** + * Publishes the given module. + * + * @param module The module to be published. + * @param configuration The publish configuration. + * @param log The logger. + */ + def publish(module: ModuleDescriptor, configuration: PublishConfiguration, log: Logger): Unit + + /** + * Makes the `pom.xml` file for the given module. + * + * @param module The module for which a `.pom` file is to be created. + * @param configuration The makePomFile configuration. + * @param log The logger. + * @return The `File` containing the POM descriptor. + */ + def makePomFile(module: ModuleDescriptor, configuration: MakePomConfiguration, log: Logger): File +} + +/** + * Decribes the representation of a module, inclding its dependencies + * and the version of Scala it uses, if any. + */ +trait ModuleDescriptor { + + /** + * The direct dependencies of this module. + */ + def directDependencies: Vector[ModuleID] + + /** + * The information and module about the scala version that this module requires, + * if any. + */ + def scalaModuleInfo: Option[ScalaModuleInfo] +} diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala new file mode 100644 index 000000000..c83911de0 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala @@ -0,0 +1,24 @@ +package sbt.librarymanagement + +abstract class LibraryManagementSyntax extends DependencyBuilders { + type ExclusionRule = InclExclRule + val ExclusionRule = InclExclRule + + type InclusionRule = InclExclRule + val InclusionRule = InclExclRule + + implicit def richUpdateReport(ur: UpdateReport): RichUpdateReport = new RichUpdateReport(ur) + + import sbt.librarymanagement.{ Configurations => C } + final val Compile = C.Compile + final val Test = C.Test + final val Runtime = C.Runtime + final val IntegrationTest = C.IntegrationTest + final val Default = C.Default + final val Provided = C.Provided + // java.lang.System is more important, so don't alias this one + // final val System = C.System + final val Optional = C.Optional +} + +object syntax extends LibraryManagementSyntax diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala b/core/src/main/scala/sbt/librarymanagement/LogicalClock.scala similarity index 94% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala rename to core/src/main/scala/sbt/librarymanagement/LogicalClock.scala index b8ce426e7..f55a61b82 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/LogicalClock.scala +++ b/core/src/main/scala/sbt/librarymanagement/LogicalClock.scala @@ -1,4 +1,4 @@ -package sbt.internal.librarymanagement +package sbt.librarymanagement /** * Represents a logical time point for dependency resolution. diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala new file mode 100644 index 000000000..1beb16003 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -0,0 +1,15 @@ +package sbt.librarymanagement + +import java.io.File +import scala.xml.{ Node => XNode, NodeSeq } + +final class MakePomConfiguration( + val file: File, + val moduleInfo: ModuleInfo, + val configurations: Option[Vector[Configuration]] = None, + val extra: NodeSeq = NodeSeq.Empty, + val process: XNode => XNode = n => n, + val filterRepositories: MavenRepository => Boolean = _ => true, + val allRepositories: Boolean, + val includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType) +) diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala rename to core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 5b89b5419..7d9bfece2 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -7,6 +7,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer +import sbt.librarymanagement.syntax._ abstract class ModuleIDExtra { def organization: String diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala similarity index 93% rename from librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala rename to core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 077c3ae1f..3ded29183 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -6,10 +6,10 @@ package sbt.librarymanagement import java.io.{ IOException, File } import java.net.URL import scala.xml.XML -import org.apache.ivy.plugins.resolver.DependencyResolver +// import org.apache.ivy.plugins.resolver.DependencyResolver import org.xml.sax.SAXParseException -final class RawRepository(val resolver: DependencyResolver) extends Resolver(resolver.getName) { +final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" override def equals(o: Any): Boolean = o match { @@ -90,15 +90,8 @@ trait SftpRepositoryExtra extends SshBasedRepositoryExtra { } /** A repository that conforms to sbt launcher's interface */ -private[sbt] class FakeRepository(resolver: DependencyResolver) extends xsbti.Repository { - def rawRepository = new RawRepository(resolver) -} - -trait ResolversSyntax { - import Resolver._ - val DefaultMavenRepository = MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) - val JavaNet2Repository = MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) - val JCenterRepository = MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) +private[sbt] class FakeRepository(resolver: AnyRef, name: String) extends xsbti.Repository { + def rawRepository = new RawRepository(resolver, name) } abstract class ResolverFunctions { @@ -115,6 +108,14 @@ abstract class ResolverFunctions { val JCenterRepositoryName = "jcenter" val JCenterRepositoryRoot = "https://jcenter.bintray.com/" val DefaultMavenRepositoryRoot = "https://repo1.maven.org/maven2/" + val DefaultMavenRepository = + MavenRepository("public", centralRepositoryRoot(useSecureResolvers)) + val JavaNet2Repository = MavenRepository(JavaNet2RepositoryName, JavaNet2RepositoryRoot) + val JCenterRepository = MavenRepository(JCenterRepositoryName, JCenterRepositoryRoot) + + def mavenCentral: Resolver = DefaultMavenRepository + def defaults: Vector[Resolver] = Vector(mavenCentral) + // TODO: This switch is only kept for backward compatibility. Hardcode to HTTPS in the future. private[sbt] def centralRepositoryRoot(secure: Boolean) = (if (secure) "https" else "http") + "://repo1.maven.org/maven2/" @@ -162,27 +163,28 @@ abstract class ResolverFunctions { def jcenterRepo = JCenterRepository /** Add the local and Maven Central repositories to the user repositories. */ - def withDefaultResolvers(userResolvers: Seq[Resolver]): Seq[Resolver] = - withDefaultResolvers(userResolvers, mavenCentral = true) + def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = + combineDefaultResolvers(userResolvers, mavenCentral = true) /** * Add the local Ivy repository to the user repositories. * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers(userResolvers: Seq[Resolver], mavenCentral: Boolean): Seq[Resolver] = - withDefaultResolvers(userResolvers, jcenter = false, mavenCentral) + def combineDefaultResolvers(userResolvers: Vector[Resolver], + mavenCentral: Boolean): Vector[Resolver] = + combineDefaultResolvers(userResolvers, jcenter = false, mavenCentral) /** * Add the local Ivy repository to the user repositories. * If `jcenter` is true, add the JCenter. * If `mavenCentral` is true, add the Maven Central repository. */ - def withDefaultResolvers( - userResolvers: Seq[Resolver], + def combineDefaultResolvers( + userResolvers: Vector[Resolver], jcenter: Boolean, mavenCentral: Boolean - ): Seq[Resolver] = - Seq(Resolver.defaultLocal) ++ + ): Vector[Resolver] = + Vector(Resolver.defaultLocal) ++ userResolvers ++ single(JCenterRepository, jcenter) ++ single(DefaultMavenRepository, mavenCentral) @@ -193,24 +195,25 @@ abstract class ResolverFunctions { * If `mavenCentral` is true, add the Maven Central repository. */ private[sbt] def reorganizeAppResolvers( - appResolvers: Seq[Resolver], + appResolvers: Vector[Resolver], jcenter: Boolean, mavenCentral: Boolean - ): Seq[Resolver] = + ): Vector[Resolver] = appResolvers.partition(_ == Resolver.defaultLocal) match { case (locals, xs) => locals ++ (xs.partition(_ == JCenterRepository) match { - case (jc, xs) => + case (_, xs) => single(JCenterRepository, jcenter) ++ (xs.partition(_ == DefaultMavenRepository) match { - case (m, xs) => + case (_, xs) => single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates? }) }) } - private def single[T](value: T, nonEmpty: Boolean): Seq[T] = if (nonEmpty) Seq(value) else Nil + private def single[T](value: T, nonEmpty: Boolean): Vector[T] = + if (nonEmpty) Vector(value) else Vector.empty /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ sealed abstract class Define[RepositoryType <: SshBasedRepository] { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala rename to core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index e4b9d1045..297611b64 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -58,7 +58,7 @@ final class RichUpdateReport(report: UpdateReport) { modReport .withArtifacts( modReport.artifacts filter { - case (art, file) => f(configuration, modReport.module, art) + case (art, _) => f(configuration, modReport.module, art) } ) .withMissingArtifacts( diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala new file mode 100644 index 000000000..e0b1b6be5 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -0,0 +1,42 @@ +package sbt.librarymanagement + +object ScalaArtifacts { + val Organization = "org.scala-lang" + val LibraryID = "scala-library" + val CompilerID = "scala-compiler" + val ReflectID = "scala-reflect" + val ActorsID = "scala-actors" + val ScalapID = "scalap" + val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) + val DottyIDPrefix = "dotty" + + def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" + + def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) + + private[sbt] def toolDependencies( + org: String, + version: String, + isDotty: Boolean = false + ): Seq[ModuleID] = + if (isDotty) + Seq( + ModuleID(org, DottyIDPrefix, version) + .withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) + .withCrossVersion(CrossVersion.binary) + ) + else + Seq( + scalaToolDependency(org, ScalaArtifacts.CompilerID, version), + scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + ) + + private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = + ModuleID(org, id, version).withConfigurations( + Some(Configurations.ScalaTool.name + "->default,optional(default)") + ) +} + +object SbtArtifacts { + val Organization = "org.scala-sbt" +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala b/core/src/main/scala/sbt/librarymanagement/TrackLevel.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/librarymanagement/TrackLevel.scala rename to core/src/main/scala/sbt/librarymanagement/TrackLevel.scala diff --git a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala new file mode 100644 index 000000000..99017ba83 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala @@ -0,0 +1,88 @@ +package sbt.librarymanagement + +import collection.mutable +import sbt.util.ShowLines +import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } + +final class ResolveException( + val messages: Seq[String], + val failed: Seq[ModuleID], + val failedPaths: Map[ModuleID, Seq[ModuleID]] +) extends RuntimeException(messages.mkString("\n")) { + def this(messages: Seq[String], failed: Seq[ModuleID]) = + this(messages, failed, Map(failed map { m => + m -> Nil + }: _*)) +} + +/** + * Represents unresolved dependency warning, which displays reconstructed dependency tree + * along with source position of each node. + */ +final class UnresolvedWarning( + val resolveException: ResolveException, + val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] +) + +object UnresolvedWarning { + def apply( + err: ResolveException, + config: UnresolvedWarningConfiguration + ): UnresolvedWarning = { + def modulePosition(m0: ModuleID): Option[SourcePosition] = + config.modulePositions.find { + case (m, _) => + (m.organization == m0.organization) && + (m0.name startsWith m.name) && + (m.revision == m0.revision) + } map { + case (_, p) => p + } + val failedPaths = err.failed map { x: ModuleID => + err.failedPaths(x).toList.reverse map { id => + (id, modulePosition(id)) + } + } + new UnresolvedWarning(err, failedPaths) + } + + private[sbt] def sourcePosStr(posOpt: Option[SourcePosition]): String = + posOpt match { + case Some(LinePosition(path, start)) => s" ($path#L$start)" + case Some(RangePosition(path, LineRange(start, end))) => s" ($path#L$start-$end)" + case _ => "" + } + implicit val unresolvedWarningLines: ShowLines[UnresolvedWarning] = ShowLines { a => + val withExtra = a.resolveException.failed.filter(_.extraDependencyAttributes.nonEmpty) + val buffer = mutable.ListBuffer[String]() + if (withExtra.nonEmpty) { + buffer += "\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes." + withExtra foreach { id => + buffer += "\t\t" + id + } + } + if (a.failedPaths.nonEmpty) { + buffer += "\n\tNote: Unresolved dependencies path:" + a.failedPaths foreach { path => + if (path.nonEmpty) { + val head = path.head + buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) + path.tail foreach { + case (m, pos) => + buffer += "\t\t +- " + m.toString + sourcePosStr(pos) + } + } + } + } + buffer.toList + } +} + +final class UnresolvedWarningConfiguration private[sbt] ( + val modulePositions: Map[ModuleID, SourcePosition] +) +object UnresolvedWarningConfiguration { + def apply(): UnresolvedWarningConfiguration = apply(Map()) + def apply(modulePositions: Map[ModuleID, SourcePosition]): UnresolvedWarningConfiguration = + new UnresolvedWarningConfiguration(modulePositions) +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala rename to core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index db97688df..a97441cfd 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -131,7 +131,7 @@ abstract class UpdateReportExtra { def allModules: Vector[ModuleID] = { val key = (m: ModuleID) => (m.organization, m.name, m.revision) configurations.flatMap(_.allModules).groupBy(key).toVector map { - case (k, v) => + case (_, v) => v reduceLeft { (agg, x) => agg.withConfigurations( (agg.configurations, x.configurations) match { diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala rename to core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 2f82a3612..144b67a66 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -145,7 +145,8 @@ object VersionNumber { case (v1, v2) if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { - case (x1, y1, 0, ts1, x2, y2, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => + case (x1 @ _, y1 @ _, 0, ts1, x2 @ _, y2 @ _, 0, ts2) + if ts1.nonEmpty || ts2.nonEmpty => // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, y1, _, _, x2, y2, _, _) => diff --git a/librarymanagement/src/test/scala/ConfigMacroSpec.scala b/core/src/test/scala/ConfigMacroSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/ConfigMacroSpec.scala rename to core/src/test/scala/ConfigMacroSpec.scala diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala new file mode 100644 index 000000000..1a0dac7db --- /dev/null +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -0,0 +1,66 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.ivy +final class ExternalIvyConfiguration private ( + lock: Option[xsbti.GlobalLock], + log: Option[xsbti.Logger], + updateOptions: sbt.librarymanagement.ivy.UpdateOptions, + val baseDirectory: Option[java.io.File], + val uri: Option[java.net.URI], + val extraResolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.ivy.IvyConfiguration(lock, log, updateOptions) with Serializable { + + private def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, None, Vector()) + + override def equals(o: Any): Boolean = o match { + case x: ExternalIvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.baseDirectory == x.baseDirectory) && (this.uri == x.uri) && (this.extraResolvers == x.extraResolvers) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ExternalIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + baseDirectory.##) + uri.##) + extraResolvers.##) + } + override def toString: String = { + "ExternalIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + baseDirectory + ", " + uri + ", " + extraResolvers + ")" + } + protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, baseDirectory: Option[java.io.File] = baseDirectory, uri: Option[java.net.URI] = uri, extraResolvers: Vector[sbt.librarymanagement.Resolver] = extraResolvers): ExternalIvyConfiguration = { + new ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) + } + def withLock(lock: Option[xsbti.GlobalLock]): ExternalIvyConfiguration = { + copy(lock = lock) + } + def withLock(lock: xsbti.GlobalLock): ExternalIvyConfiguration = { + copy(lock = Option(lock)) + } + def withLog(log: Option[xsbti.Logger]): ExternalIvyConfiguration = { + copy(log = log) + } + def withLog(log: xsbti.Logger): ExternalIvyConfiguration = { + copy(log = Option(log)) + } + def withUpdateOptions(updateOptions: sbt.librarymanagement.ivy.UpdateOptions): ExternalIvyConfiguration = { + copy(updateOptions = updateOptions) + } + def withBaseDirectory(baseDirectory: Option[java.io.File]): ExternalIvyConfiguration = { + copy(baseDirectory = baseDirectory) + } + def withBaseDirectory(baseDirectory: java.io.File): ExternalIvyConfiguration = { + copy(baseDirectory = Option(baseDirectory)) + } + def withUri(uri: Option[java.net.URI]): ExternalIvyConfiguration = { + copy(uri = uri) + } + def withUri(uri: java.net.URI): ExternalIvyConfiguration = { + copy(uri = Option(uri)) + } + def withExtraResolvers(extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = { + copy(extraResolvers = extraResolvers) + } +} +object ExternalIvyConfiguration { + + def apply(): ExternalIvyConfiguration = new ExternalIvyConfiguration(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, None, Vector()) + def apply(lock: Option[xsbti.GlobalLock], log: Option[xsbti.Logger], updateOptions: sbt.librarymanagement.ivy.UpdateOptions, baseDirectory: Option[java.io.File], uri: Option[java.net.URI], extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) + def apply(lock: xsbti.GlobalLock, log: xsbti.Logger, updateOptions: sbt.librarymanagement.ivy.UpdateOptions, baseDirectory: java.io.File, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(Option(lock), Option(log), updateOptions, Option(baseDirectory), Option(uri), extraResolvers) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala similarity index 58% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala rename to ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala index 55de96c3e..ae915f0e8 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ExternalIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala @@ -3,32 +3,32 @@ */ // DO NOT EDIT MANUALLY -package sbt.librarymanagement +package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.ExternalIvyConfiguration] = new JsonFormat[sbt.internal.librarymanagement.ExternalIvyConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ExternalIvyConfiguration = { +trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") - val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") - val log = unbuilder.readField[xsbti.Logger]("log") - val updateOptions = unbuilder.readField[sbt.librarymanagement.UpdateOptions]("updateOptions") - val uri = unbuilder.readField[java.net.URI]("uri") + val log = unbuilder.readField[Option[xsbti.Logger]]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") + val baseDirectory = unbuilder.readField[Option[java.io.File]]("baseDirectory") + val uri = unbuilder.readField[Option[java.net.URI]]("uri") val extraResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("extraResolvers") unbuilder.endObject() - sbt.internal.librarymanagement.ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) + sbt.librarymanagement.ivy.ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.internal.librarymanagement.ExternalIvyConfiguration, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.ivy.ExternalIvyConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("lock", obj.lock) - builder.addField("baseDirectory", obj.baseDirectory) builder.addField("log", obj.log) builder.addField("updateOptions", obj.updateOptions) + builder.addField("baseDirectory", obj.baseDirectory) builder.addField("uri", obj.uri) builder.addField("extraResolvers", obj.extraResolvers) builder.endObject() diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala new file mode 100644 index 000000000..61360fde3 --- /dev/null +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -0,0 +1,104 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.ivy +final class InlineIvyConfiguration private ( + lock: Option[xsbti.GlobalLock], + log: Option[xsbti.Logger], + updateOptions: sbt.librarymanagement.ivy.UpdateOptions, + val paths: Option[sbt.librarymanagement.ivy.IvyPaths], + val resolvers: Vector[sbt.librarymanagement.Resolver], + val otherResolvers: Vector[sbt.librarymanagement.Resolver], + val moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], + val checksums: Vector[String], + val managedChecksums: Boolean, + val resolutionCacheDir: Option[java.io.File]) extends sbt.librarymanagement.ivy.IvyConfiguration(lock, log, updateOptions) with Serializable { + + private def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, sbt.librarymanagement.Resolver.defaults, Vector.empty, Vector.empty, sbt.librarymanagement.ivy.IvyDefaults.defaultChecksums, false, None) + + override def equals(o: Any): Boolean = o match { + case x: InlineIvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.paths == x.paths) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.moduleConfigurations == x.moduleConfigurations) && (this.checksums == x.checksums) && (this.managedChecksums == x.managedChecksums) && (this.resolutionCacheDir == x.resolutionCacheDir) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) + } + override def toString: String = { + "InlineIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + paths + ", " + resolvers + ", " + otherResolvers + ", " + moduleConfigurations + ", " + checksums + ", " + managedChecksums + ", " + resolutionCacheDir + ")" + } + protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, paths: Option[sbt.librarymanagement.ivy.IvyPaths] = paths, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration] = moduleConfigurations, checksums: Vector[String] = checksums, managedChecksums: Boolean = managedChecksums, resolutionCacheDir: Option[java.io.File] = resolutionCacheDir): InlineIvyConfiguration = { + new InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + } + def withLock(lock: Option[xsbti.GlobalLock]): InlineIvyConfiguration = { + copy(lock = lock) + } + def withLock(lock: xsbti.GlobalLock): InlineIvyConfiguration = { + copy(lock = Option(lock)) + } + def withLog(log: Option[xsbti.Logger]): InlineIvyConfiguration = { + copy(log = log) + } + def withLog(log: xsbti.Logger): InlineIvyConfiguration = { + copy(log = Option(log)) + } + def withUpdateOptions(updateOptions: sbt.librarymanagement.ivy.UpdateOptions): InlineIvyConfiguration = { + copy(updateOptions = updateOptions) + } + def withPaths(paths: Option[sbt.librarymanagement.ivy.IvyPaths]): InlineIvyConfiguration = { + copy(paths = paths) + } + def withPaths(paths: sbt.librarymanagement.ivy.IvyPaths): InlineIvyConfiguration = { + copy(paths = Option(paths)) + } + def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { + copy(resolvers = resolvers) + } + def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { + copy(otherResolvers = otherResolvers) + } + def withModuleConfigurations(moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration]): InlineIvyConfiguration = { + copy(moduleConfigurations = moduleConfigurations) + } + def withChecksums(checksums: Vector[String]): InlineIvyConfiguration = { + copy(checksums = checksums) + } + def withManagedChecksums(managedChecksums: Boolean): InlineIvyConfiguration = { + copy(managedChecksums = managedChecksums) + } + def withResolutionCacheDir(resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = { + copy(resolutionCacheDir = resolutionCacheDir) + } + def withResolutionCacheDir(resolutionCacheDir: java.io.File): InlineIvyConfiguration = { + copy(resolutionCacheDir = Option(resolutionCacheDir)) + } +} +object InlineIvyConfiguration { + /** Provided for backward compatibility. */ + def apply( + paths: sbt.librarymanagement.ivy.IvyPaths, + resolvers: Vector[sbt.librarymanagement.Resolver], + otherResolvers: Vector[sbt.librarymanagement.Resolver], + moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], + lock: Option[xsbti.GlobalLock], + checksums: Vector[String], + managedChecksums: Boolean, + resolutionCacheDir: Option[java.io.File], + updateOptions: sbt.librarymanagement.ivy.UpdateOptions, + log: xsbti.Logger + ): InlineIvyConfiguration = { + apply() + .withLock(lock) + .withResolvers(resolvers) + .withOtherResolvers(otherResolvers) + .withModuleConfigurations(moduleConfigurations) + .withChecksums(checksums) + .withManagedChecksums(managedChecksums) + .withResolutionCacheDir(resolutionCacheDir) + .withLog(log) + } + def apply(): InlineIvyConfiguration = new InlineIvyConfiguration(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, sbt.librarymanagement.Resolver.defaults, Vector.empty, Vector.empty, sbt.librarymanagement.ivy.IvyDefaults.defaultChecksums, false, None) + def apply(lock: Option[xsbti.GlobalLock], log: Option[xsbti.Logger], updateOptions: sbt.librarymanagement.ivy.UpdateOptions, paths: Option[sbt.librarymanagement.ivy.IvyPaths], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = new InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + def apply(lock: xsbti.GlobalLock, log: xsbti.Logger, updateOptions: sbt.librarymanagement.ivy.UpdateOptions, paths: sbt.librarymanagement.ivy.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: java.io.File): InlineIvyConfiguration = new InlineIvyConfiguration(Option(lock), Option(log), updateOptions, Option(paths), resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, Option(resolutionCacheDir)) +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala similarity index 61% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala rename to ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala index 8adfd3620..8c07808f5 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/InlineIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala @@ -3,19 +3,18 @@ */ // DO NOT EDIT MANUALLY -package sbt.librarymanagement +package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.InlineIvyConfiguration] = new JsonFormat[sbt.internal.librarymanagement.InlineIvyConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.InlineIvyConfiguration = { +trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") - val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") - val log = unbuilder.readField[xsbti.Logger]("log") - val updateOptions = unbuilder.readField[sbt.librarymanagement.UpdateOptions]("updateOptions") - val paths = unbuilder.readField[sbt.internal.librarymanagement.IvyPaths]("paths") + val log = unbuilder.readField[Option[xsbti.Logger]]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") + val paths = unbuilder.readField[Option[sbt.librarymanagement.ivy.IvyPaths]]("paths") val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") val moduleConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ModuleConfiguration]]("moduleConfigurations") @@ -23,15 +22,14 @@ implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.internal.librarym val managedChecksums = unbuilder.readField[Boolean]("managedChecksums") val resolutionCacheDir = unbuilder.readField[Option[java.io.File]]("resolutionCacheDir") unbuilder.endObject() - sbt.internal.librarymanagement.InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + sbt.librarymanagement.ivy.InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.internal.librarymanagement.InlineIvyConfiguration, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.ivy.InlineIvyConfiguration, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("lock", obj.lock) - builder.addField("baseDirectory", obj.baseDirectory) builder.addField("log", obj.log) builder.addField("updateOptions", obj.updateOptions) builder.addField("paths", obj.paths) diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala new file mode 100644 index 000000000..cfc5e6448 --- /dev/null +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala @@ -0,0 +1,28 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.ivy +abstract class IvyConfiguration( + val lock: Option[xsbti.GlobalLock], + val log: Option[xsbti.Logger], + val updateOptions: sbt.librarymanagement.ivy.UpdateOptions) extends Serializable { + + def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions()) + + + override def equals(o: Any): Boolean = o match { + case x: IvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (17 + "IvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + } + override def toString: String = { + "IvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ")" + } +} +object IvyConfiguration { + +} diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala new file mode 100644 index 000000000..1b27eaeaf --- /dev/null +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala @@ -0,0 +1,11 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.ivy + +import _root_.sjsonnew.JsonFormat +trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ivy.InlineIvyConfigurationFormats with sbt.librarymanagement.ivy.ExternalIvyConfigurationFormats => +implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.IvyConfiguration] = flatUnionFormat2[sbt.librarymanagement.ivy.IvyConfiguration, sbt.librarymanagement.ivy.InlineIvyConfiguration, sbt.librarymanagement.ivy.ExternalIvyConfiguration]("type") +} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala similarity index 97% rename from librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala rename to ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index 0a5fd35ae..ca3b51086 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -3,7 +3,7 @@ */ // DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement +package sbt.librarymanagement.ivy final class IvyPaths private ( val baseDirectory: java.io.File, val ivyHome: Option[java.io.File]) extends Serializable { diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala similarity index 67% rename from librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala rename to ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala index 506047e1e..7c48da84f 100644 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyPathsFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala @@ -3,23 +3,23 @@ */ // DO NOT EDIT MANUALLY -package sbt.librarymanagement +package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait IvyPathsFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val IvyPathsFormat: JsonFormat[sbt.internal.librarymanagement.IvyPaths] = new JsonFormat[sbt.internal.librarymanagement.IvyPaths] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.IvyPaths = { +implicit lazy val IvyPathsFormat: JsonFormat[sbt.librarymanagement.ivy.IvyPaths] = new JsonFormat[sbt.librarymanagement.ivy.IvyPaths] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.IvyPaths = { jsOpt match { case Some(js) => unbuilder.beginObject(js) val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") val ivyHome = unbuilder.readField[Option[java.io.File]]("ivyHome") unbuilder.endObject() - sbt.internal.librarymanagement.IvyPaths(baseDirectory, ivyHome) + sbt.librarymanagement.ivy.IvyPaths(baseDirectory, ivyHome) case None => deserializationError("Expected JsObject but found None") } } - override def write[J](obj: sbt.internal.librarymanagement.IvyPaths, builder: Builder[J]): Unit = { + override def write[J](obj: sbt.librarymanagement.ivy.IvyPaths, builder: Builder[J]): Unit = { builder.beginObject() builder.addField("baseDirectory", obj.baseDirectory) builder.addField("ivyHome", obj.ivyHome) diff --git a/ivy/src/main/contraband/lm-ivy.json b/ivy/src/main/contraband/lm-ivy.json new file mode 100644 index 000000000..dc239f8d8 --- /dev/null +++ b/ivy/src/main/contraband/lm-ivy.json @@ -0,0 +1,144 @@ +{ + "codecNamespace": "sbt.librarymanagement.ivy", + "types": [ + { + "name": "IvyConfiguration", + "namespace": "sbt.librarymanagement.ivy", + "target": "Scala", + "type": "interface", + "fields": [ + { + "name": "lock", + "type": "xsbti.GlobalLock?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "log", + "type": "xsbti.Logger?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "updateOptions", + "type": "sbt.librarymanagement.ivy.UpdateOptions", + "default": "sbt.librarymanagement.ivy.UpdateOptions()", + "since": "0.0.1" + } + ], + "types": [ + { + "name": "InlineIvyConfiguration", + "namespace": "sbt.librarymanagement.ivy", + "target": "Scala", + "type": "record", + "fields": [ + { + "name": "paths", + "type": "sbt.librarymanagement.ivy.IvyPaths?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "resolvers", + "type": "sbt.librarymanagement.Resolver*", + "default": "sbt.librarymanagement.Resolver.defaults", + "since": "0.0.1" + }, + { + "name": "otherResolvers", + "type": "sbt.librarymanagement.Resolver*", + "default": "Vector.empty", + "since": "0.0.1" + }, + { + "name": "moduleConfigurations", + "type": "sbt.librarymanagement.ModuleConfiguration*", + "default": "Vector.empty", + "since": "0.0.1" + }, + { + "name": "checksums", + "type": "String*", + "default": "sbt.librarymanagement.ivy.IvyDefaults.defaultChecksums", + "since": "0.0.1" + }, + { + "name": "managedChecksums", + "type": "Boolean", + "default": "false", + "since": "0.0.1" + }, + { + "name": "resolutionCacheDir", + "type": "java.io.File?", + "default": "None", + "since": "0.0.1" + } + ], + "extraCompanion": [ + "/** Provided for backward compatibility. */", + "def apply(", + " paths: sbt.librarymanagement.ivy.IvyPaths,", + " resolvers: Vector[sbt.librarymanagement.Resolver],", + " otherResolvers: Vector[sbt.librarymanagement.Resolver],", + " moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration],", + " lock: Option[xsbti.GlobalLock],", + " checksums: Vector[String],", + " managedChecksums: Boolean,", + " resolutionCacheDir: Option[java.io.File],", + " updateOptions: sbt.librarymanagement.ivy.UpdateOptions,", + " log: xsbti.Logger", + "): InlineIvyConfiguration = {", + " apply()", + " .withLock(lock)", + " .withResolvers(resolvers)", + " .withOtherResolvers(otherResolvers)", + " .withModuleConfigurations(moduleConfigurations)", + " .withChecksums(checksums)", + " .withManagedChecksums(managedChecksums)", + " .withResolutionCacheDir(resolutionCacheDir)", + " .withLog(log)", + "}" + ] + }, + { + "name": "ExternalIvyConfiguration", + "namespace": "sbt.librarymanagement.ivy", + "target": "Scala", + "type": "record", + "fields": [ + { + "name": "baseDirectory", + "type": "java.io.File?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "uri", + "type": "java.net.URI?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "extraResolvers", + "type": "sbt.librarymanagement.Resolver*", + "default": "Vector()", + "since": "0.0.1" + } + ] + } + ] + }, + { + "name": "IvyPaths", + "namespace": "sbt.librarymanagement.ivy", + "target": "Scala", + "type": "record", + "fields": [ + { "name": "baseDirectory", "type": "java.io.File" }, + { "name": "ivyHome", "type": "java.io.File?" } + ] + } + ] +} diff --git a/librarymanagement/src/main/java/sbt/internal/librarymanagement/ResolverAdapter.java b/ivy/src/main/java/internal/librarymanagement/ResolverAdapter.java similarity index 100% rename from librarymanagement/src/main/java/sbt/internal/librarymanagement/ResolverAdapter.java rename to ivy/src/main/java/internal/librarymanagement/ResolverAdapter.java diff --git a/librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala similarity index 100% rename from librarymanagement/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala rename to ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 244d86c62..a973f59e1 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -31,7 +31,7 @@ class ComponentManager( def fromGlobal = lockGlobalCache { try { update(id); getOrElse(createAndCache) } catch { - case e: NotInCache => createAndCache + case _: NotInCache => createAndCache } } def getOrElse(orElse: => Iterable[File]): Iterable[File] = { diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index c81bd80a8..f31d223d3 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -37,6 +37,7 @@ import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } import sbt.io.IO import sbt.util.Logger import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.UpdateOptions private[sbt] object ConvertResolver { import UpdateOptions.ResolverConverter @@ -225,7 +226,10 @@ private[sbt] object ConvertResolver { } case repo: ChainedResolver => IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) - case repo: RawRepository => repo.resolver + case repo: RawRepository => + repo.resolver match { + case r: DependencyResolver => r + } } } diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala similarity index 92% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index c01576336..86c1ef5f2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -37,7 +37,10 @@ import org.apache.ivy.util.url._ import scala.xml.NodeSeq import scala.collection.mutable import sbt.util.Logger -import sbt.librarymanagement._ +import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } +import sbt.librarymanagement.ivy._ +import sbt.librarymanagement.syntax._ +import IvyInternalDefaults._ import Resolver.PluginPattern import ivyint.{ CachedResolutionResolveCache, @@ -48,8 +51,6 @@ import ivyint.{ } final class IvySbt(val configuration: IvyConfiguration) { self => - import configuration.baseDirectory - /* * ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. @@ -85,22 +86,26 @@ final class IvySbt(val configuration: IvyConfiguration) { self => private lazy val settings: IvySettings = { if (configuration.updateOptions.gigahorse) URLHandlerRegistry.setDefault(gigahorseUrlHandler) else URLHandlerRegistry.setDefault(basicUrlHandler) + val is = new IvySettings - is.setBaseDir(baseDirectory) is.setCircularDependencyStrategy( configuration.updateOptions.circularDependencyLevel.ivyStrategy ) CustomPomParser.registerDefault + val log = getLog(configuration.log) configuration match { case e: ExternalIvyConfiguration => - IvySbt.addResolvers(e.extraResolvers, is, configuration.log) - IvySbt.loadURI(is, e.uri) + val baseDirectory = getBaseDirectory(e.baseDirectory) + is.setBaseDir(baseDirectory) + IvySbt.addResolvers(e.extraResolvers, is, log) + IvySbt.loadURI(is, e.uri.getOrElse(sys.error("uri must be specified!"))) case i: InlineIvyConfiguration => + val paths = getIvyPaths(i.paths) + is.setBaseDir(paths.baseDirectory) is.setVariable("ivy.checksums", i.checksums mkString ",") is.setVariable(ConvertResolver.ManagedChecksums, i.managedChecksums.toString) - i.paths.ivyHome foreach is.setDefaultIvyUserDir - val log = configuration.log + paths.ivyHome foreach is.setDefaultIvyUserDir IvySbt.configureCache(is, i.resolutionCacheDir) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, configuration.updateOptions, log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, log) @@ -157,7 +162,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => val ivy = new IvyImplementation() ivy.setSettings(settings) ivy.bind() - val logger = new IvyLoggerInterface(configuration.log) + val logger = new IvyLoggerInterface(getLog(configuration.log)) ivy.getLoggerEngine.pushLogger(logger) ivy } @@ -194,8 +199,26 @@ final class IvySbt(val configuration: IvyConfiguration) { self => else IvySbt.cachedResolutionResolveCache.clean() } - final class Module(rawModuleSettings: ModuleSettings) { + final class Module(rawModuleSettings: ModuleSettings) + extends sbt.librarymanagement.ModuleDescriptor { self => val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) + + def directDependencies: Vector[ModuleID] = + moduleSettings match { + case x: InlineConfiguration => x.dependencies + case _ => Vector() + } + + def configurations = + moduleSettings match { + case ic: InlineConfiguration => ic.configurations + case _: PomConfiguration => Configurations.default ++ Configurations.defaultInternal + case _: IvyFileConfiguration => + Configurations.default ++ Configurations.defaultInternal + } + + def scalaModuleInfo: Option[ScalaModuleInfo] = moduleSettings.scalaModuleInfo + def owner = IvySbt.this def withModule[T](log: Logger)(f: (Ivy, DefaultModuleDescriptor, String) => T): T = withIvy[T](log) { ivy => @@ -213,22 +236,17 @@ final class IvySbt(val configuration: IvyConfiguration) { self => private[this] lazy val (moduleDescriptor0: DefaultModuleDescriptor, defaultConfig0: String) = { val (baseModule, baseConfiguration) = moduleSettings match { - case ic: InlineConfiguration => configureInline(ic, configuration.log) + case ic: InlineConfiguration => configureInline(ic, getLog(configuration.log)) case pc: PomConfiguration => configurePom(pc) case ifc: IvyFileConfiguration => configureIvyFile(ifc) } - val configs = - moduleSettings match { - case ic: InlineConfiguration => ic.configurations - case pc: PomConfiguration => Configurations.default ++ Configurations.defaultInternal - case ifc: IvyFileConfiguration => - Configurations.default ++ Configurations.defaultInternal - } - moduleSettings.ivyScala match { + val configs = configurations + moduleSettings.scalaModuleInfo match { case Some(is) => val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } - IvyScala.checkModule(baseModule, baseConfiguration, svc, configuration.log)(is) + IvyScalaUtil.checkModule(baseModule, baseConfiguration, svc, getLog(configuration.log))( + is) case _ => // do nothing } IvySbt.addExtraNamespace(baseModule) @@ -236,7 +254,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } private def configureInline(ic: InlineConfiguration, log: Logger) = { import ic._ - val moduleID = newConfiguredModuleID(module, moduleInfo, configurations) + val moduleID = newConfiguredModuleID(module, moduleInfo, ic.configurations) IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) val defaultConf = defaultConfiguration getOrElse Configuration.of( "Default", @@ -255,7 +273,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => ) IvySbt.addMainArtifact(moduleID) IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) - IvySbt.addExcludes(moduleID, excludes, ivyScala) + IvySbt.addExcludes(moduleID, excludes, ic.scalaModuleInfo) val transformedDeps = IvySbt.overrideDirect(dependencies, overrides) IvySbt.addDependencies(moduleID, transformedDeps, parser) (moduleID, parser.getDefaultConf) @@ -285,7 +303,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => val dmd = IvySbt.toDefaultModuleDescriptor(md) IvySbt.addConfigurations(dmd, Configurations.defaultInternal) val defaultConf = Configurations.DefaultMavenConfiguration.name - for (is <- pc.ivyScala) if (pc.autoScalaTools) { + for (is <- pc.scalaModuleInfo) if (pc.autoScalaTools) { val confParser = new CustomXmlParser.CustomParser(settings, Some(defaultConf)) confParser.setMd(dmd) addScalaToolDependencies(dmd, confParser, is) @@ -300,7 +318,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => parser.setSource(toURL(ifc.file)) parser.parse() val dmd = IvySbt.toDefaultModuleDescriptor(parser.getModuleDescriptor()) - for (is <- ifc.ivyScala) + for (is <- ifc.scalaModuleInfo) if (ifc.autoScalaTools) addScalaToolDependencies(dmd, parser, is) (dmd, parser.getDefaultConf) @@ -308,7 +326,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => private def addScalaToolDependencies( dmd: DefaultModuleDescriptor, parser: CustomXmlParser.CustomParser, - is: IvyScala + is: ScalaModuleInfo ): Unit = { IvySbt.addConfigurations(dmd, Configurations.ScalaTool :: Nil) IvySbt.addDependencies( @@ -325,7 +343,7 @@ private[sbt] object IvySbt { val DefaultIvyConfigFilename = "ivysettings.xml" val DefaultIvyFilename = "ivy.xml" val DefaultMavenFilename = "pom.xml" - val DefaultChecksums = Vector("sha1", "md5") + val DefaultChecksums = IvyDefaults.defaultChecksums private[sbt] def cachedResolutionResolveCache: CachedResolutionResolveCache = new CachedResolutionResolveCache @@ -505,8 +523,8 @@ private[sbt] object IvySbt { } } private[this] def isProjectResolver(r: DependencyResolver): Boolean = r match { - case pr: ProjectResolver => true - case _ => false + case _: ProjectResolver => true + case _ => false } // ignore the original resolver wherever possible to avoid issues like #704 override def saveResolvers( @@ -573,7 +591,7 @@ private[sbt] object IvySbt { } private def substituteCross(m: ModuleSettings): ModuleSettings = { - m.ivyScala match { + m.scalaModuleInfo match { case None => m case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) } @@ -589,7 +607,7 @@ private[sbt] object IvySbt { val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) def propagateCrossVersion(moduleID: ModuleID): ModuleID = { val crossExclusions: Vector[ExclusionRule] = - moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.ivyScala)) + moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) applyCross(moduleID) .withExclusions(crossExclusions) } @@ -723,7 +741,7 @@ private[sbt] object IvySbt { (dependencies groupBy { dep => (dep.organization, dep.name, dep.configurations) }) foreach { - case (k, vs) if vs.size > 1 => + case (_, vs) if vs.size > 1 => val v0 = vs.head (vs find { _.revision != v0.revision }) foreach { v => out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }) @@ -826,7 +844,7 @@ private[sbt] object IvySbt { for (conf <- dependencyDescriptor.getModuleConfigurations) { dependencyDescriptor.addExcludeRule( conf, - IvyScala.excludeRule( + IvyScalaUtil.excludeRule( excls.organization, excls.name, excls.configurations map { _.name }, @@ -839,7 +857,7 @@ private[sbt] object IvySbt { for (conf <- dependencyDescriptor.getModuleConfigurations) { dependencyDescriptor.addIncludeRule( conf, - IvyScala.includeRule( + IvyScalaUtil.includeRule( incls.organization, incls.name, incls.configurations map { _.name }, @@ -868,24 +886,24 @@ private[sbt] object IvySbt { def addExcludes( moduleID: DefaultModuleDescriptor, excludes: Seq[ExclusionRule], - ivyScala: Option[IvyScala] - ): Unit = excludes.foreach(exclude => addExclude(moduleID, ivyScala)(exclude)) + scalaModuleInfo: Option[ScalaModuleInfo] + ): Unit = excludes.foreach(exclude => addExclude(moduleID, scalaModuleInfo)(exclude)) - def addExclude(moduleID: DefaultModuleDescriptor, ivyScala: Option[IvyScala])( + def addExclude(moduleID: DefaultModuleDescriptor, scalaModuleInfo: Option[ScalaModuleInfo])( exclude0: ExclusionRule): Unit = { // this adds _2.11 postfix - val exclude = CrossVersion.substituteCross(exclude0, ivyScala) + val exclude = CrossVersion.substituteCross(exclude0, scalaModuleInfo) val confs = if (exclude.configurations.isEmpty) moduleID.getConfigurationsNames.toList else exclude.configurations map { _.name } val excludeRule = - IvyScala.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) + IvyScalaUtil.excludeRule(exclude.organization, exclude.name, confs, exclude.artifact) moduleID.addExcludeRule(excludeRule) } def addOverrides( moduleID: DefaultModuleDescriptor, - overrides: Set[ModuleID], + overrides: Vector[ModuleID], matcher: PatternMatcher ): Unit = overrides foreach addOverride(moduleID, matcher) @@ -902,7 +920,7 @@ private[sbt] object IvySbt { * "IllegalStateException: impossible to get artifacts when data has not been loaded." * when a direct dependency is overridden with a newer version." */ - def overrideDirect(dependencies: Seq[ModuleID], overrides: Set[ModuleID]): Seq[ModuleID] = { + def overrideDirect(dependencies: Seq[ModuleID], overrides: Vector[ModuleID]): Seq[ModuleID] = { def key(id: ModuleID) = (id.organization, id.name) val overridden = overrides.map(id => (key(id), id.revision)).toMap dependencies map { dep => diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala similarity index 53% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index acc8849a5..25decece0 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -4,8 +4,6 @@ package sbt.internal.librarymanagement import java.io.File -import scala.xml.{ Node => XNode, NodeSeq } -import collection.mutable import ivyint.CachedResolutionResolveEngine import org.apache.ivy.Ivy @@ -18,73 +16,14 @@ import org.apache.ivy.core.module.descriptor.{ ModuleDescriptor, DefaultModuleDescriptor } -import org.apache.ivy.core.report.ResolveReport import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } +import org.apache.ivy.util.filter.{ Filter => IvyFilter } import sbt.io.{ IO, PathFinder } -import sbt.util.{ Logger, ShowLines } -import sbt.internal.util.{ SourcePosition, LinePosition, RangePosition, LineRange } -import sbt.librarymanagement._, syntax._ - -final class DeliverConfiguration( - val deliverIvyPattern: String, - val status: String, - val configurations: Option[Vector[Configuration]], - val logging: UpdateLogging -) -final class PublishConfiguration( - val ivyFile: Option[File], - val resolverName: String, - val artifacts: Map[Artifact, File], - val checksums: Vector[String], - val logging: UpdateLogging, - val overwrite: Boolean -) { - def this( - ivyFile: Option[File], - resolverName: String, - artifacts: Map[Artifact, File], - checksums: Vector[String], - logging: UpdateLogging - ) = - this(ivyFile, resolverName, artifacts, checksums, logging, false) -} - -final case class MakePomConfiguration( - file: File, - moduleInfo: ModuleInfo, - configurations: Option[Vector[Configuration]] = None, - extra: NodeSeq = NodeSeq.Empty, - process: XNode => XNode = n => n, - filterRepositories: MavenRepository => Boolean = _ => true, - allRepositories: Boolean, - includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType) -) - -/** @param exclude is a map from ModuleID to classifiers that were previously tried and failed, so should now be excluded */ -final case class GetClassifiersConfiguration( - module: GetClassifiersModule, - exclude: Map[ModuleID, Set[String]], - configuration: UpdateConfiguration, - ivyScala: Option[IvyScala], - sourceArtifactTypes: Set[String], - docArtifactTypes: Set[String] -) -final case class GetClassifiersModule( - id: ModuleID, - modules: Vector[ModuleID], - configurations: Vector[Configuration], - classifiers: Vector[String] -) - -final class UnresolvedWarningConfiguration private[sbt] ( - val modulePositions: Map[ModuleID, SourcePosition] -) -object UnresolvedWarningConfiguration { - def apply(): UnresolvedWarningConfiguration = apply(Map()) - def apply(modulePositions: Map[ModuleID, SourcePosition]): UnresolvedWarningConfiguration = - new UnresolvedWarningConfiguration(modulePositions) -} +import sbt.util.Logger +import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ }, syntax._ +import InternalDefaults._ +import UpdateClassifiersUtil._ object IvyActions { @@ -117,7 +56,7 @@ object IvyActions { } /** Creates a Maven pom from the given Ivy configuration*/ - def makePom(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): Unit = { + def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = { import configuration.{ allRepositories, moduleInfo, @@ -142,29 +81,55 @@ object IvyActions { file ) log.info("Wrote " + file.getAbsolutePath) + file } } - def deliver(module: IvySbt#Module, configuration: DeliverConfiguration, log: Logger): File = { - import configuration._ + def deliver(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger): File = { + val deliverIvyPattern = configuration.deliverIvyPattern + .getOrElse(sys.error("deliverIvyPattern must be specified.")) + val status = getDeliverStatus(configuration.status) module.withModule(log) { - case (ivy, md, default) => + case (ivy, md, _) => val revID = md.getModuleRevisionId val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(IvySbt.getConfigurations(md, configurations)) + options.setConfs(getConfigurations(md, configuration.configurations)) ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) deliveredFile(ivy, deliverIvyPattern, md) } } + + def getConfigurations( + module: ModuleDescriptor, + configurations: Option[Vector[ConfigRef]] + ): Array[String] = + configurations match { + case Some(confs) => (confs map { _.name }).toArray + case None => module.getPublicConfigurationsNames + } + def deliveredFile(ivy: Ivy, pattern: String, md: ModuleDescriptor): File = ivy.getSettings.resolveFile( IvyPatternHelper.substitute(pattern, md.getResolvedModuleRevisionId) ) def publish(module: IvySbt#Module, configuration: PublishConfiguration, log: Logger): Unit = { - import configuration._ + val resolverName = configuration.resolverName match { + case Some(x) => x + case _ => sys.error("Resolver name is not specified") + } + + // Todo. Fix publish ordering https://github.com/sbt/sbt/issues/2088#issuecomment-246208872 + val ivyFile: Option[File] = + if (configuration.publishMavenStyle) None + else { + Option(deliver(module, configuration, log)) + } + + val artifacts = Map(configuration.artifacts: _*) + val checksums = configuration.checksums module.withModule(log) { - case (ivy, md, default) => + case (ivy, md, _) => val resolver = ivy.getSettings.getResolver(resolverName) if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") val ivyArtifact = ivyFile map { file => @@ -172,7 +137,9 @@ object IvyActions { } val cross = crossVersionMap(module.moduleSettings) val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList - withChecksums(resolver, checksums) { publish(md, as, resolver, overwrite = overwrite) } + withChecksums(resolver, checksums) { + publish(md, as, resolver, overwrite = configuration.overwrite) + } } } private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])( @@ -188,7 +155,7 @@ object IvyActions { } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { - case i: InlineConfiguration => CrossVersion(i.module, i.ivyScala) + case i: InlineConfiguration => CrossVersion(i.module, i.scalaModuleInfo) case _ => None } def mapArtifacts( @@ -210,8 +177,6 @@ object IvyActions { * @param module The module to be resolved. * @param configuration The update configuration. * @param uwconfig The configuration to handle unresolved warnings. - * @param logicalClock The clock necessary to cache ivy. - * @param depDir The base directory used for caching resolution. * @param log The logger. * @return The result, either an unresolved warning or an update report. Note that this * update report will or will not be successful depending on the `missingOk` option. @@ -220,8 +185,6 @@ object IvyActions { module: IvySbt#Module, configuration: UpdateConfiguration, uwconfig: UnresolvedWarningConfiguration, - logicalClock: LogicalClock, - depDir: Option[File], log: Logger ): Either[UnresolvedWarning, UpdateReport] = { module.withModule(log) { @@ -230,21 +193,27 @@ object IvyActions { val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) iw.foreach(log.warn(_)) + val metadataDirectory = configuration.metadataDirectory + // Create inputs, resolve and retrieve the module descriptor val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) val resolutionResult: Either[ResolveException, UpdateReport] = { - if (module.owner.configuration.updateOptions.cachedResolution && depDir.isDefined) { - val cache = depDir.getOrElse(sys.error("Missing directory for cached resolution.")) - cachedResolveAndRetrieve(inputs, logicalClock, cache) + if (module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined) { + val cache = + metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) + cachedResolveAndRetrieve(inputs, cache) } else resolveAndRetrieve(inputs, defaultConf) } // Convert to unresolved warning or retrieve update report resolutionResult.fold( exception => Left(UnresolvedWarning(exception, uwconfig)), - updateReport => { - val retrieveConf = configuration.retrieve - Right(retrieveConf.map(retrieve(log, ivy, updateReport, _)).getOrElse(updateReport)) + ur0 => { + val ur = configuration.retrieveManaged match { + case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) + case _ => ur0 + } + Right(ur) } ) } @@ -264,138 +233,6 @@ object IvyActions { def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = mods groupBy (grouping) mapValues (_.map(_.revision).toSet) - private[sbt] def transitiveScratch( - ivySbt: IvySbt, - label: String, - config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, - logicalClock: LogicalClock, - depDir: Option[File], - log: Logger - ): UpdateReport = { - import config.{ configuration => c, ivyScala, module => mod } - import mod.{ id, modules => deps } - val base = restrictedCopy(id, true).withName(id.name + "$" + label) - val module = - new ivySbt.Module(InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps)) - val report = updateEither(module, c, uwconfig, logicalClock, depDir, log) match { - case Right(r) => r - case Left(w) => - throw w.resolveException - } - val newConfig = config.copy(module = mod.copy(modules = report.allModules)) - updateClassifiers(ivySbt, newConfig, uwconfig, logicalClock, depDir, Vector(), log) - } - - /** - * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This - * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy - * that sbt generates for them either.
- * Artifacts can be obtained from calling toSeq on UpdateReport.
- * In addition, retrieves specific Ivy artifacts if they have one of the requested `config.configuration.types`. - * @param config important to set `config.configuration.types` to only allow artifact types that can correspond to - * "classified" artifacts (sources and javadocs). - */ - private[sbt] def updateClassifiers( - ivySbt: IvySbt, - config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, - logicalClock: LogicalClock, - depDir: Option[File], - artifacts: Vector[(String, ModuleID, Artifact, File)], - log: Logger - ): UpdateReport = { - import config.{ configuration => c, module => mod, _ } - import mod.{ configurations => confs, _ } - assert(classifiers.nonEmpty, "classifiers cannot be empty") - assert(c.artifactFilter.types.nonEmpty, "UpdateConfiguration must filter on some types") - val baseModules = modules map { m => - restrictedCopy(m, true) - } - // Adding list of explicit artifacts here. - val deps = baseModules.distinct flatMap classifiedArtifacts(classifiers, exclude, artifacts) - val base = restrictedCopy(id, true).withName(id.name + classifiers.mkString("$", "_", "")) - val module = new ivySbt.Module( - InlineConfiguration(false, ivyScala, base, ModuleInfo(base.name), deps) - .withConfigurations(confs) - ) - // c.copy ensures c.types is preserved too - val upConf = c.withMissingOk(true) - updateEither(module, upConf, uwconfig, logicalClock, depDir, log) match { - case Right(r) => - // The artifacts that came from Ivy don't have their classifier set, let's set it according to - // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They - val typeClassifierMap: Map[String, String] = - ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) - :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap - r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { - case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f - } - } - case Left(w) => - throw w.resolveException - } - } - // This version adds explicit artifact - private[sbt] def classifiedArtifacts( - classifiers: Vector[String], - exclude: Map[ModuleID, Set[String]], - artifacts: Vector[(String, ModuleID, Artifact, File)] - )(m: ModuleID): Option[ModuleID] = { - def sameModule(m1: ModuleID, m2: ModuleID): Boolean = - m1.organization == m2.organization && m1.name == m2.name && m1.revision == m2.revision - def explicitArtifacts = { - val arts = (artifacts collect { - case (_, x, art, _) if sameModule(m, x) && art.classifier.isDefined => art - }).distinct - if (arts.isEmpty) None - else Some(intransitiveModuleWithExplicitArts(m, arts)) - } - def hardcodedArtifacts = classifiedArtifacts(classifiers, exclude)(m) - explicitArtifacts orElse hardcodedArtifacts - } - private def classifiedArtifacts( - classifiers: Vector[String], - exclude: Map[ModuleID, Set[String]] - )(m: ModuleID): Option[ModuleID] = { - val excluded = exclude getOrElse (restrictedCopy(m, false), Set.empty) - val included = classifiers filterNot excluded - if (included.isEmpty) None - else { - Some( - intransitiveModuleWithExplicitArts( - module = m, - arts = classifiedArtifacts(m.name, included) - ) - ) - } - } - - /** - * Explicitly set an "include all" rule (the default) because otherwise, if we declare ANY explicitArtifacts, - * [[org.apache.ivy.core.resolve.IvyNode#getArtifacts]] (in Ivy 2.3.0-rc1) will not merge in the descriptor's - * artifacts and will only keep the explicitArtifacts. - *
- * Look for the comment saying {{{ - * // and now we filter according to include rules - * }}} - * in `IvyNode`, which iterates on `includes`, which will ordinarily be empty because higher up, in {{{ - * addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf)); - * }}} - * `usage.getDependencyIncludesSet` returns null if there are no (explicit) include rules. - */ - private def intransitiveModuleWithExplicitArts( - module: ModuleID, - arts: Vector[Artifact] - ): ModuleID = - module - .withIsTransitive(false) - .withExplicitArtifacts(arts) - .withInclusions(Vector(InclExclRule.everything)) - def addExcluded( report: UpdateReport, classifiers: Vector[String], @@ -404,10 +241,7 @@ object IvyActions { report.addMissing { id => classifiedArtifacts(id.name, classifiers filter getExcluded(id, exclude)) } - def classifiedArtifacts(name: String, classifiers: Vector[String]): Vector[Artifact] = - classifiers map { c => - Artifact.classified(name, c) - } + private[this] def getExcluded(id: ModuleID, exclude: Map[ModuleID, Set[String]]): Set[String] = exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) @@ -419,13 +253,6 @@ object IvyActions { } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } - private[this] def restrictedCopy(m: ModuleID, confs: Boolean) = - ModuleID(m.organization, m.name, m.revision) - .withCrossVersion(m.crossVersion) - .withExtraAttributes(m.extraAttributes) - .withConfigurations(if (confs) m.configurations else None) - .branch(m.branchName) - /** * Represents the inputs to pass in to [[resolveAndRetrieve]] and [[cachedResolveAndRetrieve]]. * @@ -441,6 +268,15 @@ object IvyActions { log: Logger ) + implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { + override def accept(o: Object): Boolean = Option(o) exists { + case a: IArtifact => applyFilter(f, a) + } + + def applyFilter(f: ArtifactTypeFilter, a: IArtifact): Boolean = + (f.types contains a.getType) ^ f.inverted + } + /** * Defines the internal entrypoint of module resolution and retrieval. * @@ -462,14 +298,15 @@ object IvyActions { val ivyInstance = inputs.ivy val moduleDescriptor = inputs.module val updateConfiguration = inputs.updateConfiguration - val logging = updateConfiguration.logging val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(moduleDescriptor) + val artifactFilter = getArtifactTypeFilter(updateConfiguration.artifactFilter) + import updateConfiguration._ resolveOptions.setResolveId(resolveId) - resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) - resolveOptions.setUseCacheOnly(updateConfiguration.offline) + resolveOptions.setArtifactFilter(artifactFilter) + resolveOptions.setUseCacheOnly(offline) resolveOptions.setLog(ivyLogLevel(logging)) - if (updateConfiguration.frozen) { + if (frozen) { resolveOptions.setTransitive(false) resolveOptions.setCheckIfChanged(false) } @@ -480,7 +317,7 @@ object IvyActions { ) val resolveReport = ivyInstance.resolve(moduleDescriptor, resolveOptions) - if (resolveReport.hasError && !inputs.updateConfiguration.missingOk) { + if (resolveReport.hasError && !missingOk) { // If strict error, collect report information and generated UnresolvedWarning val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct val failedPaths = resolveReport.getUnresolvedDependencies.map { node => @@ -513,7 +350,6 @@ object IvyActions { */ private[this] def cachedResolveAndRetrieve( inputs: ResolutionInputs, - logicalClock: LogicalClock, cache: File ): Either[ResolveException, UpdateReport] = { val log = inputs.log @@ -522,16 +358,22 @@ object IvyActions { val resolver = inputs.ivy.getResolveEngine.asInstanceOf[CachedResolutionResolveEngine] val resolveOptions = new ResolveOptions val resolveId = ResolveOptions.getDefaultResolveId(descriptor) + val artifactFilter = getArtifactTypeFilter(updateConfiguration.artifactFilter) + import updateConfiguration._ resolveOptions.setResolveId(resolveId) - resolveOptions.setArtifactFilter(updateConfiguration.artifactFilter) - resolveOptions.setUseCacheOnly(updateConfiguration.offline) - resolveOptions.setLog(ivyLogLevel(updateConfiguration.logging)) - if (updateConfiguration.frozen) { + resolveOptions.setArtifactFilter(artifactFilter) + resolveOptions.setUseCacheOnly(offline) + resolveOptions.setLog(ivyLogLevel(logging)) + if (frozen) { resolveOptions.setTransitive(false) resolveOptions.setCheckIfChanged(false) } - val acceptError = updateConfiguration.missingOk - resolver.customResolve(descriptor, acceptError, logicalClock, resolveOptions, cache, log) + resolver.customResolve(descriptor, + missingOk, + updateConfiguration.logicalClock, + resolveOptions, + cache, + log) } private def retrieve( @@ -541,15 +383,15 @@ object IvyActions { config: RetrieveConfiguration ): UpdateReport = { val copyChecksums = ivy.getVariable(ConvertResolver.ManagedChecksums).toBoolean - val toRetrieve: Option[Set[ConfigRef]] = config.configurationsToRetrieve - val base = config.retrieveDirectory - val pattern = config.outputPattern + val toRetrieve: Option[Vector[ConfigRef]] = config.configurationsToRetrieve + val base = getRetrieveDirectory(config.retrieveDirectory) + val pattern = getRetrievePattern(config.outputPattern) val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf: ConfigRef, mid, art, cached) => toRetrieve match { case None => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) - case Some(refs) if refs(conf) => + case Some(refs) if refs contains conf => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) case _ => cached } @@ -656,83 +498,10 @@ object IvyActions { } } private[this] def checkFilesPresent(artifacts: Seq[(IArtifact, File)]): Unit = { - val missing = artifacts filter { case (a, file) => !file.exists } + val missing = artifacts filter { case (_, file) => !file.exists } if (missing.nonEmpty) sys.error( "Missing files for publishing:\n\t" + missing.map(_._2.getAbsolutePath).mkString("\n\t") ) } } - -private[sbt] final class ResolveException( - val messages: Seq[String], - val failed: Seq[ModuleID], - val failedPaths: Map[ModuleID, Seq[ModuleID]] -) extends RuntimeException(messages.mkString("\n")) { - def this(messages: Seq[String], failed: Seq[ModuleID]) = - this(messages, failed, Map(failed map { m => - m -> Nil - }: _*)) -} - -/** - * Represents unresolved dependency warning, which displays reconstructed dependency tree - * along with source position of each node. - */ -final class UnresolvedWarning private[sbt] ( - val resolveException: ResolveException, - val failedPaths: Seq[Seq[(ModuleID, Option[SourcePosition])]] -) -object UnresolvedWarning { - private[sbt] def apply( - err: ResolveException, - config: UnresolvedWarningConfiguration - ): UnresolvedWarning = { - def modulePosition(m0: ModuleID): Option[SourcePosition] = - config.modulePositions.find { - case (m, p) => - (m.organization == m0.organization) && - (m0.name startsWith m.name) && - (m.revision == m0.revision) - } map { - case (m, p) => p - } - val failedPaths = err.failed map { x: ModuleID => - err.failedPaths(x).toList.reverse map { id => - (id, modulePosition(id)) - } - } - new UnresolvedWarning(err, failedPaths) - } - - private[sbt] def sourcePosStr(posOpt: Option[SourcePosition]): String = - posOpt match { - case Some(LinePosition(path, start)) => s" ($path#L$start)" - case Some(RangePosition(path, LineRange(start, end))) => s" ($path#L$start-$end)" - case _ => "" - } - implicit val unresolvedWarningLines: ShowLines[UnresolvedWarning] = ShowLines { a => - val withExtra = a.resolveException.failed.filter(_.extraDependencyAttributes.nonEmpty) - val buffer = mutable.ListBuffer[String]() - if (withExtra.nonEmpty) { - buffer += "\n\tNote: Some unresolved dependencies have extra attributes. Check that these dependencies exist with the requested attributes." - withExtra foreach { id => - buffer += "\t\t" + id - } - } - if (a.failedPaths.nonEmpty) { - buffer += "\n\tNote: Unresolved dependencies path:" - a.failedPaths foreach { path => - if (path.nonEmpty) { - val head = path.head - buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) - path.tail foreach { - case (m, pos) => - buffer += "\t\t +- " + m.toString + sourcePosStr(pos) - } - } - } - } - buffer.toList - } -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala similarity index 96% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 9a0044aca..cdabbd94c 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -17,6 +17,7 @@ import org.apache.ivy.plugins.resolver.util.ResolvedResource import org.apache.ivy.util.FileUtil import sbt.io.Path import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.util.Logger import scalajson.ast.unsafe._ @@ -103,18 +104,11 @@ class IvyCache(val ivyHome: Option[File]) { private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal val paths = IvyPaths(new File("."), ivyHome) - val conf = new InlineIvyConfiguration( - paths, - Vector(local), - Vector.empty, - Vector.empty, - lock, - IvySbt.DefaultChecksums, - false, - None, - UpdateOptions(), - log - ) + val conf = InlineIvyConfiguration() + .withPaths(paths) + .withResolvers(Vector(local)) + .withLock(lock) + .withLog(log) (new IvySbt(conf), local) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala new file mode 100644 index 000000000..e2d558baf --- /dev/null +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala @@ -0,0 +1,28 @@ +package sbt +package internal.librarymanagement + +import java.io.File +import sbt.librarymanagement.ivy._ +import sbt.io.syntax._ +import xsbti.{ Logger => XLogger } +import sbt.util.Logger + +/** + * This is a list of functions with default values. + */ +object IvyInternalDefaults { + def defaultBaseDirectory: File = + (new File(".")).getAbsoluteFile / "lib_managed" + + def getBaseDirectory(opt: Option[File]): File = + opt.getOrElse(defaultBaseDirectory) + + def getLog(opt: Option[XLogger]): XLogger = + opt.getOrElse(Logger.Null) + + def defaultIvyPaths: IvyPaths = + IvyPaths(defaultBaseDirectory, None) + + def getIvyPaths(opt: Option[IvyPaths]): IvyPaths = + opt.getOrElse(defaultIvyPaths) +} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala similarity index 82% rename from librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 9d18c9dad..ed21d56ae 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/IvyScalaExtra.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -1,68 +1,28 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt.librarymanagement +package sbt.internal.librarymanagement import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.core.module.descriptor._ +import org.apache.ivy.core.module.descriptor.{ Configuration => _, _ } import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher import org.apache.ivy.plugins.namespace.NamespaceTransformer import sbt.util.Logger +import sbt.librarymanagement.ScalaArtifacts._ +import sbt.librarymanagement.{ ScalaModuleInfo, CrossVersion, Configuration } -object ScalaArtifacts { - val Organization = "org.scala-lang" - val LibraryID = "scala-library" - val CompilerID = "scala-compiler" - val ReflectID = "scala-reflect" - val ActorsID = "scala-actors" - val ScalapID = "scalap" - val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) - val DottyIDPrefix = "dotty" +object IvyScalaUtil { - def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" - - def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) - - private[sbt] def toolDependencies( - org: String, - version: String, - isDotty: Boolean = false - ): Seq[ModuleID] = - if (isDotty) - Seq( - ModuleID(org, DottyIDPrefix, version) - .withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) - .withCrossVersion(CrossVersion.binary) - ) - else - Seq( - scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version) - ) - - private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = - ModuleID(org, id, version).withConfigurations( - Some(Configurations.ScalaTool.name + "->default,optional(default)") - ) -} -object SbtArtifacts { - val Organization = "org.scala-sbt" -} - -import ScalaArtifacts._ - -private[sbt] abstract class IvyScalaFunctions { - - /** Performs checks/adds filters on Scala dependencies (if enabled in IvyScala). */ + /** Performs checks/adds filters on Scala dependencies (if enabled in ScalaModuleInfo). */ def checkModule( module: DefaultModuleDescriptor, conf: String, scalaVersionConfigs: Vector[String], log: Logger - )(check: IvyScala): Unit = { + )(check: ScalaModuleInfo): Unit = { if (check.checkExplicit) checkDependencies( module, @@ -98,7 +58,7 @@ private[sbt] abstract class IvyScalaFunctions { def dependeeQualifies: Boolean = dd.getParentRevisionId == null || ( dd.getParentRevisionId.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => + case _ @(CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => false case _ => true diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 3e30bf85b..3ec739e48 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -10,6 +10,7 @@ package sbt.internal.librarymanagement import java.io.File import sbt.util.Logger import sbt.librarymanagement._ +import Resolver._ import mavenint.PomExtraDependencyAttributes // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow @@ -259,7 +260,7 @@ class MakePom(val log: Logger) { types match { case Nil => Artifact.PomType case xs if xs.contains(Artifact.DefaultType) => Artifact.DefaultType - case x :: xs => x + case x :: (xs @ _) => x } } val IgnoreTypes: Set[String] = Set(Artifact.SourceType, Artifact.DocType, Artifact.PomType) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ProjectResolver.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index e6985e943..fa3846da2 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -158,7 +158,7 @@ private[sbt] class CachedResolutionResolveCache { def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { import scala.collection.JavaConverters._ md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { - case (k, v) => + case (k, _) => k.toString } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => @@ -209,7 +209,7 @@ private[sbt] class CachedResolutionResolveCache { else None) match { case Some(path) => log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = JsonUtil.parseUpdateReport(md, path, cachedDescriptor, log) + val ur = JsonUtil.parseUpdateReport( /* md, */ path, cachedDescriptor, log) if (ur.allFiles forall { _.exists }) { updateReportCache(md.getModuleRevisionId) = Right(ur) Some(Right(ur)) @@ -299,7 +299,7 @@ private[sbt] class CachedResolutionResolveCache { if (projectReportCache contains (mrid -> logicalClock)) projectReportCache((mrid, logicalClock)) else { - val oldKeys = projectReportCache.keys filter { case (x, clk) => clk != logicalClock } + val oldKeys = projectReportCache.keys filter { case (_, clk) => clk != logicalClock } projectReportCache --= oldKeys projectReportCache.getOrElseUpdate((mrid, logicalClock), f) } @@ -645,7 +645,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { OrganizationArtifactReport(oar.organization, oar.name, mrs) } allModules2(k) = oars - case (k, v) => // do nothing + case (_, _) => // do nothing } breakLoops(rest) @@ -757,7 +757,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { - case (k, xs) => xs.head + case (_, xs) => xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct xs.head diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CustomMavenResolver.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala similarity index 93% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 9a19ac6c1..78e1154dc 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -40,8 +40,8 @@ object ErrorMessageAuthenticator { } try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some(alreadyThere: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) + case Some(_: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) } catch { case t: Throwable => Message.debug( @@ -57,7 +57,7 @@ object ErrorMessageAuthenticator { def doInstall(original: Option[Authenticator]): Unit = try Authenticator.setDefault(new ErrorMessageAuthenticator(original)) catch { - case e: SecurityException if !securityWarningLogged => + case _: SecurityException if !securityWarningLogged => securityWarningLogged = true Message.warn( "Not enough permissions to set the ErrorMessageAuthenticator. " @@ -69,7 +69,7 @@ object ErrorMessageAuthenticator { // obtain it. If that doesn't work, assume there is no original authenticator def doInstallIfIvy(original: Option[Authenticator]): Unit = original match { - case Some(installed: ErrorMessageAuthenticator) => // Ignore, we're already installed + case Some(_: ErrorMessageAuthenticator) => // Ignore, we're already installed case Some(ivy: IvyAuthenticator) => installIntoIvy(ivy); () case original => doInstall(original) diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index ad6245055..d9f72ac18 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -21,6 +21,7 @@ import org.apache.ivy.plugins.resolver.util.{ HasLatestStrategy, ResolvedResourc import org.apache.ivy.util.{ Message, StringUtils => IvyStringUtils } import sbt.util.Logger import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.UpdateOptions import scala.util.control.NonFatal diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtDefaultDependencyDescriptor.scala diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala similarity index 100% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala rename to ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/CircularDependencyLevel.scala similarity index 98% rename from librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala rename to ivy/src/main/scala/sbt/librarymanagement/ivy/CircularDependencyLevel.scala index 4f1b53200..defba16b9 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/CircularDependencyLevel.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/CircularDependencyLevel.scala @@ -1,4 +1,5 @@ package sbt.librarymanagement +package ivy import org.apache.ivy.plugins.circular.{ CircularDependencyStrategy, diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala rename to ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 4044dfd3e..26ccc57f7 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -2,6 +2,7 @@ * Copyright 2009 Mark Harrah */ package sbt.librarymanagement +package ivy import java.io.File import org.apache.ivy.util.url.CredentialsStore diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDefaults.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDefaults.scala new file mode 100644 index 000000000..70028721f --- /dev/null +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDefaults.scala @@ -0,0 +1,9 @@ +package sbt +package librarymanagement.ivy + +/** + * This is a list of functions with default values. + */ +object IvyDefaults { + val defaultChecksums: Vector[String] = Vector("sha1", "md5") +} diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala new file mode 100644 index 000000000..5eee63a45 --- /dev/null +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala @@ -0,0 +1,30 @@ +package sbt +package librarymanagement +package ivy + +import sbt.internal.librarymanagement._ +import sbt.util.Logger + +class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryManagement { + type Module = ivySbt.Module + + override def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = { + new Module(moduleSetting) + } + + override def update(module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger): Either[UnresolvedWarning, UpdateReport] = + IvyActions.updateEither(toModule(module), configuration, uwconfig, log) + + private[sbt] def toModule(module: ModuleDescriptor): Module = + module match { + case m: Module => m + } +} + +object IvyLibraryManagement { + def apply(ivyConfiguration: IvyConfiguration): LibraryManagement = + new IvyLibraryManagement(new IvySbt(ivyConfiguration)) +} diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagementCodec.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagementCodec.scala new file mode 100644 index 000000000..68bbee4d6 --- /dev/null +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagementCodec.scala @@ -0,0 +1,17 @@ +package sbt.librarymanagement +package ivy + +trait IvyLibraryManagementCodec + extends sjsonnew.BasicJsonProtocol + with LibraryManagementCodec + with sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat + with IvyPathsFormats + with ResolverFormats + with ModuleConfigurationFormats + with InlineIvyConfigurationFormats + with ExternalIvyConfigurationFormats + with IvyConfigurationFormats + +object IvyLibraryManagementCodec extends IvyLibraryManagementCodec diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala new file mode 100644 index 000000000..323826fde --- /dev/null +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -0,0 +1,35 @@ +package sbt +package librarymanagement +package ivy + +import sbt.internal.librarymanagement._ +import sbt.util.Logger +import java.io.File + +class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends Publisher { + type Module = ivySbt.Module + + override def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = { + new Module(moduleSetting) + } + + override def makePomFile(module: ModuleDescriptor, + configuration: MakePomConfiguration, + log: Logger): File = + IvyActions.makePomFile(toModule(module), configuration, log) + + override def publish(module: ModuleDescriptor, + configuration: PublishConfiguration, + log: Logger): Unit = + IvyActions.publish(toModule(module), configuration, log) + + private[sbt] def toModule(module: ModuleDescriptor): Module = + module match { + case m: Module => m + } +} + +object IvyPublisher { + def apply(ivyConfiguration: IvyConfiguration): Publisher = + new IvyPublisher(new IvySbt(ivyConfiguration)) +} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala similarity index 99% rename from librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala rename to ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index bafbc3e4c..f09436e6b 100644 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -1,4 +1,5 @@ package sbt.librarymanagement +package ivy import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala similarity index 97% rename from librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala rename to ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala index c948a12c1..db0e83789 100644 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/UpdateOptionsFormat.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala @@ -1,4 +1,4 @@ -package sbt.internal.librarymanagement +package sbt.librarymanagement.ivy package formats import sjsonnew._ diff --git a/librarymanagement/src/test/resources/artifact1.jar b/ivy/src/test/resources/artifact1.jar similarity index 100% rename from librarymanagement/src/test/resources/artifact1.jar rename to ivy/src/test/resources/artifact1.jar diff --git a/librarymanagement/src/test/resources/artifact2.txt b/ivy/src/test/resources/artifact2.txt similarity index 100% rename from librarymanagement/src/test/resources/artifact2.txt rename to ivy/src/test/resources/artifact2.txt diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml b/ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml similarity index 100% rename from librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml rename to ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/ivys/ivy.xml diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar b/ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar similarity index 100% rename from librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar rename to ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/jars/libmodule.jar diff --git a/librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar b/ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar similarity index 100% rename from librarymanagement/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar rename to ivy/src/test/resources/test-ivy-repo/com.test/module-with-srcs/0.1.00/srcs/libmodule-source.jar diff --git a/librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar similarity index 100% rename from librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar rename to ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.jar diff --git a/librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom b/ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom similarity index 100% rename from librarymanagement/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom rename to ivy/src/test/resources/test-maven-repo/com/test/test-artifact/1.0.0-SNAPSHOT/test-artifact-1.0.0-SNAPSHOT.pom diff --git a/librarymanagement/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala similarity index 55% rename from librarymanagement/src/test/scala/BaseIvySpecification.scala rename to ivy/src/test/scala/BaseIvySpecification.scala index 5fa82c305..a4c1d4fda 100644 --- a/librarymanagement/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -6,6 +6,7 @@ import java.io.File import cross.CrossVersionUtil import sbt.internal.util.ConsoleLogger import sbt.librarymanagement._ +import sbt.librarymanagement.ivy._ import Configurations._ trait BaseIvySpecification extends UnitSpec { @@ -17,6 +18,8 @@ trait BaseIvySpecification extends UnitSpec { ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) lazy val log = ConsoleLogger() + def lmEngine(uo: UpdateOptions = UpdateOptions()): LibraryManagement = + IvyLibraryManagement(mkIvyConfiguration(uo)) def configurations = Vector(Compile, Test, Runtime) def module(moduleId: ModuleID, @@ -24,8 +27,8 @@ trait BaseIvySpecification extends UnitSpec { scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), overrideScalaVersion: Boolean = true): IvySbt#Module = { - val ivyScala = scalaFullVersion map { fv => - IvyScala( + val scalaModuleInfo = scalaFullVersion map { fv => + ScalaModuleInfo( scalaFullVersion = fv, scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), configurations = Vector.empty, @@ -35,60 +38,49 @@ trait BaseIvySpecification extends UnitSpec { ) } - val moduleSetting: ModuleSettings = InlineConfiguration( - false, - ivyScala, - module = moduleId, - moduleInfo = ModuleInfo("foo"), - dependencies = deps - ).withConfigurations(configurations) + val moduleSetting: ModuleSettings = ModuleDescriptorConfiguration(moduleId, ModuleInfo("foo")) + .withDependencies(deps) + .withConfigurations(configurations) + .withScalaModuleInfo(scalaModuleInfo) val ivySbt = new IvySbt(mkIvyConfiguration(uo)) new ivySbt.Module(moduleSetting) } - def resolvers: Vector[Resolver] = Vector(DefaultMavenRepository) + def resolvers: Vector[Resolver] = Vector(Resolver.mavenCentral) def chainResolver = ChainedResolver("sbt-chain", resolvers) def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { - val paths = IvyPaths(currentBase, Some(currentTarget)) - val other = Vector.empty - val check = Vector.empty - val managedChecksums = false val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" - new InlineIvyConfiguration(paths, - resolvers, - other, - moduleConfs, - None, - check, - managedChecksums, - Some(resCacheDir), - uo, - log) + InlineIvyConfiguration() + .withPaths(IvyPaths(currentBase, Some(currentTarget))) + .withResolvers(resolvers) + .withModuleConfigurations(moduleConfs) + .withChecksums(Vector.empty) + .withResolutionCacheDir(resCacheDir) + .withLog(log) + .withUpdateOptions(uo) } - def makeUpdateConfiguration(offline: Boolean): UpdateConfiguration = { - val retrieveConfig = - RetrieveConfiguration(currentManaged, Resolver.defaultRetrievePattern).withSync(false) - UpdateConfiguration(Some(retrieveConfig), - false, - UpdateLogging.Full, - ArtifactTypeFilter.forbid(Set("src", "doc")), - offline, - false) + def makeUpdateConfiguration(offline: Boolean, + metadataDirectory: Option[File]): UpdateConfiguration = { + val retrieveConfig = RetrieveConfiguration() + .withRetrieveDirectory(currentManaged) + .withOutputPattern(Resolver.defaultRetrievePattern) + .withSync(false) + + UpdateConfiguration() + .withRetrieveManaged(retrieveConfig) + .withLogging(UpdateLogging.Full) + .withOffline(offline) + .withMetadataDirectory(metadataDirectory) } def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { // IO.delete(currentTarget) - val config = makeUpdateConfiguration(false) - IvyActions.updateEither(module, - config, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - Some(currentDependency), - log) + val config = makeUpdateConfiguration(false, Some(currentDependency)) + IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), log) } def cleanIvyCache(): Unit = IO.delete(currentTarget / "cache") @@ -105,14 +97,11 @@ trait BaseIvySpecification extends UnitSpec { def mkPublishConfiguration(resolver: Resolver, artifacts: Map[Artifact, File]): PublishConfiguration = { - new PublishConfiguration( - ivyFile = None, - resolverName = resolver.name, - artifacts = artifacts, - checksums = Vector.empty, - logging = UpdateLogging.Full, - overwrite = true - ) + PublishConfiguration() + .withResolverName(resolver.name) + .withArtifacts(artifacts.toVector) + .withChecksums(Vector.empty) + .withOverwrite(true) } def ivyPublish(module: IvySbt#Module, config: PublishConfiguration) = { diff --git a/librarymanagement/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala similarity index 98% rename from librarymanagement/src/test/scala/CachedResolutionSpec.scala rename to ivy/src/test/scala/CachedResolutionSpec.scala index f00787fdf..ebab80288 100644 --- a/librarymanagement/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -2,6 +2,7 @@ package sbt.internal.librarymanagement import sbt.util.ShowLines import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.UpdateOptions class CachedResolutionSpec extends BaseIvySpecification { import ShowLines._ diff --git a/librarymanagement/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/ComponentManagerTest.scala similarity index 100% rename from librarymanagement/src/test/scala/ComponentManagerTest.scala rename to ivy/src/test/scala/ComponentManagerTest.scala diff --git a/librarymanagement/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala similarity index 100% rename from librarymanagement/src/test/scala/CrossVersionTest.scala rename to ivy/src/test/scala/CrossVersionTest.scala diff --git a/librarymanagement/src/test/scala/CustomPomParserTest.scala b/ivy/src/test/scala/CustomPomParserTest.scala similarity index 71% rename from librarymanagement/src/test/scala/CustomPomParserTest.scala rename to ivy/src/test/scala/CustomPomParserTest.scala index 488f683a8..97d5c54cb 100644 --- a/librarymanagement/src/test/scala/CustomPomParserTest.scala +++ b/ivy/src/test/scala/CustomPomParserTest.scala @@ -5,6 +5,7 @@ import org.apache.ivy.core.module.descriptor.{ Artifact => IvyArtifact } import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.resolve.ResolveOptions import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.io.IO.withTemporaryDirectory import sbt.internal.util.ConsoleLogger @@ -15,16 +16,10 @@ class CustomPomParserTest extends UnitSpec { val repoUrl = getClass.getResource("/test-maven-repo") val local = MavenRepository("Test Repo", repoUrl.toExternalForm) val paths = IvyPaths(new File("."), Some(cacheDir)) - val conf = new InlineIvyConfiguration(paths, - Vector(local), - Vector.empty, - Vector.empty, - None, - Vector("sha1", "md5"), - false, - None, - UpdateOptions(), - log) + val conf = InlineIvyConfiguration() + .withPaths(paths) + .withResolvers(Vector(local)) + .withLog(log) val ivySbt = new IvySbt(conf) val resolveOpts = new ResolveOptions().setConfs(Array("default")) val mrid = ModuleRevisionId.newInstance("com.test", "test-artifact", "1.0.0-SNAPSHOT") diff --git a/librarymanagement/src/test/scala/DMSerializationSpec.scala b/ivy/src/test/scala/DMSerializationSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/DMSerializationSpec.scala rename to ivy/src/test/scala/DMSerializationSpec.scala diff --git a/librarymanagement/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/EvictionWarningSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/EvictionWarningSpec.scala rename to ivy/src/test/scala/EvictionWarningSpec.scala diff --git a/librarymanagement/src/test/scala/FrozenModeSpec.scala b/ivy/src/test/scala/FrozenModeSpec.scala similarity index 84% rename from librarymanagement/src/test/scala/FrozenModeSpec.scala rename to ivy/src/test/scala/FrozenModeSpec.scala index e84abfe99..cd9a30799 100644 --- a/librarymanagement/src/test/scala/FrozenModeSpec.scala +++ b/ivy/src/test/scala/FrozenModeSpec.scala @@ -1,13 +1,13 @@ package sbt.librarymanagement +import sbt.librarymanagement.ivy.UpdateOptions import sbt.internal.librarymanagement._ -import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.librarymanagement.syntax._ -class FrozenModeSpec extends BaseIvySpecification with DependencyBuilders { +class FrozenModeSpec extends BaseIvySpecification { private final val targetDir = Some(currentDependency) - private final val onlineConf = makeUpdateConfiguration(false) - private final val frozenConf = makeUpdateConfiguration(false).withFrozen(true) - private final val noClock = LogicalClock.unknown + private final val onlineConf = makeUpdateConfiguration(false, targetDir) + private final val frozenConf = makeUpdateConfiguration(false, targetDir).withFrozen(true) private final val warningConf = UnresolvedWarningConfiguration() private final val normalOptions = UpdateOptions() @@ -29,7 +29,7 @@ class FrozenModeSpec extends BaseIvySpecification with DependencyBuilders { it should "fail when artifacts are missing in the cache" in { cleanIvyCache() def update(module: IvySbt#Module, conf: UpdateConfiguration) = - IvyActions.updateEither(module, conf, warningConf, noClock, targetDir, log) + IvyActions.updateEither(module, conf, warningConf, log) val toResolve = module(defaultModuleId, stoml, None, normalOptions) val onlineResolution = update(toResolve, onlineConf) diff --git a/librarymanagement/src/test/scala/InclExclSpec.scala b/ivy/src/test/scala/InclExclSpec.scala similarity index 84% rename from librarymanagement/src/test/scala/InclExclSpec.scala rename to ivy/src/test/scala/InclExclSpec.scala index c3a867550..62856f0c1 100644 --- a/librarymanagement/src/test/scala/InclExclSpec.scala +++ b/ivy/src/test/scala/InclExclSpec.scala @@ -2,9 +2,10 @@ package sbt.librarymanagement import org.scalatest.Assertion import sbt.internal.librarymanagement.BaseIvySpecification -import sbt.internal.librarymanagement.impl.{ DependencyBuilders, GroupArtifactID } +import sbt.librarymanagement.syntax._ +import DependencyBuilders.OrganizationArtifactName -class InclExclSpec extends BaseIvySpecification with DependencyBuilders { +class InclExclSpec extends BaseIvySpecification { def createLiftDep(toExclude: ExclusionRule): ModuleID = ("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile").excludeAll(toExclude) @@ -41,13 +42,13 @@ class InclExclSpec extends BaseIvySpecification with DependencyBuilders { } it should "exclude any version of lift-json with explicit Scala version" in { - val excluded: GroupArtifactID = "net.liftweb" % "lift-json_2.10" + val excluded: OrganizationArtifactName = "net.liftweb" % "lift-json_2.10" val report = getIvyReport(createLiftDep(excluded), scala210) testLiftJsonIsMissing(report) } it should "exclude any version of cross-built lift-json" in { - val excluded: GroupArtifactID = "net.liftweb" %% "lift-json" + val excluded: OrganizationArtifactName = "net.liftweb" %% "lift-json" val report = getIvyReport(createLiftDep(excluded), scala210) testLiftJsonIsMissing(report) } @@ -60,7 +61,7 @@ class InclExclSpec extends BaseIvySpecification with DependencyBuilders { } it should "exclude any version of lift-json when it's full cross version" in { - val excluded = new GroupArtifactID("net.liftweb", "lift-json", CrossVersion.full) + val excluded = new OrganizationArtifactName("net.liftweb", "lift-json", CrossVersion.full) val report = getIvyReport(createMetaDep(excluded), scala2122) testScalahostIsMissing(report) } diff --git a/librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/InconsistentDuplicateSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/InconsistentDuplicateSpec.scala rename to ivy/src/test/scala/InconsistentDuplicateSpec.scala diff --git a/librarymanagement/src/test/scala/MakePomSpec.scala b/ivy/src/test/scala/MakePomSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/MakePomSpec.scala rename to ivy/src/test/scala/MakePomSpec.scala diff --git a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala b/ivy/src/test/scala/MergeDescriptorSpec.scala similarity index 92% rename from librarymanagement/src/test/scala/MergeDescriptorSpec.scala rename to ivy/src/test/scala/MergeDescriptorSpec.scala index b435027bd..ded1a9f15 100644 --- a/librarymanagement/src/test/scala/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/MergeDescriptorSpec.scala @@ -2,6 +2,7 @@ package sbt.internal.librarymanagement import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor import sbt.librarymanagement._ +import sbt.librarymanagement.ivy.UpdateOptions import sbt.internal.librarymanagement.ivyint._ class MergeDescriptorSpec extends BaseIvySpecification { @@ -14,11 +15,11 @@ class MergeDescriptorSpec extends BaseIvySpecification { UpdateOptions() ) m.withModule(log) { - case (ivy, md, _) => + case (_, md, _) => val deps = md.getDependencies assert(deps.size == 1) deps.headOption.getOrElse(sys.error("Dependencies not found")) match { - case dd @ MergedDescriptors(dd0, dd1) => + case dd @ MergedDescriptors(_, _) => val arts = dd.getAllDependencyArtifacts val a0: DependencyArtifactDescriptor = arts.toList(0) val a1: DependencyArtifactDescriptor = arts.toList(1) diff --git a/librarymanagement/src/test/scala/ModuleIdTest.scala b/ivy/src/test/scala/ModuleIdTest.scala similarity index 100% rename from librarymanagement/src/test/scala/ModuleIdTest.scala rename to ivy/src/test/scala/ModuleIdTest.scala diff --git a/librarymanagement/src/test/scala/ModuleResolversTest.scala b/ivy/src/test/scala/ModuleResolversTest.scala similarity index 92% rename from librarymanagement/src/test/scala/ModuleResolversTest.scala rename to ivy/src/test/scala/ModuleResolversTest.scala index dd35c89ea..dea739b03 100644 --- a/librarymanagement/src/test/scala/ModuleResolversTest.scala +++ b/ivy/src/test/scala/ModuleResolversTest.scala @@ -1,9 +1,11 @@ package sbt.librarymanagement +import sbt.librarymanagement.ivy.UpdateOptions import sbt.internal.librarymanagement.BaseIvySpecification -import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.librarymanagement.syntax._ +import Resolver._ -class ModuleResolversTest extends BaseIvySpecification with DependencyBuilders { +class ModuleResolversTest extends BaseIvySpecification { override final val resolvers = Vector( DefaultMavenRepository, JavaNet2Repository, diff --git a/librarymanagement/src/test/scala/OfflineModeSpec.scala b/ivy/src/test/scala/OfflineModeSpec.scala similarity index 88% rename from librarymanagement/src/test/scala/OfflineModeSpec.scala rename to ivy/src/test/scala/OfflineModeSpec.scala index f4747a7f9..5bf20732b 100644 --- a/librarymanagement/src/test/scala/OfflineModeSpec.scala +++ b/ivy/src/test/scala/OfflineModeSpec.scala @@ -1,18 +1,17 @@ package sbt.librarymanagement +import sbt.librarymanagement.ivy.UpdateOptions import org.scalatest.Assertion import sbt.internal.librarymanagement._ -import sbt.internal.librarymanagement.impl.DependencyBuilders import sbt.io.IO -class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { +class OfflineModeSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) - private final def onlineConf = makeUpdateConfiguration(false) - private final def offlineConf = makeUpdateConfiguration(true) + private final def onlineConf = makeUpdateConfiguration(false, targetDir) + private final def offlineConf = makeUpdateConfiguration(true, targetDir) private final def warningConf = UnresolvedWarningConfiguration() private final def normalOptions = UpdateOptions() private final def cachedOptions = UpdateOptions().withCachedResolution(true) - private final def noClock = LogicalClock.unknown def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7") def dataAvro1940 = ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40") @@ -34,7 +33,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { cleanCachedResolutionCache(toResolve) val onlineResolution = - IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) + IvyActions.updateEither(toResolve, onlineConf, warningConf, log) assert(onlineResolution.isRight) assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0)) @@ -43,7 +42,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { val estimatedCachedTime = originalResolveTime * 0.3 val offlineResolution = - IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) + IvyActions.updateEither(toResolve, offlineConf, warningConf, log) assert(offlineResolution.isRight, s"Offline resolution has failed with $offlineResolution.") val resolveTime = offlineResolution.right.get.stats.resolveTime @@ -65,7 +64,7 @@ class OfflineModeSpec extends BaseIvySpecification with DependencyBuilders { val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve) val failedOfflineResolution = - IvyActions.updateEither(toResolve, offlineConf, warningConf, noClock, targetDir, log) + IvyActions.updateEither(toResolve, offlineConf, warningConf, log) assert(failedOfflineResolution.isLeft) } diff --git a/librarymanagement/src/test/scala/ResolverTest.scala b/ivy/src/test/scala/ResolverTest.scala similarity index 100% rename from librarymanagement/src/test/scala/ResolverTest.scala rename to ivy/src/test/scala/ResolverTest.scala diff --git a/librarymanagement/src/test/scala/ScalaOverrideTest.scala b/ivy/src/test/scala/ScalaOverrideTest.scala similarity index 98% rename from librarymanagement/src/test/scala/ScalaOverrideTest.scala rename to ivy/src/test/scala/ScalaOverrideTest.scala index bb872438d..57ee011cc 100644 --- a/librarymanagement/src/test/scala/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/ScalaOverrideTest.scala @@ -5,7 +5,7 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor import sbt.internal.librarymanagement.UnitSpec -import IvyScala.OverrideScalaMediator +import sbt.internal.librarymanagement.IvyScalaUtil.OverrideScalaMediator import ScalaArtifacts._ class ScalaOverrideTest extends UnitSpec { diff --git a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala b/ivy/src/test/scala/UpdateOptionsSpec.scala similarity index 95% rename from librarymanagement/src/test/scala/UpdateOptionsSpec.scala rename to ivy/src/test/scala/UpdateOptionsSpec.scala index eaf61fe29..831d2934e 100644 --- a/librarymanagement/src/test/scala/UpdateOptionsSpec.scala +++ b/ivy/src/test/scala/UpdateOptionsSpec.scala @@ -1,4 +1,4 @@ -package sbt.librarymanagement +package sbt.librarymanagement.ivy import sbt.internal.librarymanagement.UnitSpec diff --git a/librarymanagement/src/test/scala/VersionNumberSpec.scala b/ivy/src/test/scala/VersionNumberSpec.scala similarity index 98% rename from librarymanagement/src/test/scala/VersionNumberSpec.scala rename to ivy/src/test/scala/VersionNumberSpec.scala index 5a1c27a7a..4c1b8497a 100644 --- a/librarymanagement/src/test/scala/VersionNumberSpec.scala +++ b/ivy/src/test/scala/VersionNumberSpec.scala @@ -131,8 +131,8 @@ class VersionNumberSpec extends UnitSpec { } def beParsedAsError(s: String): Unit = s match { - case VersionNumber(ns1, ts1, es1) => sys.error(s) - case _ => () + case VersionNumber(_, _, _) => sys.error(s) + case _ => () } def beSemVerCompatWith(v1: String, v2: String) = VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala similarity index 95% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index 07962f60a..fdb5cc413 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -4,7 +4,7 @@ package librarymanagement import java.io.File -import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport } +import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport, ResolveException } class FakeResolverSpecification extends BaseIvySpecification { import FakeResolver._ @@ -67,7 +67,8 @@ class FakeResolverSpecification extends BaseIvySpecification { ) private def fakeResolver = new FakeResolver("FakeResolver", new File("tmp"), modules) - override def resolvers: Vector[Resolver] = Vector(new RawRepository(fakeResolver)) + override def resolvers: Vector[Resolver] = + Vector(new RawRepository(fakeResolver, fakeResolver.getName)) private def getModule(myModule: ModuleID): IvySbt#Module = module(defaultModuleId, Vector(myModule), None) private def getAllFiles(report: UpdateReport) = diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala similarity index 75% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 30965e810..2117e8c89 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -1,10 +1,11 @@ package sbt.internal.librarymanagement import org.scalatest.Inside -import sbt.internal.librarymanagement.impl.DependencyBuilders import sbt.librarymanagement._ +import sbt.librarymanagement.syntax._ +import InternalDefaults._ -class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { +class IvyRepoSpec extends BaseIvySpecification { val ourModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) @@ -43,12 +44,12 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val m = makeModuleForDepWithSources - // the "default" configuration used in updateEither. - val c = makeUpdateConfiguration(false) + // the "default" configuration used in `update`. + val c = makeUpdateConfiguration(false, None) - val ivyScala = m.moduleSettings.ivyScala - val srcTypes = Set("src") - val docTypes = Set("javadoc") + val scalaModuleInfo = m.moduleSettings.scalaModuleInfo + val srcTypes = Vector("src") + val docTypes = Vector("javadoc") // These will be the default classifiers that SBT should try, in case a dependency is Maven. // In this case though, they will be tried and should fail gracefully - only the val attemptedClassifiers = Vector("sources", "javadoc") @@ -61,25 +62,24 @@ class IvyRepoSpec extends BaseIvySpecification with DependencyBuilders { val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) GetClassifiersModule(ourModuleID, + scalaModuleInfo, externalModules, Vector(Configurations.Compile), attemptedClassifiers) } + val artifactFilter = getArtifactTypeFilter(c.artifactFilter) val gcm = GetClassifiersConfiguration(clMod, - Map.empty, - c.withArtifactFilter(c.artifactFilter.invert), - ivyScala, + Vector.empty, + c.withArtifactFilter(artifactFilter.invert), srcTypes, docTypes) - val report2 = IvyActions.updateClassifiers(m.owner, - gcm, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - None, - Vector(), - log) + val report2 = + lmEngine() + .updateClassifiers(gcm, UnresolvedWarningConfiguration(), Vector(), log) + .right + .get import Inside._ inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala similarity index 63% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index 493d600e5..fab7016df 100644 --- a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -3,25 +3,14 @@ package sbt.librarymanagement import java.io.File import org.apache.ivy.util.Message -import org.scalatest.Assertion -import sbt.internal.librarymanagement.{ - BaseIvySpecification, - InlineIvyConfiguration, - IvyActions, - IvyConfiguration, - IvyPaths, - IvySbt, - LogicalClock, - UnresolvedWarningConfiguration -} -import sbt.internal.librarymanagement.impl.DependencyBuilders +import sbt.internal.librarymanagement.{ BaseIvySpecification, IvyActions } +import sbt.librarymanagement.ivy._ import sbt.io.IO -class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders { +class ManagedChecksumsSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) - private final def onlineConf = makeUpdateConfiguration(false) + private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def warningConf = UnresolvedWarningConfiguration() - private final def noClock = LogicalClock.unknown private final val Checksum = "sha1" def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7") @@ -32,21 +21,17 @@ class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders import sbt.io.syntax._ override def mkIvyConfiguration(uo: UpdateOptions): IvyConfiguration = { - val paths = IvyPaths(currentBase, Some(currentTarget)) - val other = Vector.empty - val check = Vector(Checksum) val moduleConfs = Vector(ModuleConfiguration("*", chainResolver)) val resCacheDir = currentTarget / "resolution-cache" - new InlineIvyConfiguration(paths, - resolvers, - other, - moduleConfs, - None, - check, - managedChecksums = true, - Some(resCacheDir), - uo, - log) + InlineIvyConfiguration() + .withPaths(IvyPaths(currentBase, Some(currentTarget))) + .withResolvers(resolvers) + .withModuleConfigurations(moduleConfs) + .withChecksums(Vector(Checksum)) + .withResolutionCacheDir(resCacheDir) + .withLog(log) + .withUpdateOptions(uo) + .withManagedChecksums(true) } def cleanAll(): Unit = { @@ -66,7 +51,7 @@ class ManagedChecksumsSpec extends BaseIvySpecification with DependencyBuilders cleanAll() val updateOptions = UpdateOptions() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) - val res = IvyActions.updateEither(toResolve, onlineConf, warningConf, noClock, targetDir, log) + val res = IvyActions.updateEither(toResolve, onlineConf, warningConf, log) assert(res.isRight, s"Resolution with managed checksums failed! $res") val updateReport = res.right.get val allModuleReports = updateReport.configurations.flatMap(_.modules) diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala similarity index 100% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/TestLogger.scala diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala diff --git a/librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala similarity index 100% rename from librarymanagement/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala deleted file mode 100644 index b99ec9238..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/ExternalIvyConfiguration.scala +++ /dev/null @@ -1,56 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement -final class ExternalIvyConfiguration private ( - lock: Option[xsbti.GlobalLock], - baseDirectory: java.io.File, - log: xsbti.Logger, - updateOptions: sbt.librarymanagement.UpdateOptions, - val uri: java.net.URI, - val extraResolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.internal.librarymanagement.IvyConfiguration(lock, baseDirectory, log, updateOptions) with Serializable { - - - - override def equals(o: Any): Boolean = o match { - case x: ExternalIvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.uri == x.uri) && (this.extraResolvers == x.extraResolvers) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ExternalIvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) + uri.##) + extraResolvers.##) - } - override def toString: String = { - "ExternalIvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ", " + uri + ", " + extraResolvers + ")" - } - protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, baseDirectory: java.io.File = baseDirectory, log: xsbti.Logger = log, updateOptions: sbt.librarymanagement.UpdateOptions = updateOptions, uri: java.net.URI = uri, extraResolvers: Vector[sbt.librarymanagement.Resolver] = extraResolvers): ExternalIvyConfiguration = { - new ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) - } - def withLock(lock: Option[xsbti.GlobalLock]): ExternalIvyConfiguration = { - copy(lock = lock) - } - def withLock(lock: xsbti.GlobalLock): ExternalIvyConfiguration = { - copy(lock = Option(lock)) - } - def withBaseDirectory(baseDirectory: java.io.File): ExternalIvyConfiguration = { - copy(baseDirectory = baseDirectory) - } - def withLog(log: xsbti.Logger): ExternalIvyConfiguration = { - copy(log = log) - } - def withUpdateOptions(updateOptions: sbt.librarymanagement.UpdateOptions): ExternalIvyConfiguration = { - copy(updateOptions = updateOptions) - } - def withUri(uri: java.net.URI): ExternalIvyConfiguration = { - copy(uri = uri) - } - def withExtraResolvers(extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = { - copy(extraResolvers = extraResolvers) - } -} -object ExternalIvyConfiguration { - - def apply(lock: Option[xsbti.GlobalLock], baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(lock, baseDirectory, log, updateOptions, uri, extraResolvers) - def apply(lock: xsbti.GlobalLock, baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(Option(lock), baseDirectory, log, updateOptions, uri, extraResolvers) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala deleted file mode 100644 index 5ddc4a153..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineConfiguration.scala +++ /dev/null @@ -1,78 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement -final class InlineConfiguration private ( - validate: Boolean, - ivyScala: Option[sbt.librarymanagement.IvyScala], - val module: sbt.librarymanagement.ModuleID, - val moduleInfo: sbt.librarymanagement.ModuleInfo, - val dependencies: Vector[sbt.librarymanagement.ModuleID], - val overrides: Set[sbt.librarymanagement.ModuleID], - val excludes: Vector[sbt.librarymanagement.InclExclRule], - val ivyXML: scala.xml.NodeSeq, - val configurations: Vector[sbt.librarymanagement.Configuration], - val defaultConfiguration: Option[sbt.librarymanagement.Configuration], - val conflictManager: sbt.librarymanagement.ConflictManager) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { - - private def this(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]) = this(validate, ivyScala, module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) - - override def equals(o: Any): Boolean = o match { - case x: InlineConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.module == x.module) && (this.moduleInfo == x.moduleInfo) && (this.dependencies == x.dependencies) && (this.overrides == x.overrides) && (this.excludes == x.excludes) && (this.ivyXML == x.ivyXML) && (this.configurations == x.configurations) && (this.defaultConfiguration == x.defaultConfiguration) && (this.conflictManager == x.conflictManager) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineConfiguration".##) + validate.##) + ivyScala.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) - } - override def toString: String = { - "InlineConfiguration(" + validate + ", " + ivyScala + ", " + module + ", " + moduleInfo + ", " + dependencies + ", " + overrides + ", " + excludes + ", " + ivyXML + ", " + configurations + ", " + defaultConfiguration + ", " + conflictManager + ")" - } - protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, module: sbt.librarymanagement.ModuleID = module, moduleInfo: sbt.librarymanagement.ModuleInfo = moduleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, overrides: Set[sbt.librarymanagement.ModuleID] = overrides, excludes: Vector[sbt.librarymanagement.InclExclRule] = excludes, ivyXML: scala.xml.NodeSeq = ivyXML, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, defaultConfiguration: Option[sbt.librarymanagement.Configuration] = defaultConfiguration, conflictManager: sbt.librarymanagement.ConflictManager = conflictManager): InlineConfiguration = { - new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) - } - def withValidate(validate: Boolean): InlineConfiguration = { - copy(validate = validate) - } - def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): InlineConfiguration = { - copy(ivyScala = ivyScala) - } - def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): InlineConfiguration = { - copy(ivyScala = Option(ivyScala)) - } - def withModule(module: sbt.librarymanagement.ModuleID): InlineConfiguration = { - copy(module = module) - } - def withModuleInfo(moduleInfo: sbt.librarymanagement.ModuleInfo): InlineConfiguration = { - copy(moduleInfo = moduleInfo) - } - def withDependencies(dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = { - copy(dependencies = dependencies) - } - def withOverrides(overrides: Set[sbt.librarymanagement.ModuleID]): InlineConfiguration = { - copy(overrides = overrides) - } - def withExcludes(excludes: Vector[sbt.librarymanagement.InclExclRule]): InlineConfiguration = { - copy(excludes = excludes) - } - def withIvyXML(ivyXML: scala.xml.NodeSeq): InlineConfiguration = { - copy(ivyXML = ivyXML) - } - def withConfigurations(configurations: Vector[sbt.librarymanagement.Configuration]): InlineConfiguration = { - copy(configurations = configurations) - } - def withDefaultConfiguration(defaultConfiguration: Option[sbt.librarymanagement.Configuration]): InlineConfiguration = { - copy(defaultConfiguration = defaultConfiguration) - } - def withConflictManager(conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = { - copy(conflictManager = conflictManager) - } -} -object InlineConfiguration extends sbt.internal.librarymanagement.InlineConfigurationFunctions { - - def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) - def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID]): InlineConfiguration = new InlineConfiguration(validate, Option(ivyScala), module, moduleInfo, dependencies, Set.empty, Vector.empty, scala.xml.NodeSeq.Empty, Vector.empty, None, sbt.librarymanagement.ConflictManager.default) - def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Set[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = new InlineConfiguration(validate, ivyScala, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) - def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Set[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): InlineConfiguration = new InlineConfiguration(validate, Option(ivyScala), module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala deleted file mode 100644 index 0cd006bfa..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/InlineIvyConfiguration.scala +++ /dev/null @@ -1,92 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement -final class InlineIvyConfiguration private ( - lock: Option[xsbti.GlobalLock], - baseDirectory: java.io.File, - log: xsbti.Logger, - updateOptions: sbt.librarymanagement.UpdateOptions, - val paths: sbt.internal.librarymanagement.IvyPaths, - val resolvers: Vector[sbt.librarymanagement.Resolver], - val otherResolvers: Vector[sbt.librarymanagement.Resolver], - val moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], - val checksums: Vector[String], - val managedChecksums: Boolean, - val resolutionCacheDir: Option[java.io.File]) extends sbt.internal.librarymanagement.IvyConfiguration(lock, baseDirectory, log, updateOptions) with Serializable { - def this( - paths: sbt.internal.librarymanagement.IvyPaths, - resolvers: Vector[sbt.librarymanagement.Resolver], - otherResolvers: Vector[sbt.librarymanagement.Resolver], - moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], - lock: Option[xsbti.GlobalLock], - checksums: Vector[String], - managedChecksums: Boolean, - resolutionCacheDir: Option[java.io.File], - updateOptions: sbt.librarymanagement.UpdateOptions, - log: xsbti.Logger - ) = - this(lock, paths.baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, - moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) - - - override def equals(o: Any): Boolean = o match { - case x: InlineIvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.paths == x.paths) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.moduleConfigurations == x.moduleConfigurations) && (this.checksums == x.checksums) && (this.managedChecksums == x.managedChecksums) && (this.resolutionCacheDir == x.resolutionCacheDir) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineIvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) - } - override def toString: String = { - "InlineIvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ", " + paths + ", " + resolvers + ", " + otherResolvers + ", " + moduleConfigurations + ", " + checksums + ", " + managedChecksums + ", " + resolutionCacheDir + ")" - } - protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, baseDirectory: java.io.File = baseDirectory, log: xsbti.Logger = log, updateOptions: sbt.librarymanagement.UpdateOptions = updateOptions, paths: sbt.internal.librarymanagement.IvyPaths = paths, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration] = moduleConfigurations, checksums: Vector[String] = checksums, managedChecksums: Boolean = managedChecksums, resolutionCacheDir: Option[java.io.File] = resolutionCacheDir): InlineIvyConfiguration = { - new InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) - } - def withLock(lock: Option[xsbti.GlobalLock]): InlineIvyConfiguration = { - copy(lock = lock) - } - def withLock(lock: xsbti.GlobalLock): InlineIvyConfiguration = { - copy(lock = Option(lock)) - } - def withBaseDirectory(baseDirectory: java.io.File): InlineIvyConfiguration = { - copy(baseDirectory = baseDirectory) - } - def withLog(log: xsbti.Logger): InlineIvyConfiguration = { - copy(log = log) - } - def withUpdateOptions(updateOptions: sbt.librarymanagement.UpdateOptions): InlineIvyConfiguration = { - copy(updateOptions = updateOptions) - } - def withPaths(paths: sbt.internal.librarymanagement.IvyPaths): InlineIvyConfiguration = { - copy(paths = paths) - } - def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { - copy(resolvers = resolvers) - } - def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): InlineIvyConfiguration = { - copy(otherResolvers = otherResolvers) - } - def withModuleConfigurations(moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration]): InlineIvyConfiguration = { - copy(moduleConfigurations = moduleConfigurations) - } - def withChecksums(checksums: Vector[String]): InlineIvyConfiguration = { - copy(checksums = checksums) - } - def withManagedChecksums(managedChecksums: Boolean): InlineIvyConfiguration = { - copy(managedChecksums = managedChecksums) - } - def withResolutionCacheDir(resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = { - copy(resolutionCacheDir = resolutionCacheDir) - } - def withResolutionCacheDir(resolutionCacheDir: java.io.File): InlineIvyConfiguration = { - copy(resolutionCacheDir = Option(resolutionCacheDir)) - } -} -object InlineIvyConfiguration { - - def apply(lock: Option[xsbti.GlobalLock], baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, paths: sbt.internal.librarymanagement.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = new InlineIvyConfiguration(lock, baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) - def apply(lock: xsbti.GlobalLock, baseDirectory: java.io.File, log: xsbti.Logger, updateOptions: sbt.librarymanagement.UpdateOptions, paths: sbt.internal.librarymanagement.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: java.io.File): InlineIvyConfiguration = new InlineIvyConfiguration(Option(lock), baseDirectory, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, Option(resolutionCacheDir)) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala deleted file mode 100644 index a50adcb0a..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/IvyConfiguration.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement -abstract class IvyConfiguration( - val lock: Option[xsbti.GlobalLock], - val baseDirectory: java.io.File, - val log: xsbti.Logger, - val updateOptions: sbt.librarymanagement.UpdateOptions) extends Serializable { - - - - - override def equals(o: Any): Boolean = o match { - case x: IvyConfiguration => (this.lock == x.lock) && (this.baseDirectory == x.baseDirectory) && (this.log == x.log) && (this.updateOptions == x.updateOptions) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "IvyConfiguration".##) + lock.##) + baseDirectory.##) + log.##) + updateOptions.##) - } - override def toString: String = { - "IvyConfiguration(" + lock + ", " + baseDirectory + ", " + log + ", " + updateOptions + ")" - } -} -object IvyConfiguration { - -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala deleted file mode 100644 index 0a6551f33..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/internal/librarymanagement/RetrieveConfiguration.scala +++ /dev/null @@ -1,45 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.internal.librarymanagement -final class RetrieveConfiguration private ( - val retrieveDirectory: java.io.File, - val outputPattern: String, - val sync: Boolean, - val configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]) extends Serializable { - - private def this(retrieveDirectory: java.io.File, outputPattern: String) = this(retrieveDirectory, outputPattern, false, None) - - override def equals(o: Any): Boolean = o match { - case x: RetrieveConfiguration => (this.retrieveDirectory == x.retrieveDirectory) && (this.outputPattern == x.outputPattern) && (this.sync == x.sync) && (this.configurationsToRetrieve == x.configurationsToRetrieve) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) - } - override def toString: String = { - "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" - } - protected[this] def copy(retrieveDirectory: java.io.File = retrieveDirectory, outputPattern: String = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]] = configurationsToRetrieve): RetrieveConfiguration = { - new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) - } - def withRetrieveDirectory(retrieveDirectory: java.io.File): RetrieveConfiguration = { - copy(retrieveDirectory = retrieveDirectory) - } - def withOutputPattern(outputPattern: String): RetrieveConfiguration = { - copy(outputPattern = outputPattern) - } - def withSync(sync: Boolean): RetrieveConfiguration = { - copy(sync = sync) - } - def withConfigurationsToRetrieve(configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = { - copy(configurationsToRetrieve = configurationsToRetrieve) - } -} -object RetrieveConfiguration { - - def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, false, None) - def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: Option[Set[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala deleted file mode 100644 index a4ab026da..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/Configuration.scala +++ /dev/null @@ -1,50 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** Represents an Ivy configuration. */ -final class Configuration private ( - val name: String, - val description: String, - val isPublic: Boolean, - val extendsConfigs: Vector[sbt.librarymanagement.Configuration], - val transitive: Boolean) extends sbt.librarymanagement.ConfigurationExtra with Serializable { - - private def this(name: String) = this(name, "", true, Vector.empty, true) - - override def equals(o: Any): Boolean = o match { - case x: Configuration => (this.name == x.name) && (this.description == x.description) && (this.isPublic == x.isPublic) && (this.extendsConfigs == x.extendsConfigs) && (this.transitive == x.transitive) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "Configuration".##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) - } - override def toString: String = { - name - } - protected[this] def copy(name: String = name, description: String = description, isPublic: Boolean = isPublic, extendsConfigs: Vector[sbt.librarymanagement.Configuration] = extendsConfigs, transitive: Boolean = transitive): Configuration = { - new Configuration(name, description, isPublic, extendsConfigs, transitive) - } - def withName(name: String): Configuration = { - copy(name = name) - } - def withDescription(description: String): Configuration = { - copy(description = description) - } - def withIsPublic(isPublic: Boolean): Configuration = { - copy(isPublic = isPublic) - } - def withExtendsConfigs(extendsConfigs: Vector[sbt.librarymanagement.Configuration]): Configuration = { - copy(extendsConfigs = extendsConfigs) - } - def withTransitive(transitive: Boolean): Configuration = { - copy(transitive = transitive) - } -} -object Configuration { - - def apply(name: String): Configuration = new Configuration(name, "", true, Vector.empty, true) - def apply(name: String, description: String, isPublic: Boolean, extendsConfigs: Vector[sbt.librarymanagement.Configuration], transitive: Boolean): Configuration = new Configuration(name, description, isPublic, extendsConfigs, transitive) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala deleted file mode 100644 index 70e4b21fc..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ConfigurationFormats.scala +++ /dev/null @@ -1,35 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = new JsonFormat[sbt.librarymanagement.Configuration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Configuration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - val name = unbuilder.readField[String]("name") - val description = unbuilder.readField[String]("description") - val isPublic = unbuilder.readField[Boolean]("isPublic") - val extendsConfigs = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("extendsConfigs") - val transitive = unbuilder.readField[Boolean]("transitive") - unbuilder.endObject() - sbt.librarymanagement.Configuration(name, description, isPublic, extendsConfigs, transitive) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Configuration, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("name", obj.name) - builder.addField("description", obj.description) - builder.addField("isPublic", obj.isPublic) - builder.addField("extendsConfigs", obj.extendsConfigs) - builder.addField("transitive", obj.transitive) - builder.endObject() - } -} -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala deleted file mode 100644 index 405edbbad..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyConfigurationFormats.scala +++ /dev/null @@ -1,11 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement - -import _root_.sjsonnew.JsonFormat -trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.internal.librarymanagement.formats.UpdateOptionsFormat with sbt.librarymanagement.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InlineIvyConfigurationFormats with sbt.librarymanagement.ExternalIvyConfigurationFormats => -implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.internal.librarymanagement.IvyConfiguration] = flatUnionFormat2[sbt.internal.librarymanagement.IvyConfiguration, sbt.internal.librarymanagement.InlineIvyConfiguration, sbt.internal.librarymanagement.ExternalIvyConfiguration]("type") -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala deleted file mode 100644 index 2939baaa8..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -final class IvyFileConfiguration private ( - validate: Boolean, - ivyScala: Option[sbt.librarymanagement.IvyScala], - val file: java.io.File, - val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { - - - - override def equals(o: Any): Boolean = o match { - case x: IvyFileConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "IvyFileConfiguration".##) + validate.##) + ivyScala.##) + file.##) + autoScalaTools.##) - } - override def toString: String = { - "IvyFileConfiguration(" + validate + ", " + ivyScala + ", " + file + ", " + autoScalaTools + ")" - } - protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): IvyFileConfiguration = { - new IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) - } - def withValidate(validate: Boolean): IvyFileConfiguration = { - copy(validate = validate) - } - def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): IvyFileConfiguration = { - copy(ivyScala = ivyScala) - } - def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): IvyFileConfiguration = { - copy(ivyScala = Option(ivyScala)) - } - def withFile(file: java.io.File): IvyFileConfiguration = { - copy(file = file) - } - def withAutoScalaTools(autoScalaTools: Boolean): IvyFileConfiguration = { - copy(autoScalaTools = autoScalaTools) - } -} -object IvyFileConfiguration { - - def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, ivyScala, file, autoScalaTools) - def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, Option(ivyScala), file, autoScalaTools) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala deleted file mode 100644 index 66ae6c37f..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala +++ /dev/null @@ -1,11 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement - -import _root_.sjsonnew.JsonFormat -trait ModuleSettingsFormats { self: sbt.librarymanagement.IvyScalaFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.InlineConfigurationFormats => -implicit lazy val ModuleSettingsFormat: JsonFormat[sbt.librarymanagement.ModuleSettings] = flatUnionFormat3[sbt.librarymanagement.ModuleSettings, sbt.librarymanagement.IvyFileConfiguration, sbt.librarymanagement.PomConfiguration, sbt.internal.librarymanagement.InlineConfiguration]("type") -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala deleted file mode 100644 index ff9b16137..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ /dev/null @@ -1,48 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -final class PomConfiguration private ( - validate: Boolean, - ivyScala: Option[sbt.librarymanagement.IvyScala], - val file: java.io.File, - val autoScalaTools: Boolean) extends sbt.librarymanagement.ModuleSettings(validate, ivyScala) with Serializable { - - - - override def equals(o: Any): Boolean = o match { - case x: PomConfiguration => (this.validate == x.validate) && (this.ivyScala == x.ivyScala) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "PomConfiguration".##) + validate.##) + ivyScala.##) + file.##) + autoScalaTools.##) - } - override def toString: String = { - "PomConfiguration(" + validate + ", " + ivyScala + ", " + file + ", " + autoScalaTools + ")" - } - protected[this] def copy(validate: Boolean = validate, ivyScala: Option[sbt.librarymanagement.IvyScala] = ivyScala, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): PomConfiguration = { - new PomConfiguration(validate, ivyScala, file, autoScalaTools) - } - def withValidate(validate: Boolean): PomConfiguration = { - copy(validate = validate) - } - def withIvyScala(ivyScala: Option[sbt.librarymanagement.IvyScala]): PomConfiguration = { - copy(ivyScala = ivyScala) - } - def withIvyScala(ivyScala: sbt.librarymanagement.IvyScala): PomConfiguration = { - copy(ivyScala = Option(ivyScala)) - } - def withFile(file: java.io.File): PomConfiguration = { - copy(file = file) - } - def withAutoScalaTools(autoScalaTools: Boolean): PomConfiguration = { - copy(autoScalaTools = autoScalaTools) - } -} -object PomConfiguration { - - def apply(validate: Boolean, ivyScala: Option[sbt.librarymanagement.IvyScala], file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, ivyScala, file, autoScalaTools) - def apply(validate: Boolean, ivyScala: sbt.librarymanagement.IvyScala, file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, Option(ivyScala), file, autoScalaTools) -} diff --git a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala deleted file mode 100644 index de5773eed..000000000 --- a/librarymanagement/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ /dev/null @@ -1,56 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -final class UpdateConfiguration private ( - val retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration], - val missingOk: Boolean, - val logging: sbt.librarymanagement.UpdateLogging, - val artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, - val offline: Boolean, - val frozen: Boolean) extends Serializable { - - - - override def equals(o: Any): Boolean = o match { - case x: UpdateConfiguration => (this.retrieve == x.retrieve) && (this.missingOk == x.missingOk) && (this.logging == x.logging) && (this.artifactFilter == x.artifactFilter) && (this.offline == x.offline) && (this.frozen == x.frozen) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "UpdateConfiguration".##) + retrieve.##) + missingOk.##) + logging.##) + artifactFilter.##) + offline.##) + frozen.##) - } - override def toString: String = { - "UpdateConfiguration(" + retrieve + ", " + missingOk + ", " + logging + ", " + artifactFilter + ", " + offline + ", " + frozen + ")" - } - protected[this] def copy(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration] = retrieve, missingOk: Boolean = missingOk, logging: sbt.librarymanagement.UpdateLogging = logging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter = artifactFilter, offline: Boolean = offline, frozen: Boolean = frozen): UpdateConfiguration = { - new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) - } - def withRetrieve(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration]): UpdateConfiguration = { - copy(retrieve = retrieve) - } - def withRetrieve(retrieve: sbt.internal.librarymanagement.RetrieveConfiguration): UpdateConfiguration = { - copy(retrieve = Option(retrieve)) - } - def withMissingOk(missingOk: Boolean): UpdateConfiguration = { - copy(missingOk = missingOk) - } - def withLogging(logging: sbt.librarymanagement.UpdateLogging): UpdateConfiguration = { - copy(logging = logging) - } - def withArtifactFilter(artifactFilter: sbt.librarymanagement.ArtifactTypeFilter): UpdateConfiguration = { - copy(artifactFilter = artifactFilter) - } - def withOffline(offline: Boolean): UpdateConfiguration = { - copy(offline = offline) - } - def withFrozen(frozen: Boolean): UpdateConfiguration = { - copy(frozen = frozen) - } -} -object UpdateConfiguration { - - def apply(retrieve: Option[sbt.internal.librarymanagement.RetrieveConfiguration], missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(retrieve, missingOk, logging, artifactFilter, offline, frozen) - def apply(retrieve: sbt.internal.librarymanagement.RetrieveConfiguration, missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(Option(retrieve), missingOk, logging, artifactFilter, offline, frozen) -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala deleted file mode 100644 index e365b961b..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/formats/DependencyResolverFormat.scala +++ /dev/null @@ -1,8 +0,0 @@ -package sbt.internal.librarymanagement.formats - -import sjsonnew._ -import org.apache.ivy.plugins.resolver.DependencyResolver - -trait DependencyResolverFormat { self: BasicJsonProtocol => - implicit lazy val DependencyResolverFormat: JsonFormat[DependencyResolver] = ??? -} diff --git a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala b/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala deleted file mode 100755 index a37a4f38f..000000000 --- a/librarymanagement/src/main/scala/sbt/internal/librarymanagement/impl/DependencyBuilders.scala +++ /dev/null @@ -1,58 +0,0 @@ -/* sbt -- Simple Build Tool - * Copyright 2009,2010 Mark Harrah - */ -package sbt.internal.librarymanagement -package impl - -import StringUtilities.nonEmpty -import sbt.librarymanagement._ - -trait DependencyBuilders { - final implicit def toGroupID(groupID: String): GroupID = { - nonEmpty(groupID, "Group ID") - new GroupID(groupID) - } - final implicit def toRepositoryName(name: String): RepositoryName = { - nonEmpty(name, "Repository name") - new RepositoryName(name) - } - final implicit def moduleIDConfigurable(m: ModuleID): ModuleIDConfigurable = { - require(m.configurations.isEmpty, "Configurations already specified for module " + m) - new ModuleIDConfigurable(m) - } -} - -final class GroupID private[sbt] (private[sbt] val groupID: String) { - def %(artifactID: String) = groupArtifact(artifactID, Disabled()) - def %%(artifactID: String): GroupArtifactID = groupArtifact(artifactID, CrossVersion.binary) - - private def groupArtifact(artifactID: String, cross: CrossVersion) = { - nonEmpty(artifactID, "Artifact ID") - new GroupArtifactID(groupID, artifactID, cross) - } -} -final class GroupArtifactID private[sbt] ( - private[sbt] val groupID: String, - private[sbt] val artifactID: String, - private[sbt] val crossVersion: CrossVersion -) { - def %(revision: String): ModuleID = { - nonEmpty(revision, "Revision") - ModuleID(groupID, artifactID, revision).cross(crossVersion) - } -} -final class ModuleIDConfigurable private[sbt] (moduleID: ModuleID) { - def %(configuration: Configuration): ModuleID = %(configuration.name) - - def %(configurations: String): ModuleID = { - nonEmpty(configurations, "Configurations") - val c = configurations - moduleID.withConfigurations(configurations = Some(c)) - } -} -final class RepositoryName private[sbt] (name: String) { - def at(location: String) = { - nonEmpty(location, "Repository location") - MavenRepository(name, location) - } -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala deleted file mode 100644 index 49af3cb71..000000000 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/DefaultLibraryManagement.scala +++ /dev/null @@ -1,105 +0,0 @@ -package sbt -package librarymanagement - -import java.io.File -import sbt.internal.librarymanagement._ -import sbt.util.Logger -import sbt.io.Hash - -class DefaultLibraryManagement(ivyConfiguration: IvyConfiguration, log: Logger) - extends LibraryManagement { - private[sbt] val ivySbt: IvySbt = new IvySbt(ivyConfiguration) - private val sbtOrgTemp = JsonUtil.sbtOrgTemp - private val modulePrefixTemp = "temp-module-" - - type Module = ivySbt.Module - - /** - * Returns a dummy module that depends on `moduleID`. - * Note: Sbt's implementation of Ivy requires us to do this, because only the dependencies - * of the specified module will be downloaded. - */ - def getModule(moduleId: ModuleID): Module = getModule(moduleId, None) - - def getModule(moduleId: ModuleID, ivyScala: Option[IvyScala]): ivySbt.Module = { - val sha1 = Hash.toHex(Hash(moduleId.name)) - val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, moduleId.revision) - .withConfigurations(moduleId.configurations) - getModule(dummyID, Vector(moduleId), UpdateOptions(), ivyScala) - } - - def getModule( - moduleId: ModuleID, - deps: Vector[ModuleID], - uo: UpdateOptions = UpdateOptions(), - ivyScala: Option[IvyScala] - ): ivySbt.Module = { - val moduleSetting = InlineConfiguration( - validate = false, - ivyScala = ivyScala, - module = moduleId, - moduleInfo = ModuleInfo(moduleId.name), - dependencies = deps - ).withConfigurations(Vector(Configurations.Component)) - new ivySbt.Module(moduleSetting) - } - - private def dependenciesNames(module: ivySbt.Module): String = - module.moduleSettings match { - // `module` is a dummy module, we will only fetch its dependencies. - case ic: InlineConfiguration => - ic.dependencies map { - case mID: ModuleID => - import mID._ - s"$organization % $name % $revision" - } mkString ", " - case _ => - s"unknown" - } - - def update(module: ivySbt.Module, retrieveDirectory: File)( - predicate: File => Boolean - ): Option[Seq[File]] = { - val specialArtifactTypes = Artifact.DefaultSourceTypes union Artifact.DefaultDocTypes - val artifactFilter = ArtifactTypeFilter.forbid(specialArtifactTypes) - val retrieveConfiguration = - RetrieveConfiguration(retrieveDirectory, Resolver.defaultRetrievePattern).withSync(false) - val updateConfiguration = UpdateConfiguration( - Some(retrieveConfiguration), - true, - UpdateLogging.DownloadOnly, - artifactFilter, - false, - false - ) - - log.debug(s"Attempting to fetch ${dependenciesNames(module)}. This operation may fail.") - IvyActions.updateEither( - module, - updateConfiguration, - UnresolvedWarningConfiguration(), - LogicalClock.unknown, - None, - log - ) match { - case Left(unresolvedWarning) => - log.debug(s"Couldn't retrieve module ${dependenciesNames(module)}.") - None - - case Right(updateReport) => - val allFiles = - for { - conf <- updateReport.configurations - m <- conf.modules - (_, f) <- m.artifacts - } yield f - - log.debug(s"Files retrieved for ${dependenciesNames(module)}:") - log.debug(allFiles mkString ", ") - allFiles filter predicate match { - case Seq() => None - case files => Some(files) - } - } - } -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala deleted file mode 100644 index ce86cc0b5..000000000 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagement.scala +++ /dev/null @@ -1,8 +0,0 @@ -package sbt.librarymanagement - -// Interface for library management - -trait LibraryManagement { - type Module - def getModule(moduleId: ModuleID): Module -} diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala deleted file mode 100644 index e6c43d872..000000000 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala +++ /dev/null @@ -1,7 +0,0 @@ -package sbt.librarymanagement - -trait LibraryManagementSyntax { - implicit def richUpdateReport(ur: UpdateReport): RichUpdateReport = new RichUpdateReport(ur) -} - -object syntax extends LibraryManagementSyntax diff --git a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala b/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala deleted file mode 100644 index a1892b2f0..000000000 --- a/librarymanagement/src/main/scala/sbt/librarymanagement/package.scala +++ /dev/null @@ -1,9 +0,0 @@ -package sbt - -package object librarymanagement extends ResolversSyntax { - type ExclusionRule = InclExclRule - val ExclusionRule = InclExclRule - - type InclusionRule = InclExclRule - val InclusionRule = InclExclRule -} diff --git a/notes/1.0.0.markdown b/notes/1.0.0.markdown new file mode 100644 index 000000000..2225348b7 --- /dev/null +++ b/notes/1.0.0.markdown @@ -0,0 +1,5 @@ +- InlineConfiguration is renamed to ModuleConfiguration +- IvyScala is renamed to ScalaModuleInfo +- UpdateConfiguration, RetrieveConfiguration, PublishConfiguration are refactored to use builder pattern. +- Adds ConfigRef for referencing Configuration +- Moves syntax related things into `sbt.librarymagement.syntax` diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index cc95f3ff3..3e729cd4d 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -34,8 +34,12 @@ object DatatypeConfig { "sbt.internal.librarymanagement.formats.LoggerFormat" :: Nil } - case "sbt.librarymanagement.UpdateOptions" => { _ => - "sbt.internal.librarymanagement.formats.UpdateOptionsFormat" :: Nil + case "sbt.librarymanagement.ivy.UpdateOptions" => { _ => + "sbt.librarymanagement.ivy.formats.UpdateOptionsFormat" :: Nil + } + + case "sbt.librarymanagement.LogicalClock" => { _ => + "sbt.internal.librarymanagement.formats.LogicalClockFormats" :: Nil } // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo From a98c5f4c65d8093d45f083762d314a226f30f37d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 12 Jul 2017 07:15:09 -0400 Subject: [PATCH 0648/1030] Minor cleanups per review --- .../scala/sbt/librarymanagement/DependencyBuilders.scala | 5 ++++- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 1 - .../scala/sbt/internal/librarymanagement/IvyActions.scala | 4 ++-- .../ivyint/CachedResolutionResolveEngine.scala | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala index 8191cb1bf..5c4071dd5 100755 --- a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -5,6 +5,9 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.StringUtilities.nonEmpty +/** + * DependencyBuilders implements the implicits for % and %% DSL. + */ abstract class DependencyBuilders { import DependencyBuilders._ @@ -31,7 +34,7 @@ object DependencyBuilders { organizationArtifact(name, CrossVersion.binary) private def organizationArtifact(name: String, cross: CrossVersion) = { - nonEmpty(name, "Artifact ID") + nonEmpty(name, "Name") new OrganizationArtifactName(organization, name, cross) } } diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 3ded29183..52e0b7fd2 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -6,7 +6,6 @@ package sbt.librarymanagement import java.io.{ IOException, File } import java.net.URL import scala.xml.XML -// import org.apache.ivy.plugins.resolver.DependencyResolver import org.xml.sax.SAXParseException final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 25decece0..4aa761d66 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -270,10 +270,10 @@ object IvyActions { implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { override def accept(o: Object): Boolean = Option(o) exists { - case a: IArtifact => applyFilter(f, a) + case a: IArtifact => applyFilter(a) } - def applyFilter(f: ArtifactTypeFilter, a: IArtifact): Boolean = + def applyFilter(a: IArtifact): Boolean = (f.types contains a.getType) ^ f.inverted } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index fa3846da2..4cebabdc4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -209,7 +209,7 @@ private[sbt] class CachedResolutionResolveCache { else None) match { case Some(path) => log.debug(s"parsing ${path.getAbsolutePath.toString}") - val ur = JsonUtil.parseUpdateReport( /* md, */ path, cachedDescriptor, log) + val ur = JsonUtil.parseUpdateReport(path, cachedDescriptor, log) if (ur.allFiles forall { _.exists }) { updateReportCache(md.getModuleRevisionId) = Right(ur) Some(Right(ur)) From 7844190964d285cd8ae679d3ec2d9398a6d36211 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 12 Jul 2017 07:42:30 -0400 Subject: [PATCH 0649/1030] Use delegation instead of inheritance --- .../librarymanagement/LibraryManagement.scala | 37 ++++++++++++--- .../LibraryManagementInterface.scala | 2 +- .../sbt/librarymanagement/Publisher.scala | 47 +++++++++++++++++++ .../ivy/IvyLibraryManagement.scala | 4 +- .../librarymanagement/ivy/IvyPublisher.scala | 4 +- 5 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 core/src/main/scala/sbt/librarymanagement/Publisher.scala diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala index 82401ec4b..54a3fa970 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala @@ -6,12 +6,21 @@ import sbt.io.Hash import sbt.librarymanagement.syntax._ /** - * Helper mixin to provide methods for library management + * Library management API to resolve dependencies. */ -abstract class LibraryManagement extends LibraryManagementInterface { +class LibraryManagement private[sbt] (lmEngine: LibraryManagementInterface) { import sbt.internal.librarymanagement.InternalDefaults._ import sbt.internal.librarymanagement.UpdateClassifiersUtil._ + /** + * Builds a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleSetting It contains the information about the module including the dependencies. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = + lmEngine.moduleDescriptor(moduleSetting) + /** * Build a ModuleDescriptor that describes a subproject with dependencies. * @@ -30,6 +39,22 @@ abstract class LibraryManagement extends LibraryManagementInterface { moduleDescriptor(moduleSetting) } + /** + * Resolves the given module's dependencies performing a retrieval. + * + * @param module The module to be resolved. + * @param configuration The update configuration. + * @param uwconfig The configuration to handle unresolved warnings. + * @param log The logger. + * @return The result, either an unresolved warning or an update report. Note that this + * update report will or will not be successful depending on the `missingOk` option. + */ + def update(module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger): Either[UnresolvedWarning, UpdateReport] = + lmEngine.update(module, configuration, uwconfig, log) + /** * Returns a `ModuleDescriptor` that depends on `dependencyId`. * @@ -192,7 +217,7 @@ abstract class LibraryManagement extends LibraryManagementInterface { }).mkString(", ") } -/** - * Helper mixin to provide methods for publisher - */ -abstract class Publisher extends PublisherInterface +object LibraryManagement { + def apply(lmEngine: LibraryManagementInterface): LibraryManagement = + new LibraryManagement(lmEngine) +} diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 6650376b8..9af54bd06 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -4,7 +4,7 @@ import java.io.File import sbt.util.Logger /** - * Interface for library management + * Interface for library management intended for library management engine authors. */ abstract class LibraryManagementInterface { diff --git a/core/src/main/scala/sbt/librarymanagement/Publisher.scala b/core/src/main/scala/sbt/librarymanagement/Publisher.scala new file mode 100644 index 000000000..da3e09e6f --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/Publisher.scala @@ -0,0 +1,47 @@ +package sbt.librarymanagement + +import java.io.File +import sbt.util.Logger + +/** + * Library management API to publish artifacts. + */ +class Publisher private[sbt] (publisherEngine: PublisherInterface) { + + /** + * Builds a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleSetting It contains the information about the module including the dependencies. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = + publisherEngine.moduleDescriptor(moduleSetting) + + /** + * Publishes the given module. + * + * @param module The module to be published. + * @param configuration The publish configuration. + * @param log The logger. + */ + def publish(module: ModuleDescriptor, configuration: PublishConfiguration, log: Logger): Unit = + publisherEngine.publish(module, configuration, log) + + /** + * Makes the `pom.xml` file for the given module. + * + * @param module The module for which a `.pom` file is to be created. + * @param configuration The makePomFile configuration. + * @param log The logger. + * @return The `File` containing the POM descriptor. + */ + def makePomFile(module: ModuleDescriptor, + configuration: MakePomConfiguration, + log: Logger): File = + publisherEngine.makePomFile(module, configuration, log) +} + +object Publisher { + def apply(publisherEngine: PublisherInterface): Publisher = + new Publisher(publisherEngine) +} diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala index 5eee63a45..3d591ea02 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala @@ -5,7 +5,7 @@ package ivy import sbt.internal.librarymanagement._ import sbt.util.Logger -class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryManagement { +class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryManagementInterface { type Module = ivySbt.Module override def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = { @@ -26,5 +26,5 @@ class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryMana object IvyLibraryManagement { def apply(ivyConfiguration: IvyConfiguration): LibraryManagement = - new IvyLibraryManagement(new IvySbt(ivyConfiguration)) + LibraryManagement(new IvyLibraryManagement(new IvySbt(ivyConfiguration))) } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index 323826fde..cc92e8bf9 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -6,7 +6,7 @@ import sbt.internal.librarymanagement._ import sbt.util.Logger import java.io.File -class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends Publisher { +class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface { type Module = ivySbt.Module override def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = { @@ -31,5 +31,5 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends Publisher { object IvyPublisher { def apply(ivyConfiguration: IvyConfiguration): Publisher = - new IvyPublisher(new IvySbt(ivyConfiguration)) + Publisher(new IvyPublisher(new IvySbt(ivyConfiguration))) } From 358b750dde39d675522bdba621d41de9d3841971 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 12 Jul 2017 08:02:25 -0400 Subject: [PATCH 0650/1030] turn back syntax classes into traits --- .../DependencyBuilders.scala | 7 ++++- .../librarymanagement/DependencyFilter.scala | 8 ++++++ .../LibraryManagementSyntax.scala | 27 ++++++++++++++----- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala index 5c4071dd5..09b1d8468 100755 --- a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -8,7 +8,12 @@ import sbt.internal.librarymanagement.StringUtilities.nonEmpty /** * DependencyBuilders implements the implicits for % and %% DSL. */ -abstract class DependencyBuilders { +trait DependencyBuilders { + // See http://www.scala-lang.org/news/2.12.0#traits-compile-to-interfaces + // Avoid defining fields (val or var, but a constant is ok – final val without result type) + // Avoid calling super + // Avoid initializer statements in the body + import DependencyBuilders._ implicit def stringToOrganization(organization: String): Organization = { diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 969271fe9..2f2adf763 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -6,6 +6,11 @@ package sbt.librarymanagement import sbt.io.{ AllPassFilter, NameFilter } trait DependencyFilterExtra { + // See http://www.scala-lang.org/news/2.12.0#traits-compile-to-interfaces + // Avoid defining fields (val or var, but a constant is ok – final val without result type) + // Avoid calling super + // Avoid initializer statements in the body + def moduleFilter( organization: NameFilter = AllPassFilter, name: NameFilter = AllPassFilter, @@ -15,6 +20,7 @@ trait DependencyFilterExtra { def apply(m: ModuleID): Boolean = organization.accept(m.organization) && name.accept(m.name) && revision.accept(m.revision) } + def artifactFilter( name: NameFilter = AllPassFilter, `type`: NameFilter = AllPassFilter, @@ -26,11 +32,13 @@ trait DependencyFilterExtra { name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier .accept(a.classifier getOrElse "") } + def configurationFilter(name: NameFilter = AllPassFilter): ConfigurationFilter = new ConfigurationFilter { def apply(c: ConfigRef): Boolean = name.accept(c.name) } } + object DependencyFilter extends DependencyFilterExtra { def make( configuration: ConfigurationFilter = configurationFilter(), diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala index c83911de0..8d177c835 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala @@ -1,13 +1,28 @@ package sbt.librarymanagement -abstract class LibraryManagementSyntax extends DependencyBuilders { - type ExclusionRule = InclExclRule - val ExclusionRule = InclExclRule - - type InclusionRule = InclExclRule - val InclusionRule = InclExclRule +trait LibraryManagementSyntax0 { + // See http://www.scala-lang.org/news/2.12.0#traits-compile-to-interfaces + // Avoid defining fields (val or var, but a constant is ok – final val without result type) + // Avoid calling super + // Avoid initializer statements in the body implicit def richUpdateReport(ur: UpdateReport): RichUpdateReport = new RichUpdateReport(ur) +} + +trait LibraryManagementSyntax + extends LibraryManagementSyntax0 + with DependencyBuilders + with DependencyFilterExtra { + // See http://www.scala-lang.org/news/2.12.0#traits-compile-to-interfaces + // Avoid defining fields (val or var, but a constant is ok – final val without result type) + // Avoid calling super + // Avoid initializer statements in the body + + type ExclusionRule = InclExclRule + final val ExclusionRule = InclExclRule + + type InclusionRule = InclExclRule + final val InclusionRule = InclExclRule import sbt.librarymanagement.{ Configurations => C } final val Compile = C.Compile From 0c28db9d210192a1f62bbb69c4883ff99b5254ab Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 12 Jul 2017 08:33:18 -0400 Subject: [PATCH 0651/1030] rename to DependencyResolutionInterface --- README.md | 4 ++-- ...ibraryManagement.scala => DependencyResolution.scala} | 8 ++++---- .../librarymanagement/LibraryManagementInterface.scala | 6 +++--- ...aryManagement.scala => IvyDependencyResolution.scala} | 9 +++++---- ivy/src/test/scala/BaseIvySpecification.scala | 4 ++-- 5 files changed, 16 insertions(+), 15 deletions(-) rename core/src/main/scala/sbt/librarymanagement/{LibraryManagement.scala => DependencyResolution.scala} (97%) rename ivy/src/main/scala/sbt/librarymanagement/ivy/{IvyLibraryManagement.scala => IvyDependencyResolution.scala} (70%) diff --git a/README.md b/README.md index d3e7f5c20..f8a089339 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,9 @@ log: sbt.internal.util.ManagedLogger = sbt.internal.util.ManagedLogger@c439b0f scala> val lm = { import sbt.librarymanagement.ivy._ val ivyConfig = InlineIvyConfiguration().withLog(log) - IvyLibraryManagement(ivyConfig) + IvyDependencyResolution(ivyConfig) } -lm: sbt.librarymanagement.LibraryManagement = sbt.librarymanagement.ivy.IvyLibraryManagement@11c07acb +lm: sbt.librarymanagement.DependencyResolution = sbt.librarymanagement.DependencyResolution@6a9b40f8 scala> val module = "commons-io" % "commons-io" % "2.5" module: sbt.librarymanagement.ModuleID = commons-io:commons-io:2.5 diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala similarity index 97% rename from core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala rename to core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index 54a3fa970..b2d5beb03 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagement.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -8,7 +8,7 @@ import sbt.librarymanagement.syntax._ /** * Library management API to resolve dependencies. */ -class LibraryManagement private[sbt] (lmEngine: LibraryManagementInterface) { +class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface) { import sbt.internal.librarymanagement.InternalDefaults._ import sbt.internal.librarymanagement.UpdateClassifiersUtil._ @@ -217,7 +217,7 @@ class LibraryManagement private[sbt] (lmEngine: LibraryManagementInterface) { }).mkString(", ") } -object LibraryManagement { - def apply(lmEngine: LibraryManagementInterface): LibraryManagement = - new LibraryManagement(lmEngine) +object DependencyResolution { + def apply(lmEngine: DependencyResolutionInterface): DependencyResolution = + new DependencyResolution(lmEngine) } diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 9af54bd06..6afc27e2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -4,9 +4,9 @@ import java.io.File import sbt.util.Logger /** - * Interface for library management intended for library management engine authors. + * Interface for dependency resolution intended for engine authors. */ -abstract class LibraryManagementInterface { +trait DependencyResolutionInterface { /** * Builds a ModuleDescriptor that describes a subproject with dependencies. @@ -35,7 +35,7 @@ abstract class LibraryManagementInterface { /** * Interface for publishing modules. */ -abstract class PublisherInterface { +trait PublisherInterface { /** * Builds a ModuleDescriptor that describes a subproject with dependencies. diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala similarity index 70% rename from ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala rename to ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index 3d591ea02..fd0fd259c 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyLibraryManagement.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -5,7 +5,8 @@ package ivy import sbt.internal.librarymanagement._ import sbt.util.Logger -class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryManagementInterface { +class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) + extends DependencyResolutionInterface { type Module = ivySbt.Module override def moduleDescriptor(moduleSetting: ModuleDescriptorConfiguration): ModuleDescriptor = { @@ -24,7 +25,7 @@ class IvyLibraryManagement private[sbt] (val ivySbt: IvySbt) extends LibraryMana } } -object IvyLibraryManagement { - def apply(ivyConfiguration: IvyConfiguration): LibraryManagement = - LibraryManagement(new IvyLibraryManagement(new IvySbt(ivyConfiguration))) +object IvyDependencyResolution { + def apply(ivyConfiguration: IvyConfiguration): DependencyResolution = + DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration))) } diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/BaseIvySpecification.scala index a4c1d4fda..4dd23afe3 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/BaseIvySpecification.scala @@ -18,8 +18,8 @@ trait BaseIvySpecification extends UnitSpec { ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) lazy val log = ConsoleLogger() - def lmEngine(uo: UpdateOptions = UpdateOptions()): LibraryManagement = - IvyLibraryManagement(mkIvyConfiguration(uo)) + def lmEngine(uo: UpdateOptions = UpdateOptions()): DependencyResolution = + IvyDependencyResolution(mkIvyConfiguration(uo)) def configurations = Vector(Compile, Test, Runtime) def module(moduleId: ModuleID, From c95a885a3a947503559fda8b29983303e2345780 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 14 Jul 2017 16:21:19 -0400 Subject: [PATCH 0652/1030] Bump to latest Contraband --- .../internal/librarymanagement/ConfigurationReportLite.scala | 2 +- .../sbt/internal/librarymanagement/UpdateReportLite.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Artifact.scala | 2 +- .../sbt/librarymanagement/ArtifactTypeFilter.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Binary.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Caller.scala | 2 +- .../sbt/librarymanagement/ChainedResolver.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Checksum.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/ConfigRef.scala | 2 +- .../sbt/librarymanagement/ConfigurationReport.scala | 2 +- .../sbt/librarymanagement/ConflictManager.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Constant.scala | 2 +- .../contraband-scala/sbt/librarymanagement/CrossVersion.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Developer.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Disabled.scala | 2 +- .../sbt/librarymanagement/FileConfiguration.scala | 2 +- .../contraband-scala/sbt/librarymanagement/FileRepository.scala | 2 +- core/src/main/contraband-scala/sbt/librarymanagement/Full.scala | 2 +- .../sbt/librarymanagement/GetClassifiersConfiguration.scala | 2 +- .../sbt/librarymanagement/GetClassifiersModule.scala | 2 +- .../contraband-scala/sbt/librarymanagement/InclExclRule.scala | 2 +- .../sbt/librarymanagement/IvyFileConfiguration.scala | 2 +- .../sbt/librarymanagement/KeyFileAuthentication.scala | 2 +- .../contraband-scala/sbt/librarymanagement/MavenCache.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/MavenRepo.scala | 2 +- .../sbt/librarymanagement/MavenRepository.scala | 2 +- .../sbt/librarymanagement/ModuleConfiguration.scala | 2 +- .../sbt/librarymanagement/ModuleDescriptorConfiguration.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/ModuleID.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ModuleInfo.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ModuleReport.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ModuleSettings.scala | 2 +- .../sbt/librarymanagement/OrganizationArtifactReport.scala | 2 +- .../sbt/librarymanagement/PasswordAuthentication.scala | 2 +- .../src/main/contraband-scala/sbt/librarymanagement/Patch.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Patterns.scala | 2 +- .../sbt/librarymanagement/PatternsBasedRepository.scala | 2 +- .../sbt/librarymanagement/PomConfiguration.scala | 2 +- .../sbt/librarymanagement/PublishConfiguration.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Resolver.scala | 2 +- .../sbt/librarymanagement/RetrieveConfiguration.scala | 2 +- .../sbt/librarymanagement/ScalaModuleInfo.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/ScmInfo.scala | 2 +- .../contraband-scala/sbt/librarymanagement/SftpRepository.scala | 2 +- .../sbt/librarymanagement/SshAuthentication.scala | 2 +- .../sbt/librarymanagement/SshBasedRepository.scala | 2 +- .../contraband-scala/sbt/librarymanagement/SshConnection.scala | 2 +- .../contraband-scala/sbt/librarymanagement/SshRepository.scala | 2 +- .../contraband-scala/sbt/librarymanagement/URLRepository.scala | 2 +- .../sbt/librarymanagement/UpdateConfiguration.scala | 2 +- .../contraband-scala/sbt/librarymanagement/UpdateReport.scala | 2 +- .../contraband-scala/sbt/librarymanagement/UpdateStats.scala | 2 +- .../sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala | 2 +- .../sbt/librarymanagement/ivy/InlineIvyConfiguration.scala | 2 +- .../sbt/librarymanagement/ivy/IvyConfiguration.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala | 2 +- project/plugins.sbt | 2 +- 57 files changed, 57 insertions(+), 57 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala index f63313b93..7570d3356 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala @@ -15,7 +15,7 @@ final class ConfigurationReportLite private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "ConfigurationReportLite".##) + configuration.##) + details.##) + 37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.ConfigurationReportLite".##) + configuration.##) + details.##) } override def toString: String = { "ConfigurationReportLite(" + configuration + ", " + details + ")" diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala index 4d927be08..350fff041 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala @@ -14,7 +14,7 @@ final class UpdateReportLite private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (17 + "UpdateReportLite".##) + configurations.##) + 37 * (37 * (17 + "sbt.internal.librarymanagement.UpdateReportLite".##) + configurations.##) } override def toString: String = { "UpdateReportLite(" + configurations + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index df5d51f0a..a676be246 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -21,7 +21,7 @@ final class Artifact private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) } override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala index 9b64bf71d..3086e498e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -22,7 +22,7 @@ final class ArtifactTypeFilter private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "ArtifactTypeFilter".##) + types.##) + inverted.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.ArtifactTypeFilter".##) + types.##) + inverted.##) } override def toString: String = { "ArtifactTypeFilter(" + types + ", " + inverted + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala index 323002dd7..f06902d22 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala @@ -21,7 +21,7 @@ final class Binary private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "Binary".##) + prefix.##) + suffix.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.Binary".##) + prefix.##) + suffix.##) } override def toString: String = { "Binary(" + prefix + ", " + suffix + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala index 3cfd92909..cbf57fa13 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -20,7 +20,7 @@ final class Caller private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "Caller".##) + caller.##) + callerConfigurations.##) + callerExtraAttributes.##) + isForceDependency.##) + isChangingDependency.##) + isTransitiveDependency.##) + isDirectlyForceDependency.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Caller".##) + caller.##) + callerConfigurations.##) + callerExtraAttributes.##) + isForceDependency.##) + isChangingDependency.##) + isTransitiveDependency.##) + isDirectlyForceDependency.##) } override def toString: String = { s"$caller" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index 75978cc04..19215a7c8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -15,7 +15,7 @@ final class ChainedResolver private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "ChainedResolver".##) + name.##) + resolvers.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.ChainedResolver".##) + name.##) + resolvers.##) } override def toString: String = { "ChainedResolver(" + name + ", " + resolvers + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala index dd2db5902..2a699be36 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala @@ -15,7 +15,7 @@ final class Checksum private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "Checksum".##) + digest.##) + `type`.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.Checksum".##) + digest.##) + `type`.##) } override def toString: String = { "Checksum(" + digest + ", " + `type` + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index 2fd00af21..78e47af49 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -16,7 +16,7 @@ final class ConfigRef private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (17 + "ConfigRef".##) + name.##) + 37 * (37 * (17 + "sbt.librarymanagement.ConfigRef".##) + name.##) } override def toString: String = { name diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index 5929ae95d..a11155f73 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -20,7 +20,7 @@ final class ConfigurationReport private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "ConfigurationReport".##) + configuration.##) + modules.##) + details.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ConfigurationReport".##) + configuration.##) + modules.##) + details.##) } override def toString: String = { s"\t$configuration:\n" + diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala index 84cfeefab..d7adb8829 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -17,7 +17,7 @@ final class ConflictManager private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "ConflictManager".##) + name.##) + organization.##) + module.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ConflictManager".##) + name.##) + organization.##) + module.##) } override def toString: String = { "ConflictManager(" + name + ", " + organization + ", " + module + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala index bca95bb25..25ca45c3b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala @@ -15,7 +15,7 @@ final class Constant private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (17 + "Constant".##) + value.##) + 37 * (37 * (17 + "sbt.librarymanagement.Constant".##) + value.##) } override def toString: String = { "Constant(" + value + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala index c1f658229..321be7615 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala @@ -15,7 +15,7 @@ override def equals(o: Any): Boolean = o match { case _ => false } override def hashCode: Int = { - 37 * (17 + "CrossVersion".##) + 37 * (17 + "sbt.librarymanagement.CrossVersion".##) } override def toString: String = { "CrossVersion()" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index 0689fccf4..d1c69eec9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -17,7 +17,7 @@ final class Developer private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "Developer".##) + id.##) + name.##) + email.##) + url.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Developer".##) + id.##) + name.##) + email.##) + url.##) } override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala index c1f3339d1..1c03d422e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala @@ -14,7 +14,7 @@ override def equals(o: Any): Boolean = o match { case _ => false } override def hashCode: Int = { - 37 * (17 + "Disabled".##) + 37 * (17 + "sbt.librarymanagement.Disabled".##) } override def toString: String = { "Disabled()" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala index c74be3197..4787d4bfb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala @@ -16,7 +16,7 @@ final class FileConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "FileConfiguration".##) + isLocal.##) + isTransactional.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.FileConfiguration".##) + isLocal.##) + isTransactional.##) } override def toString: String = { "FileConfiguration(" + isLocal + ", " + isTransactional + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala index 77d2d3068..8bbf9f976 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala @@ -18,7 +18,7 @@ final class FileRepository private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "FileRepository".##) + name.##) + patterns.##) + configuration.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.FileRepository".##) + name.##) + patterns.##) + configuration.##) } override def toString: String = { "FileRepository(" + name + ", " + patterns + ", " + configuration + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala index 3ad99a43e..c51ccd0db 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala @@ -21,7 +21,7 @@ final class Full private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "Full".##) + prefix.##) + suffix.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.Full".##) + prefix.##) + suffix.##) } override def toString: String = { "Full(" + prefix + ", " + suffix + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala index 6ef40d2b0..200aa87fe 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala @@ -18,7 +18,7 @@ final class GetClassifiersConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "GetClassifiersConfiguration".##) + module.##) + excludes.##) + updateConfiguration.##) + sourceArtifactTypes.##) + docArtifactTypes.##) + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.GetClassifiersConfiguration".##) + module.##) + excludes.##) + updateConfiguration.##) + sourceArtifactTypes.##) + docArtifactTypes.##) } override def toString: String = { "GetClassifiersConfiguration(" + module + ", " + excludes + ", " + updateConfiguration + ", " + sourceArtifactTypes + ", " + docArtifactTypes + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala index 22d70c167..147ba44ae 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala @@ -18,7 +18,7 @@ final class GetClassifiersModule private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "GetClassifiersModule".##) + id.##) + scalaModuleInfo.##) + dependencies.##) + configurations.##) + classifiers.##) + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.GetClassifiersModule".##) + id.##) + scalaModuleInfo.##) + dependencies.##) + configurations.##) + classifiers.##) } override def toString: String = { "GetClassifiersModule(" + id + ", " + scalaModuleInfo + ", " + dependencies + ", " + configurations + ", " + classifiers + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index dde013ed2..e93c8ac2c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -27,7 +27,7 @@ final class InclExclRule private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "InclExclRule".##) + organization.##) + name.##) + artifact.##) + configurations.##) + crossVersion.##) + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.InclExclRule".##) + organization.##) + name.##) + artifact.##) + configurations.##) + crossVersion.##) } override def toString: String = { "InclExclRule(" + organization + ", " + name + ", " + artifact + ", " + configurations + ", " + crossVersion + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala index 1f2c5b652..cd0a38aff 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -17,7 +17,7 @@ final class IvyFileConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "IvyFileConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.IvyFileConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) } override def toString: String = { "IvyFileConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala index 33742d372..e696a61d4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala @@ -16,7 +16,7 @@ final class KeyFileAuthentication private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "KeyFileAuthentication".##) + user.##) + keyfile.##) + password.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.KeyFileAuthentication".##) + user.##) + keyfile.##) + password.##) } override def toString: String = { "KeyFileAuthentication(" + user + ", " + keyfile + ", " + password + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index 5ecbb9173..a99bb5da9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -22,7 +22,7 @@ final class MavenCache private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "MavenCache".##) + name.##) + root.##) + localIfFile.##) + rootFile.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenCache".##) + name.##) + root.##) + localIfFile.##) + rootFile.##) } override def toString: String = { s"cache:$name: ${rootFile.getAbsolutePath}" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index 1374e2d0b..f964670f1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -16,7 +16,7 @@ final class MavenRepo private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "MavenRepo".##) + name.##) + root.##) + localIfFile.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) } override def toString: String = { s"$name: $root" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala index b3487a7d4..f1bbb608c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -18,7 +18,7 @@ abstract class MavenRepository( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "MavenRepository".##) + name.##) + root.##) + localIfFile.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepository".##) + name.##) + root.##) + localIfFile.##) } override def toString: String = { "MavenRepository(" + name + ", " + root + ", " + localIfFile + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala index 7198727a9..38accc410 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala @@ -17,7 +17,7 @@ final class ModuleConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "ModuleConfiguration".##) + organization.##) + name.##) + revision.##) + resolver.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleConfiguration".##) + organization.##) + name.##) + revision.##) + resolver.##) } override def toString: String = { "ModuleConfiguration(" + organization + ", " + name + ", " + revision + ", " + resolver + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 3c1213b4c..92c7a3a92 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -24,7 +24,7 @@ final class ModuleDescriptorConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleDescriptorConfiguration".##) + validate.##) + scalaModuleInfo.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleDescriptorConfiguration".##) + validate.##) + scalaModuleInfo.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) } override def toString: String = { "ModuleDescriptorConfiguration(" + validate + ", " + scalaModuleInfo + ", " + module + ", " + moduleInfo + ", " + dependencies + ", " + overrides + ", " + excludes + ", " + ivyXML + ", " + configurations + ", " + defaultConfiguration + ", " + conflictManager + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index 4e117921e..822f7d2d6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -26,7 +26,7 @@ final class ModuleID private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) } override def toString: String = { this.toStringImpl diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index ef9dc5ac1..ae7d42f5c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -23,7 +23,7 @@ final class ModuleInfo private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleInfo".##) + nameFormal.##) + description.##) + homepage.##) + startYear.##) + licenses.##) + organizationName.##) + organizationHomepage.##) + scmInfo.##) + developers.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleInfo".##) + nameFormal.##) + description.##) + homepage.##) + startYear.##) + licenses.##) + organizationName.##) + organizationHomepage.##) + scmInfo.##) + developers.##) } override def toString: String = { "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 13f44f54e..0c2526b1d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -35,7 +35,7 @@ final class ModuleReport private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ModuleReport".##) + module.##) + artifacts.##) + missingArtifacts.##) + status.##) + publicationDate.##) + resolver.##) + artifactResolver.##) + evicted.##) + evictedData.##) + evictedReason.##) + problem.##) + homepage.##) + extraAttributes.##) + isDefault.##) + branch.##) + configurations.##) + licenses.##) + callers.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleReport".##) + module.##) + artifacts.##) + missingArtifacts.##) + status.##) + publicationDate.##) + resolver.##) + artifactResolver.##) + evicted.##) + evictedData.##) + evictedReason.##) + problem.##) + homepage.##) + extraAttributes.##) + isDefault.##) + branch.##) + configurations.##) + licenses.##) + callers.##) } override def toString: String = { s"\t\t$module: " + diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala index 95f9e8be7..2ce752c29 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala @@ -16,7 +16,7 @@ abstract class ModuleSettings( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "ModuleSettings".##) + validate.##) + scalaModuleInfo.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleSettings".##) + validate.##) + scalaModuleInfo.##) } override def toString: String = { "ModuleSettings(" + validate + ", " + scalaModuleInfo + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index daceb5658..3b62b191a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -27,7 +27,7 @@ final class OrganizationArtifactReport private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) } override def toString: String = { "OrganizationArtifactReport(" + organization + ", " + name + ", " + modules + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala index ff71e1e0a..a67739cc5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala @@ -15,7 +15,7 @@ final class PasswordAuthentication private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "PasswordAuthentication".##) + user.##) + password.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.PasswordAuthentication".##) + user.##) + password.##) } override def toString: String = { "PasswordAuthentication(" + user + ", " + password + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala index f6cefff42..ffdf666eb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala @@ -17,7 +17,7 @@ override def equals(o: Any): Boolean = o match { case _ => false } override def hashCode: Int = { - 37 * (17 + "Patch".##) + 37 * (17 + "sbt.librarymanagement.Patch".##) } override def toString: String = { "Patch()" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala index 5457c8a4a..ea43d5525 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -18,7 +18,7 @@ final class Patterns private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "Patterns".##) + ivyPatterns.##) + artifactPatterns.##) + isMavenCompatible.##) + descriptorOptional.##) + skipConsistencyCheck.##) + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Patterns".##) + ivyPatterns.##) + artifactPatterns.##) + isMavenCompatible.##) + descriptorOptional.##) + skipConsistencyCheck.##) } override def toString: String = { "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format( diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala index 8354c6b44..93e624284 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala @@ -17,7 +17,7 @@ abstract class PatternsBasedRepository( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "PatternsBasedRepository".##) + name.##) + patterns.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.PatternsBasedRepository".##) + name.##) + patterns.##) } override def toString: String = { "PatternsBasedRepository(" + name + ", " + patterns + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala index 92b367e95..93fdbc39c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -17,7 +17,7 @@ final class PomConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "PomConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.PomConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) } override def toString: String = { "PomConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala index 8c6481d07..8dcd7d7aa 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -22,7 +22,7 @@ final class PublishConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "PublishConfiguration".##) + publishMavenStyle.##) + deliverIvyPattern.##) + status.##) + configurations.##) + resolverName.##) + artifacts.##) + checksums.##) + logging.##) + overwrite.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.PublishConfiguration".##) + publishMavenStyle.##) + deliverIvyPattern.##) + status.##) + configurations.##) + resolverName.##) + artifacts.##) + checksums.##) + logging.##) + overwrite.##) } override def toString: String = { "PublishConfiguration(" + publishMavenStyle + ", " + deliverIvyPattern + ", " + status + ", " + configurations + ", " + resolverName + ", " + artifacts + ", " + checksums + ", " + logging + ", " + overwrite + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index 792d0daa6..c6caf7eaf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -15,7 +15,7 @@ abstract class Resolver( case _ => false } override def hashCode: Int = { - 37 * (37 * (17 + "Resolver".##) + name.##) + 37 * (37 * (17 + "sbt.librarymanagement.Resolver".##) + name.##) } override def toString: String = { "Resolver(" + name + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala index dbd6c9312..7a063b474 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -18,7 +18,7 @@ final class RetrieveConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) } override def toString: String = { "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index f3867aecc..73afbfcb9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -21,7 +21,7 @@ final class ScalaModuleInfo private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) } override def toString: String = { "ScalaModuleInfo(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 701bfc4b1..19766ac5e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -17,7 +17,7 @@ final class ScmInfo private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "ScmInfo".##) + browseUrl.##) + connection.##) + devConnection.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScmInfo".##) + browseUrl.##) + connection.##) + devConnection.##) } override def toString: String = { "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala index b2a4fe6fc..63734d7ef 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala @@ -18,7 +18,7 @@ final class SftpRepository private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "SftpRepository".##) + name.##) + patterns.##) + connection.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SftpRepository".##) + name.##) + patterns.##) + connection.##) } override def toString: String = { "SftpRepository(" + name + ", " + patterns + ", " + connection + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala index 96b0ec553..af49207c4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala @@ -14,7 +14,7 @@ override def equals(o: Any): Boolean = o match { case _ => false } override def hashCode: Int = { - 37 * (17 + "SshAuthentication".##) + 37 * (17 + "sbt.librarymanagement.SshAuthentication".##) } override def toString: String = { "SshAuthentication()" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala index 484b74778..958439832 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala @@ -18,7 +18,7 @@ abstract class SshBasedRepository( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "SshBasedRepository".##) + name.##) + patterns.##) + connection.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshBasedRepository".##) + name.##) + patterns.##) + connection.##) } override def toString: String = { "SshBasedRepository(" + name + ", " + patterns + ", " + connection + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala index 185d9b8f5..5e105ebef 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala @@ -16,7 +16,7 @@ final class SshConnection private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "SshConnection".##) + authentication.##) + hostname.##) + port.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshConnection".##) + authentication.##) + hostname.##) + port.##) } override def toString: String = { "SshConnection(" + authentication + ", " + hostname + ", " + port + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala index 9a65cfeae..ca7af27ed 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala @@ -19,7 +19,7 @@ final class SshRepository private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "SshRepository".##) + name.##) + patterns.##) + connection.##) + publishPermissions.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshRepository".##) + name.##) + patterns.##) + connection.##) + publishPermissions.##) } override def toString: String = { "SshRepository(" + name + ", " + patterns + ", " + connection + ", " + publishPermissions + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 2120a339b..41a52e655 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -15,7 +15,7 @@ final class URLRepository private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "URLRepository".##) + name.##) + patterns.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) } override def toString: String = { "URLRepository(" + name + ", " + patterns + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index 234d826ad..b62d6e719 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -32,7 +32,7 @@ final class UpdateConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "UpdateConfiguration".##) + retrieveManaged.##) + missingOk.##) + logging.##) + logicalClock.##) + metadataDirectory.##) + artifactFilter.##) + offline.##) + frozen.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateConfiguration".##) + retrieveManaged.##) + missingOk.##) + logging.##) + logicalClock.##) + metadataDirectory.##) + artifactFilter.##) + offline.##) + frozen.##) } override def toString: String = { "UpdateConfiguration(" + retrieveManaged + ", " + missingOk + ", " + logging + ", " + logicalClock + ", " + metadataDirectory + ", " + artifactFilter + ", " + offline + ", " + frozen + ")" diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 00b9e8225..91da13639 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -25,7 +25,7 @@ final class UpdateReport private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "UpdateReport".##) + cachedDescriptor.##) + configurations.##) + stats.##) + stamps.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateReport".##) + cachedDescriptor.##) + configurations.##) + stats.##) + stamps.##) } override def toString: String = { "Update report:\n\t" + stats + "\n" + configurations.mkString diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala index 6b33803da..408223e24 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala @@ -17,7 +17,7 @@ final class UpdateStats private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (17 + "UpdateStats".##) + resolveTime.##) + downloadTime.##) + downloadSize.##) + cached.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateStats".##) + resolveTime.##) + downloadTime.##) + downloadSize.##) + cached.##) } override def toString: String = { Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala index 1a0dac7db..02456951f 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -19,7 +19,7 @@ final class ExternalIvyConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "ExternalIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + baseDirectory.##) + uri.##) + extraResolvers.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.ExternalIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + baseDirectory.##) + uri.##) + extraResolvers.##) } override def toString: String = { "ExternalIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + baseDirectory + ", " + uri + ", " + extraResolvers + ")" diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index 61360fde3..0d781c437 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -23,7 +23,7 @@ final class InlineIvyConfiguration private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "InlineIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.InlineIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) } override def toString: String = { "InlineIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + paths + ", " + resolvers + ", " + otherResolvers + ", " + moduleConfigurations + ", " + checksums + ", " + managedChecksums + ", " + resolutionCacheDir + ")" diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala index cfc5e6448..9ca6e9dd0 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala @@ -17,7 +17,7 @@ abstract class IvyConfiguration( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "IvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.IvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) } override def toString: String = { "IvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ")" diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index ca3b51086..562419c40 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -15,7 +15,7 @@ final class IvyPaths private ( case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "IvyPaths".##) + baseDirectory.##) + ivyHome.##) + 37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.IvyPaths".##) + baseDirectory.##) + ivyHome.##) } override def toString: String = { "IvyPaths(" + baseDirectory + ", " + ivyHome + ")" diff --git a/project/plugins.sbt b/project/plugins.sbt index ae33ece34..e5b186e6d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M7") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0") addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") From 1d2f4d02cf3e78439969b429197074a8e8e99f6d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 Jul 2017 11:19:14 -0400 Subject: [PATCH 0653/1030] Remove transitiveScratch This is used only by sbt, and we are not sure if it needs to be part of the API --- .../DependencyResolution.scala | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index b2d5beb03..f9f2f41cc 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -136,26 +136,6 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface } } - def transitiveScratch( - label: String, - config: GetClassifiersConfiguration, - uwconfig: UnresolvedWarningConfiguration, - log: Logger - ): Either[UnresolvedWarning, UpdateReport] = { - import config.{ updateConfiguration => c, module => mod } - import mod.{ id, dependencies => deps, scalaModuleInfo } - val base = restrictedCopy(id, true).withName(id.name + "$" + label) - val module = moduleDescriptor(base, deps, scalaModuleInfo) - val report = update(module, c, uwconfig, log) match { - case Right(r) => r - case Left(w) => - throw w.resolveException - } - val newConfig = config - .withModule(mod.withDependencies(report.allModules)) - updateClassifiers(newConfig, uwconfig, Vector(), log) - } - /** * Creates explicit artifacts for each classifier in `config.module`, and then attempts to resolve them directly. This * is for Maven compatibility, where these artifacts are not "published" in the POM, so they don't end up in the Ivy From a09af23cc654a4de15eb9b53155e5a61b92f6f42 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 Jul 2017 12:00:21 -0400 Subject: [PATCH 0654/1030] Builder pattern for MakePomConfiguration --- .../MakePomConfiguration.scala | 141 ++++++++++++++++-- .../librarymanagement/IvyActions.scala | 6 +- 2 files changed, 134 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala index 1beb16003..87f0a5cc5 100644 --- a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -3,13 +3,134 @@ package sbt.librarymanagement import java.io.File import scala.xml.{ Node => XNode, NodeSeq } -final class MakePomConfiguration( - val file: File, - val moduleInfo: ModuleInfo, - val configurations: Option[Vector[Configuration]] = None, - val extra: NodeSeq = NodeSeq.Empty, - val process: XNode => XNode = n => n, - val filterRepositories: MavenRepository => Boolean = _ => true, - val allRepositories: Boolean, - val includeTypes: Set[String] = Set(Artifact.DefaultType, Artifact.PomType) -) +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +final class MakePomConfiguration private (val file: Option[File], + val moduleInfo: Option[ModuleInfo], + val configurations: Option[Vector[Configuration]], + val extra: Option[NodeSeq], + val process: XNode => XNode, + val filterRepositories: MavenRepository => Boolean, + val allRepositories: Boolean, + val includeTypes: Set[String]) + extends Serializable { + private def this() = + this(None, + None, + None, + None, + identity, + MakePomConfiguration.constTrue, + true, + Set(Artifact.DefaultType, Artifact.PomType)) + + override def equals(o: Any): Boolean = o match { + case x: MakePomConfiguration => + (this.file == x.file) && (this.moduleInfo == x.moduleInfo) && (this.configurations == x.configurations) && (this.extra == x.extra) && (this.process == x.process) && (this.filterRepositories == x.filterRepositories) && (this.allRepositories == x.allRepositories) && (this.includeTypes == x.includeTypes) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MakePomConfiguration".##) + file.##) + moduleInfo.##) + configurations.##) + extra.##) + process.##) + filterRepositories.##) + allRepositories.##) + includeTypes.##) + } + override def toString: String = { + "MakePomConfiguration(" + file + ", " + moduleInfo + ", " + configurations + ", " + extra + ", " + process + ", " + filterRepositories + ", " + allRepositories + ", " + includeTypes + ")" + } + protected[this] def copy(file: Option[File] = file, + moduleInfo: Option[ModuleInfo] = moduleInfo, + configurations: Option[Vector[Configuration]] = configurations, + extra: Option[NodeSeq] = extra, + process: XNode => XNode = process, + filterRepositories: MavenRepository => Boolean = filterRepositories, + allRepositories: Boolean = allRepositories, + includeTypes: Set[String] = includeTypes): MakePomConfiguration = { + new MakePomConfiguration(file, + moduleInfo, + configurations, + extra, + process, + filterRepositories, + allRepositories, + includeTypes) + } + def withFile(file: Option[File]): MakePomConfiguration = { + copy(file = file) + } + def withFile(file: File): MakePomConfiguration = { + copy(file = Option(file)) + } + def withModuleInfo(moduleInfo: Option[ModuleInfo]): MakePomConfiguration = { + copy(moduleInfo = moduleInfo) + } + def withModuleInfo(moduleInfo: ModuleInfo): MakePomConfiguration = { + copy(moduleInfo = Option(moduleInfo)) + } + def withConfigurations(configurations: Option[Vector[Configuration]]): MakePomConfiguration = { + copy(configurations = configurations) + } + def withExtra(extra: Option[NodeSeq]): MakePomConfiguration = { + copy(extra = extra) + } + def withExtra(extra: NodeSeq): MakePomConfiguration = { + copy(extra = Option(extra)) + } + def withProcess(process: XNode => XNode): MakePomConfiguration = { + copy(process = process) + } + def withFilterRepositories( + filterRepositories: MavenRepository => Boolean): MakePomConfiguration = { + copy(filterRepositories = filterRepositories) + } + def withAllRepositories(allRepositories: Boolean): MakePomConfiguration = { + copy(allRepositories = allRepositories) + } + def withIncludeTypes(includeTypes: Set[String]): MakePomConfiguration = { + copy(includeTypes = includeTypes) + } +} + +object MakePomConfiguration { + private[sbt] lazy val constTrue: MavenRepository => Boolean = _ => true + + def apply(): MakePomConfiguration = + new MakePomConfiguration(None, + None, + None, + None, + identity, + constTrue, + true, + Set(Artifact.DefaultType, Artifact.PomType)) + def apply(file: Option[File], + moduleInfo: Option[ModuleInfo], + configurations: Option[Vector[Configuration]], + extra: Option[NodeSeq], + process: XNode => XNode, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean, + includeTypes: Set[String]): MakePomConfiguration = + new MakePomConfiguration(file, + moduleInfo, + configurations, + extra, + process, + filterRepositories, + allRepositories, + includeTypes) + def apply(file: File, + moduleInfo: ModuleInfo, + configurations: Vector[Configuration], + extra: NodeSeq, + process: XNode => XNode, + filterRepositories: MavenRepository => Boolean, + allRepositories: Boolean, + includeTypes: Set[String]): MakePomConfiguration = + new MakePomConfiguration(Option(file), + Option(moduleInfo), + Option(configurations), + Option(extra), + process, + filterRepositories, + allRepositories, + includeTypes) +} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 4aa761d66..e62d7b0ca 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -59,14 +59,14 @@ object IvyActions { def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = { import configuration.{ allRepositories, - moduleInfo, configurations, - extra, - file, filterRepositories, process, includeTypes } + val file = configuration.file.getOrElse(sys.error("file must be specified.")) + val moduleInfo = configuration.moduleInfo.getOrElse(sys.error("moduleInfo must be specified.")) + val extra = configuration.extra.getOrElse(scala.xml.NodeSeq.Empty) module.withModule(log) { (ivy, md, default) => (new MakePom(log)).write( ivy, From 509c80c8a704e0bac9625f6040d5ffa4cdfb9bff Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 Jul 2017 13:52:10 -0400 Subject: [PATCH 0655/1030] Bump to latest IO and Util --- .../main/scala/sbt/internal/librarymanagement/IvyCache.scala | 2 +- ivy/src/test/scala/DMSerializationSpec.scala | 2 +- project/Dependencies.scala | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index cdabbd94c..c17aa283d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -20,7 +20,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.util.Logger -import scalajson.ast.unsafe._ +import sjsonnew.shaded.scalajson.ast.unsafe._ import scala.collection.mutable import jawn.{ SupportParser, MutableFacade } diff --git a/ivy/src/test/scala/DMSerializationSpec.scala b/ivy/src/test/scala/DMSerializationSpec.scala index d38c8fcdb..937fa3537 100644 --- a/ivy/src/test/scala/DMSerializationSpec.scala +++ b/ivy/src/test/scala/DMSerializationSpec.scala @@ -4,7 +4,7 @@ import java.net.URL import java.io.File import sbt.internal._, librarymanagement._ -import scalajson.ast.unsafe._ +import sjsonnew.shaded.scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ import org.scalatest.Assertion diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 264d23e13..57048034a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.2" - private val ioVersion = "1.0.0-M12" - private val utilVersion = "1.0.0-M26" + private val ioVersion = "1.0.0-M13" + private val utilVersion = "1.0.0-M27" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From c61a690109b2874a2aaa3dbacc1aaad20a048931 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 17 Jul 2017 11:03:08 +0100 Subject: [PATCH 0656/1030] Improve config-creating macro error message Fixes #130 --- .../main/scala/sbt/librarymanagement/ConfigurationExtra.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 6f19e572b..83cdd2bcd 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -109,7 +109,7 @@ private[sbt] object ConfigurationMacro { val enclosingValName = definingValName( c, methodName => - s"""$methodName must be directly assigned to a val, such as `val x = $methodName`.""") + s"""$methodName must be directly assigned to a val, such as `val Tooling = $methodName("tooling")`.""") val id = c.Expr[String](Literal(Constant(enclosingValName))) reify { Configuration.of(id.splice, name.splice) } } From d004e9e31a72d8c3826ff00f89d7ec74ee4d377c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 19 Jul 2017 21:32:39 -0400 Subject: [PATCH 0657/1030] sbt 1.0.0-RC2 --- .travis.yml | 4 +++- build.sbt | 4 ++-- project/build.properties | 2 +- project/plugins.sbt | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 20ffdf8b7..7b9d62d48 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,7 +6,9 @@ scala: - 2.12.2 script: - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" +# drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt +# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test" cache: directories: diff --git a/build.sbt b/build.sbt index 9fbe4fa00..e249b949f 100644 --- a/build.sbt +++ b/build.sbt @@ -41,9 +41,9 @@ lazy val lmRoot = (project in file(".")) url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git" )), bintrayPackage := "librarymanagement", - scalafmtOnCompile := true, + // scalafmtOnCompile := true, // scalafmtVersion 1.0.0-RC3 has regression - scalafmtVersion := "0.6.8", + // scalafmtVersion := "0.6.8", git.baseVersion := baseVersion, version := { val v = version.value diff --git a/project/build.properties b/project/build.properties index cd66fd542..c9e698a14 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0-M6 +sbt.version=1.0.0-RC2 diff --git a/project/plugins.sbt b/project/plugins.sbt index e5b186e6d..3023a6dc1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") -addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0") -addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") + +// addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") scalacOptions += "-language:postfixOps" From c5c20db754274f110388606646240243d12939cc Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 20 Jul 2017 11:13:52 +0100 Subject: [PATCH 0658/1030] Add Constant aliases to CrossVersion --- .../main/scala/sbt/librarymanagement/CrossVersionExtra.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 93c28a199..a57a9f4f3 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -10,9 +10,11 @@ abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary + final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full final val Patch = sbt.librarymanagement.Patch type Binary = sbt.librarymanagement.Binary + type Constant = sbt.librarymanagement.Constant type Full = sbt.librarymanagement.Full type Patch = sbt.librarymanagement.Patch From 8c3955258bc16053b422054d0055503685189315 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 20 Jul 2017 11:32:24 +0100 Subject: [PATCH 0659/1030] Revert "sbt 1.0.0-RC2" --- .travis.yml | 4 +--- build.sbt | 4 ++-- project/build.properties | 2 +- project/plugins.sbt | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b9d62d48..20ffdf8b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,7 @@ scala: - 2.12.2 script: -# drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt -# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" cache: directories: diff --git a/build.sbt b/build.sbt index e249b949f..9fbe4fa00 100644 --- a/build.sbt +++ b/build.sbt @@ -41,9 +41,9 @@ lazy val lmRoot = (project in file(".")) url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git" )), bintrayPackage := "librarymanagement", - // scalafmtOnCompile := true, + scalafmtOnCompile := true, // scalafmtVersion 1.0.0-RC3 has regression - // scalafmtVersion := "0.6.8", + scalafmtVersion := "0.6.8", git.baseVersion := baseVersion, version := { val v = version.value diff --git a/project/build.properties b/project/build.properties index c9e698a14..cd66fd542 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0-RC2 +sbt.version=1.0.0-M6 diff --git a/project/plugins.sbt b/project/plugins.sbt index 3023a6dc1..e5b186e6d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") - -// addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") +addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.4.0") +addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") scalacOptions += "-language:postfixOps" From 66b8863d799607e2535cbc7d9757f3b206e01b8f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 20 Jul 2017 17:13:35 +0100 Subject: [PATCH 0660/1030] Add, configure & enable MiMa --- .travis.yml | 4 ++-- build.sbt | 8 +++++++- project/plugins.sbt | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7b9d62d48..2a123e73c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,8 @@ scala: script: # drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt -# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test;scalafmt::test;test:scalafmt::test" - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION test" +# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test;scalafmt::test;test:scalafmt::test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test" cache: directories: diff --git a/build.sbt b/build.sbt index e249b949f..326830172 100644 --- a/build.sbt +++ b/build.sbt @@ -30,6 +30,10 @@ def commonSettings: Seq[Setting[_]] = Seq( parallelExecution in Test := false ) +val mimaSettings = Def settings ( + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-X18") +) + lazy val lmRoot = (project in file(".")) .aggregate(lmCore, lmIvy) .settings( @@ -91,7 +95,8 @@ lazy val lmCore = (project in file("core")) val sdirs = (managedSourceDirectories in Compile).value val base = baseDirectory.value (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) - } + }, + mimaSettings, ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -107,6 +112,7 @@ lazy val lmIvy = (project in file("ivy")) sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), + mimaSettings, ) def customCommands: Seq[Setting[_]] = Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 3023a6dc1..86d334893 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,5 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.14") scalacOptions += "-language:postfixOps" From 26fa1c5f4bd6a727deb493d9c0f187f168706cfa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 23 Jul 2017 02:34:36 -0400 Subject: [PATCH 0661/1030] Fixes sbtApiVersion logic The NonRelease pattern matcher is ony checking for the third segment, but for sbt 1.x, we need to check both the second and third segment since 1.1.0-M1 would be bincompat with 1.0. Fixes sbt/sbt#3360 --- .../librarymanagement/cross/CrossVersionUtil.scala | 11 +++++++---- ivy/src/test/scala/CrossVersionTest.scala | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index b9d4cc2dd..b9e784a51 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -36,10 +36,13 @@ object CrossVersionUtil { * Compatible versions include 0.12.0-1 and 0.12.0-RC1 for Some(0, 12). */ private[sbt] def sbtApiVersion(v: String): Option[(Long, Long)] = v match { - case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) - case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) - case NonReleaseV_n(x, y, z, _) if z.toInt > 0 => Some(sbtApiVersion(x.toLong, y.toLong)) - case _ => None + case ReleaseV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case CandidateV(x, y, _, _) => Some(sbtApiVersion(x.toLong, y.toLong)) + case NonReleaseV_n(x, y, z, _) if x.toLong == 0 && z.toLong > 0 => + Some(sbtApiVersion(x.toLong, y.toLong)) + case NonReleaseV_n(x, y, z, _) if x.toLong > 0 && (y.toLong > 0 || z.toLong > 0) => + Some(sbtApiVersion(x.toLong, y.toLong)) + case _ => None } private def sbtApiVersion(x: Long, y: Long) = { diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/ivy/src/test/scala/CrossVersionTest.scala index b2c52a732..5ba8d8b72 100644 --- a/ivy/src/test/scala/CrossVersionTest.scala +++ b/ivy/src/test/scala/CrossVersionTest.scala @@ -135,6 +135,9 @@ class CrossVersionTest extends UnitSpec { it should "for 1.3.0 return 1.0" in { binarySbtVersion("1.3.0") shouldBe "1.0" } + it should "for 1.3.0-SNAPSHOT return 1.0" in { + binarySbtVersion("1.3.0-SNAPSHOT") shouldBe "1.0" + } it should "for 1.10.0 return 1.0" in { binarySbtVersion("1.10.0") shouldBe "1.0" } From 3db33720a943aca1c5f6e3bdd8ca5d63eb3d6041 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Jul 2017 05:16:42 -0400 Subject: [PATCH 0662/1030] Use IvyAuthenticator and JavaNetAuthenticator Fixes sbt/sbt#3331 The siatuation is a bit complicated. Currently the credentials are stored in Ivy's credential store. This needs to be translated into `java.net.Authenticator` by installing `IvyAuthenticator` and `ErrorMessageAuthenticator` in succession. This, then, needs to be translated into OkHttp Authenticator using `okhttp3.JavaNetAuthenticator`. --- .../scala/sbt/librarymanagement/Http.scala | 6 -- .../ivyint/GigahorseUrlHandler.scala | 55 +++++++++++++++++-- 2 files changed, 49 insertions(+), 12 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 3fee33b82..9870d9b0f 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,13 +1,7 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse -import okhttp3.{ OkUrlFactory, OkHttpClient } -import java.net.{ URL, HttpURLConnection } object Http { lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) - - private[sbt] lazy val urlFactory = new OkUrlFactory(http.underlying[OkHttpClient]) - private[sbt] def open(url: URL): HttpURLConnection = - urlFactory.open(url) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 6603919b5..69ab22cf7 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -4,9 +4,8 @@ package ivyint import java.net.{ URL, UnknownHostException, HttpURLConnection } import java.io.{ File, IOException, InputStream, ByteArrayOutputStream, ByteArrayInputStream } import org.apache.ivy.util.{ CopyProgressListener, Message, FileUtil } -import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler } +import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler, IvyAuthenticator } import org.apache.ivy.util.url.URLHandler._ -import sbt.librarymanagement.Http import sbt.io.{ IO, Using } // Copied from Ivy's BasicURLHandler. @@ -24,8 +23,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { * if the url is not reachable. */ def getURLInfo(url0: URL, timeout: Int): URLInfo = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val con = Http.open(url) + val con = GigahorseUrlHandler.open(url) val infoOption = try { con match { case httpCon: HttpURLConnection => @@ -65,8 +70,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def openStream(url0: URL): InputStream = { + // Install the ErrorMessageAuthenticator + if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val url = normalizeToURL(url0) - val conn = Http.open(url) + val conn = GigahorseUrlHandler.open(url) conn.setRequestProperty("Accept-Encoding", "gzip,deflate") conn match { case httpCon: HttpURLConnection => @@ -91,8 +102,14 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { + // Install the ErrorMessageAuthenticator + if ("http" == src0.getProtocol() || "https" == src0.getProtocol()) { + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + } + val src = normalizeToURL(src0) - val srcConn = Http.open(src) + val srcConn = GigahorseUrlHandler.open(src) srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate") srcConn match { case httpCon: HttpURLConnection => @@ -126,8 +143,16 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { + if( ("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { + throw new UnsupportedOperationException( + "URL repository only support HTTP PUT at the moment") + } + + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() + val dest = normalizeToURL(dest0) - val conn = Http.open(dest) match { + val conn = GigahorseUrlHandler.open(dest) match { case c: HttpURLConnection => c } conn.setDoOutput(true) @@ -169,3 +194,21 @@ class GigahorseUrlHandler extends AbstractURLHandler { } } } + +object GigahorseUrlHandler { + import gigahorse._, support.okhttp.Gigahorse + import okhttp3.{ OkUrlFactory, OkHttpClient, JavaNetAuthenticator } + + lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + + private[sbt] def urlFactory = { + val client0 = http.underlying[OkHttpClient] + val client = client0.newBuilder() + .authenticator(new JavaNetAuthenticator) + .build + new OkUrlFactory(client) + } + + private[sbt] def open(url: URL): HttpURLConnection = + urlFactory.open(url) +} From ace8d88f9fb4a41c5ff64e58d5fe7bd2ad015788 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 04:09:44 -0400 Subject: [PATCH 0663/1030] Filter out ":: loading settings" Fixes sbt/sbt#3287 I'm not sure why we started to see these messages, but given that their info is mapped to our info, it kind of makes sense that it is surfacing. The fix is hacky, but it should work. --- .../internal/librarymanagement/IvyLogger.scala | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index f178a95f0..29f61222a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -7,7 +7,7 @@ import org.apache.ivy.util.{ Message, MessageLogger, MessageLoggerEngine } import sbt.util.Logger /** Interface to Ivy logging. */ -private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { +private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def rawlog(msg: String, level: Int): Unit = log(msg, level) def log(msg: String, level: Int): Unit = { import Message.{ MSG_DEBUG, MSG_VERBOSE, MSG_INFO, MSG_WARN, MSG_ERR } @@ -24,7 +24,7 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def debug(msg: String): Unit = () def verbose(msg: String): Unit = logger.verbose(msg) def deprecated(msg: String): Unit = warn(msg) - def info(msg: String): Unit = logger.info(msg) + def info(msg: String): Unit = if (SbtIvyLogger.acceptInfo(msg)) logger.info(msg) def rawinfo(msg: String): Unit = info(msg) def warn(msg: String): Unit = logger.warn(msg) def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) logger.error(msg) @@ -43,13 +43,16 @@ private final class IvyLoggerInterface(logger: Logger) extends MessageLogger { def isShowProgress = false def setShowProgress(progress: Boolean): Unit = () } -private final class SbtMessageLoggerEngine extends MessageLoggerEngine { +private[sbt] final class SbtMessageLoggerEngine extends MessageLoggerEngine { /** This is a hack to filter error messages about 'unknown resolver ...'. */ override def error(msg: String): Unit = if (SbtIvyLogger.acceptError(msg)) super.error(msg) override def sumupProblems(): Unit = clearProblems() } -private object SbtIvyLogger { - val UnknownResolver = "unknown resolver" - def acceptError(msg: String) = (msg ne null) && !msg.startsWith(UnknownResolver) +private[sbt] object SbtIvyLogger { + final val unknownResolver = "unknown resolver" + def acceptError(msg: String) = (msg ne null) && !msg.startsWith(unknownResolver) + + final val loadingSettings = ":: loading settings" + def acceptInfo(msg: String) = (msg ne null) && !msg.startsWith(loadingSettings) } From 22f47be292135a4d7118cd03732dca434b293bf2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 17:19:45 -0400 Subject: [PATCH 0664/1030] Change overwrite warning Previously the warning read: Attempting to overwrite $destination This usage is deprecated and will be removed in sbt 1.0. This is an empty threat since we did not remove the feature. I'm replacing it with: Attempting to overwrite $destination (non-SNAPSHOT) You need to remove it from the cache manually to take effect. Fixes sbt/sbt#3271 --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index f31d223d3..a90399b8b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -400,10 +400,11 @@ private[sbt] object ConvertResolver { try super.put(source, destination, overwrite) catch { case e: java.io.IOException if e.getMessage.contains("destination already exists") => + val overwriteWarning = + if (destination contains "-SNAPSHOT") s"Attempting to overwrite $destination" + else "Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." import org.apache.ivy.util.Message - Message.warn( - s"Attempting to overwrite $destination\n\tThis usage is deprecated and will be removed in sbt 1.0." - ) + Message.warn(overwriteWarning) super.put(source, destination, true) } } From 1512d73a076820b3f50ece9107a80a4737408143 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 26 Jul 2017 11:40:54 +0100 Subject: [PATCH 0665/1030] Upgrade to mima 0.1.15 & add exclusions --- build.sbt | 17 ++++++++++++++--- project/plugins.sbt | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 326830172..91c79119e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,6 @@ import Dependencies._ import Path._ - -// import com.typesafe.tools.mima.core._, ProblemFilters._ +import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "1.0.0-SNAPSHOT" @@ -24,7 +23,6 @@ def commonSettings: Seq[Setting[_]] = Seq( case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } }, - // mimaPreviousArtifacts := Set(), // Some(organization.value %% moduleName.value % "1.0.0"), publishArtifact in Compile := true, publishArtifact in Test := false, parallelExecution in Test := false @@ -97,6 +95,14 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // method urlFactory()okhttp3.OkUrlFactory in object sbt.librarymanagement.Http does not have a correspondent in current version + // Was private[sbt] and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.urlFactory"), + // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version + // Was private[sbt] and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -113,6 +119,11 @@ lazy val lmIvy = (project in file("ivy")) contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // method UnknownResolver()java.lang.String in object sbt.internal.librarymanagement.SbtIvyLogger does not have a correspondent in current version + // Was in a private object in sbt.internal and manually checked to be unused in Zinc or sbt + ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.SbtIvyLogger.UnknownResolver") + ) ) def customCommands: Seq[Setting[_]] = Seq( diff --git a/project/plugins.sbt b/project/plugins.sbt index 86d334893..12fc4e3b1 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,6 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.14") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") scalacOptions += "-language:postfixOps" From 93c06d29b1f84eece613c51273438fa9dec04a99 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 25 Jul 2017 16:58:40 -0400 Subject: [PATCH 0666/1030] Implement better fake formats than ??? Fixes sbt/librarymanagement#67 Fixes sbt/sbt#3288 --- .../formats/GlobalLockFormat.scala | 19 ++++++++++++++++++- .../formats/LoggerFormat.scala | 10 +++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala index 2f4342d24..fffd9b6a8 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala @@ -2,7 +2,24 @@ package sbt.internal.librarymanagement.formats import sjsonnew._ import xsbti._ +import java.io.File +import java.util.concurrent.Callable +/** + * A fake JsonFormat for xsbti.GlobalLock. + * This is mostly for making IvyConfiguration serializable to JSON. + */ trait GlobalLockFormat { self: BasicJsonProtocol => - implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = ??? + import GlobalLockFormats._ + + implicit lazy val globalLockIsoString: IsoString[GlobalLock] = + IsoString.iso(_ => "", _ => NoGlobalLock) + + implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = implicitly +} + +private[sbt] object GlobalLockFormats { + object NoGlobalLock extends GlobalLock { + def apply[T](lockFile: File, run: Callable[T]) = run.call() + } } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala index b751672bd..954b48127 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala @@ -2,7 +2,15 @@ package sbt.internal.librarymanagement.formats import sjsonnew._ import xsbti._ +import sbt.util.Logger.Null +/** + * A fake JsonFormat for xsbti.Logger. + * This is mostly for making IvyConfiguration serializable to JSON. + */ trait LoggerFormat { self: BasicJsonProtocol => - implicit lazy val LoggerFormat: JsonFormat[Logger] = ??? + implicit lazy val xsbtiLoggerIsoString: IsoString[Logger] = + IsoString.iso(_ => "", _ => Null) + + implicit lazy val LoggerFormat: JsonFormat[Logger] = implicitly } From d6e2720201f2209a2f7eb0b1c500321a176f4be0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 01:37:01 -0400 Subject: [PATCH 0667/1030] Let `ModuleDescriptor` declare cache inputs --- build.sbt | 2 + .../LibraryManagementInterface.scala | 10 +++ .../sbt/internal/librarymanagement/Ivy.scala | 73 ++++++++++++++++++- 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 91c79119e..3debd56b2 100644 --- a/build.sbt +++ b/build.sbt @@ -102,6 +102,8 @@ lazy val lmCore = (project in file("core")) // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + // New methods added to LM API + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 6afc27e2d..33c72c55f 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -81,4 +81,14 @@ trait ModuleDescriptor { * if any. */ def scalaModuleInfo: Option[ScalaModuleInfo] + + /** + * The input parameters used to construct the `ModuleSettings`. + */ + def moduleSettings: ModuleSettings + + /** + * Hash for extra parameter that were not captured as `moduleSettings`. + */ + def extraInputHash: Long } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 86c1ef5f2..dcf5f3327 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -36,10 +36,12 @@ import org.apache.ivy.util.extendable.ExtendableItem import org.apache.ivy.util.url._ import scala.xml.NodeSeq import scala.collection.mutable -import sbt.util.Logger +import scala.util.{ Success, Failure } +import sbt.util._ import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } import sbt.librarymanagement.ivy._ import sbt.librarymanagement.syntax._ + import IvyInternalDefaults._ import Resolver.PluginPattern import ivyint.{ @@ -49,6 +51,8 @@ import ivyint.{ SbtDefaultDependencyDescriptor, GigahorseUrlHandler } +import sjsonnew.JsonFormat +import sjsonnew.support.murmurhash.Hasher final class IvySbt(val configuration: IvyConfiguration) { self => /* @@ -336,6 +340,73 @@ final class IvySbt(val configuration: IvyConfiguration) { self => ) } private def toURL(file: File) = file.toURI.toURL + + // Todo: We just need writing side of this codec. We can clean up the reads. + private[sbt] object AltLibraryManagementCodec extends IvyLibraryManagementCodec { + import sbt.io.Hash + type InlineIvyHL = (Option[IvyPaths], Vector[Resolver], Vector[Resolver], Vector[ + ModuleConfiguration], Vector[String], Boolean) + def inlineIvyToHL(i: InlineIvyConfiguration): InlineIvyHL = + (i.paths, i.resolvers, i.otherResolvers, i.moduleConfigurations, + i.checksums, i.managedChecksums) + + type ExternalIvyHL = (Option[PlainFileInfo], Array[Byte]) + def externalIvyToHL(e: ExternalIvyConfiguration): ExternalIvyHL = + (e.baseDirectory.map(FileInfo.exists.apply), + e.uri.map(Hash.contentsIfLocal).getOrElse(Array.empty)) + + // Redefine to use a subset of properties, that are serialisable + override implicit lazy val InlineIvyConfigurationFormat: JsonFormat[InlineIvyConfiguration] = { + def hlToInlineIvy(i: InlineIvyHL): InlineIvyConfiguration = { + val (paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums) = i + InlineIvyConfiguration() + .withPaths(paths) + .withResolvers(resolvers) + .withOtherResolvers(otherResolvers) + .withModuleConfigurations(moduleConfigurations) + .withManagedChecksums(managedChecksums) + .withChecksums(checksums) + } + projectFormat[InlineIvyConfiguration, InlineIvyHL](inlineIvyToHL, hlToInlineIvy) + } + + // Redefine to use a subset of properties, that are serialisable + override implicit lazy val ExternalIvyConfigurationFormat + : JsonFormat[ExternalIvyConfiguration] = { + def hlToExternalIvy(e: ExternalIvyHL): ExternalIvyConfiguration = { + val (baseDirectory, _) = e + ExternalIvyConfiguration( + None, + Some(NullLogger), + UpdateOptions(), + baseDirectory.map(_.file), + None /* the original uri is destroyed.. */, + Vector.empty + ) + } + projectFormat[ExternalIvyConfiguration, ExternalIvyHL](externalIvyToHL, hlToExternalIvy) + } + + // Redefine to switch to unionFormat + override implicit lazy val IvyConfigurationFormat: JsonFormat[IvyConfiguration] = + unionFormat2[IvyConfiguration, InlineIvyConfiguration, ExternalIvyConfiguration] + + object NullLogger extends sbt.internal.util.BasicLogger { + override def control(event: sbt.util.ControlEvent.Value, message: ⇒ String): Unit = () + override def log(level: Level.Value, message: ⇒ String): Unit = () + override def logAll(events: Seq[sbt.util.LogEvent]): Unit = () + override def success(message: ⇒ String): Unit = () + override def trace(t: ⇒ Throwable): Unit = () + } + } + + def extraInputHash: Long = { + import AltLibraryManagementCodec._ + Hasher.hash(owner.configuration) match { + case Success(keyHash) => keyHash.toLong + case Failure(_) => 0L + } + } } } From 208b8e427932f41bb17c0a7b6f2767622306ecae Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 02:00:17 -0400 Subject: [PATCH 0668/1030] Exclude ReversedMissingMethodProblem sbt.internal.librarymanagement.formats.* --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 3debd56b2..144eb0a9a 100644 --- a/build.sbt +++ b/build.sbt @@ -104,6 +104,8 @@ lazy val lmCore = (project in file("core")) ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), // New methods added to LM API ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), + // New formats for Logger and GlockLock + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.*"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) From f976c6824b8ce0e8dec26c584a60f12806af0a39 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 02:11:20 -0400 Subject: [PATCH 0669/1030] Name the reverse missing methods --- build.sbt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 144eb0a9a..6830f8389 100644 --- a/build.sbt +++ b/build.sbt @@ -103,7 +103,9 @@ lazy val lmCore = (project in file("core")) // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.*"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.moduleSettings"), + // New methods added to LM API + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.extraInputHash"), // New formats for Logger and GlockLock ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.*"), ) From 749a1c9a9b8b4eea3dbfd7550269a65733fb67fa Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 28 Jul 2017 07:18:27 +0100 Subject: [PATCH 0670/1030] Fix MiMa failures --- build.sbt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/build.sbt b/build.sbt index 91c79119e..a34ca446e 100644 --- a/build.sbt +++ b/build.sbt @@ -102,6 +102,15 @@ lazy val lmCore = (project in file("core")) // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version // Was private[sbt] and manually checked to be unused in Zinc or sbt ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), + + // method globalLockIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.GlobalLockFormat is present only in current version + // method xsbtiLoggerIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.LoggerFormat is present only in current version + // These only fail in Scala 2.11 + // We're _probably_ ok to add these between sbt 1 RC2 and RC3, + // but it's dangerous territory in general + // see typesafehub/migration-manager#183 for an example of what happens.. + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.GlobalLockFormat.globalLockIsoString"), + ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.LoggerFormat.xsbtiLoggerIsoString"), ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) From 8f912301be4d6e7bda6188fc8ec5ce51911d161d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 28 Jul 2017 07:56:02 +0100 Subject: [PATCH 0671/1030] Upgrade to Scala 2.12.3 --- .travis.yml | 2 +- project/Dependencies.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a123e73c..b63e2b2f4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ jdk: oraclejdk8 scala: - 2.11.11 - - 2.12.2 + - 2.12.3 script: # drop scalafmt on the 1.0.0 branch to dogfood 1.0.0-RC2 before there is a sbt 1.0 of new-sbt-scalafnt diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 57048034a..1bca36c6f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala211 = "2.11.11" - val scala212 = "2.12.2" + val scala212 = "2.12.3" private val ioVersion = "1.0.0-M13" private val utilVersion = "1.0.0-M27" From 52923854cc5ba87e0737664fcd66e19c5ec46d1f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 27 Jul 2017 15:55:47 +0100 Subject: [PATCH 0672/1030] Make sure UpdateReport has a nice toString Fixes sbt/sbt#3357 --- .../OrganizationArtifactReport.scala | 3 +- .../main/contraband/librarymanagement.json | 4 ++ core/src/test/scala/UpdateReportSpec.scala | 41 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 core/src/test/scala/UpdateReportSpec.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index 3b62b191a..112c4708b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -30,7 +30,8 @@ final class OrganizationArtifactReport private ( 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) } override def toString: String = { - "OrganizationArtifactReport(" + organization + ", " + name + ", " + modules + ")" + val details = modules map { _.detailReport } + s"\t$organization:$name\n${details.mkString}\n" } protected[this] def copy(organization: String = organization, name: String = name, modules: Vector[sbt.librarymanagement.ModuleReport] = modules): OrganizationArtifactReport = { new OrganizationArtifactReport(organization, name, modules) diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index fa7506f95..c7a04ede8 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -596,6 +596,10 @@ { "name": "organization", "type": "String" }, { "name": "name", "type": "String" }, { "name": "modules", "type": "sbt.librarymanagement.ModuleReport*" } + ], + "toString": [ + "val details = modules map { _.detailReport }", + "s\"\\t$organization:$name\\n${details.mkString}\\n\"" ] }, { diff --git a/core/src/test/scala/UpdateReportSpec.scala b/core/src/test/scala/UpdateReportSpec.scala new file mode 100644 index 000000000..cc7dfd7fd --- /dev/null +++ b/core/src/test/scala/UpdateReportSpec.scala @@ -0,0 +1,41 @@ +package sbt.librarymanagement + +import java.io.File + +import org.scalatest._ + +class UpdateReportSpec extends FlatSpec with Matchers { + "UpdateReport.toString" should "have a nice toString" in { + assert(updateReport.toString === s""" + |Update report: + | Resolve time: 0 ms, Download time: 0 ms, Download size: 0 bytes + | compile: + | org:name + | - 1.0 + | evicted: false + | + |""".stripMargin.drop(1)) + } + + lazy val updateReport = + UpdateReport( + new File("cachedDescriptor.data"), + Vector(configurationReport), + UpdateStats(0, 0, 0, false), + Map.empty + ) + + lazy val configurationReport = + ConfigurationReport( + ConfigRef("compile"), + Vector(moduleReport), + Vector(organizationArtifactReport) + ) + + lazy val moduleReport = + ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) + + lazy val organizationArtifactReport = + OrganizationArtifactReport("org", "name", Vector(moduleReport)) + +} From 831e99bd59d977134b51ef2f3f9cc7f5e254aa9d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 12:47:41 -0400 Subject: [PATCH 0673/1030] Contraband 0.3.0 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 12fc4e3b1..fa1b88965 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0-M9") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") From 0a42cf07498e9aefd0c078f9e7fd861653bfcb4a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Jul 2017 12:47:57 -0400 Subject: [PATCH 0674/1030] IO 1.0.0-RC3, Util 1.0.0-RC3 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1bca36c6f..428f3786a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.3" - private val ioVersion = "1.0.0-M13" - private val utilVersion = "1.0.0-M27" + private val ioVersion = "1.0.0-RC3" + private val utilVersion = "1.0.0-RC3" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 8e8f9a5380854d5511c7d25995be3e1cba229cf7 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 31 Jul 2017 11:39:05 +0100 Subject: [PATCH 0675/1030] Bump mimaPreviousArtifacts to 1.0.0-RC3 --- build.sbt | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/build.sbt b/build.sbt index 9f96c390e..2b2b4bd16 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import Dependencies._ import Path._ -import com.typesafe.tools.mima.core._, ProblemFilters._ +//import com.typesafe.tools.mima.core._, ProblemFilters._ def baseVersion = "1.0.0-SNAPSHOT" @@ -29,7 +29,7 @@ def commonSettings: Seq[Setting[_]] = Seq( ) val mimaSettings = Def settings ( - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-X18") + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-RC3") ) lazy val lmRoot = (project in file(".")) @@ -82,7 +82,6 @@ lazy val lmCore = (project in file("core")) version.value, resourceManaged.value, streams.value, (compile in Compile).value ) ).taskValue, - // mimaBinaryIssueFilters ++= Seq(), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", @@ -95,26 +94,6 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, - mimaBinaryIssueFilters ++= Seq( - // method urlFactory()okhttp3.OkUrlFactory in object sbt.librarymanagement.Http does not have a correspondent in current version - // Was private[sbt] and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.urlFactory"), - // method open(java.net.URL)java.net.HttpURLConnection in object sbt.librarymanagement.Http does not have a correspondent in current version - // Was private[sbt] and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Http.open"), - // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.moduleSettings"), - // New methods added to LM API - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptor.extraInputHash"), - // method globalLockIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.GlobalLockFormat is present only in current version - // method xsbtiLoggerIsoString()sjsonnew.IsoString in trait sbt.internal.librarymanagement.formats.LoggerFormat is present only in current version - // These only fail in Scala 2.11 - // We're _probably_ ok to add these between sbt 1 RC2 and RC3, - // but it's dangerous territory in general - // see typesafehub/migration-manager#183 for an example of what happens.. - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.GlobalLockFormat.globalLockIsoString"), - ProblemFilters.exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.formats.LoggerFormat.xsbtiLoggerIsoString"), - ) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -131,11 +110,6 @@ lazy val lmIvy = (project in file("ivy")) contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, - mimaBinaryIssueFilters ++= Seq( - // method UnknownResolver()java.lang.String in object sbt.internal.librarymanagement.SbtIvyLogger does not have a correspondent in current version - // Was in a private object in sbt.internal and manually checked to be unused in Zinc or sbt - ProblemFilters.exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.SbtIvyLogger.UnknownResolver") - ) ) def customCommands: Seq[Setting[_]] = Seq( From 14cc1c56e2f11f286d0b94d26df794b0ac381b73 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 31 Jul 2017 14:54:52 +0100 Subject: [PATCH 0676/1030] Upgrade to sbt 1.0.0-RC3 --- project/build.properties | 2 +- project/plugins.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index c9e698a14..12c38d389 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0-RC2 +sbt.version=1.0.0-RC3 diff --git a/project/plugins.sbt b/project/plugins.sbt index fa1b88965..7ddf08986 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,6 +2,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") // addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.15") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") scalacOptions += "-language:postfixOps" From f45a07624121d7457dd533fc17ebace2dfd576b9 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 4 Aug 2017 12:03:11 +0100 Subject: [PATCH 0677/1030] Make sure UpdateReport has a nice toString^2 Fixes sbt/sbt#3357 --- .../sbt/librarymanagement/UpdateReportExtra.scala | 7 ++++++- core/src/test/scala/UpdateReportSpec.scala | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index a97441cfd..12a8fbf69 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -61,7 +61,7 @@ abstract class ModuleReportExtra { s"\t\t- ${module.revision}\n" + (if (arts.size <= 1) "" else arts.mkString("\t\t\t", "\n\t\t\t", "\n")) + reportStr("status", status) + - reportStr("publicationDate", publicationDate map { _.toString }) + + reportStr("publicationDate", publicationDate map calendarToString) + reportStr("resolver", resolver) + reportStr("artifactResolver", artifactResolver) + reportStr("evicted", Some(evicted.toString)) + @@ -96,6 +96,11 @@ abstract class ModuleReportExtra { s"\t\t\t$key: $x\n" } getOrElse "" + private[this] def calendarToString(c: ju.Calendar): String = { + import sjsonnew._, BasicJsonProtocol._ + implicitly[IsoString[ju.Calendar]] to c + } + def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) diff --git a/core/src/test/scala/UpdateReportSpec.scala b/core/src/test/scala/UpdateReportSpec.scala index cc7dfd7fd..12d7e70ca 100644 --- a/core/src/test/scala/UpdateReportSpec.scala +++ b/core/src/test/scala/UpdateReportSpec.scala @@ -12,6 +12,7 @@ class UpdateReportSpec extends FlatSpec with Matchers { | compile: | org:name | - 1.0 + | publicationDate: 1970-01-01T00:00:00Z | evicted: false | |""".stripMargin.drop(1)) @@ -32,10 +33,18 @@ class UpdateReportSpec extends FlatSpec with Matchers { Vector(organizationArtifactReport) ) - lazy val moduleReport = + lazy val moduleReport = ( ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) + withPublicationDate Some(epochCalendar) + ) lazy val organizationArtifactReport = OrganizationArtifactReport("org", "name", Vector(moduleReport)) + val epochCalendar: java.util.Calendar = { + val utc = java.util.TimeZone getTimeZone "UTC" + val c = new java.util.GregorianCalendar(utc, java.util.Locale.ENGLISH) + c setTimeInMillis 0L + c + } } From 3258e7b41343f2bbb8e3ef7a61e9ee3f223724ee Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 9 Aug 2017 21:14:57 -0400 Subject: [PATCH 0678/1030] IO 1.0.0, Util 1.0.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 428f3786a..9f92915e6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.11" val scala212 = "2.12.3" - private val ioVersion = "1.0.0-RC3" - private val utilVersion = "1.0.0-RC3" + private val ioVersion = "1.0.0" + private val utilVersion = "1.0.0" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 63e63f05fac24a284870b74c82610fba1ec1a9d7 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 10 Aug 2017 11:56:43 +0100 Subject: [PATCH 0679/1030] Add back, re-configure & re-enable Scalafmt --- .scalafmt.conf | 8 --- .travis.yml | 4 +- build.sbt | 51 +++++++++++-------- .../cross/CrossVersionUtil.scala | 2 +- .../librarymanagement/EvictionWarning.scala | 3 +- .../scala/sbt/librarymanagement/Extra.scala | 3 +- .../MakePomConfiguration.scala | 3 +- .../sbt/librarymanagement/VersionNumber.scala | 3 +- .../librarymanagement/ConvertResolver.scala | 9 ++-- .../sbt/internal/librarymanagement/Ivy.scala | 38 +++++++++++--- .../CachedResolutionResolveEngine.scala | 5 +- .../ivyint/GigahorseUrlHandler.scala | 20 ++++---- ivy/src/test/scala/VersionNumberSpec.scala | 3 +- project/Dependencies.scala | 8 ++- project/Util.scala | 3 +- project/plugins.sbt | 5 +- 16 files changed, 91 insertions(+), 77 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 0d5990db2..e4ab36511 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -8,11 +8,3 @@ docstrings = JavaDoc # This also seems more idiomatic to include whitespace in import x.{ yyy } spaces.inImportCurlyBraces = true - -# This works around sequence wildcard (`_*`) turning into `_ *` -spaces.beforeSeqWildcard = true - -# Vertical alignment only => for pattern matching -align.tokens.add = [ - { code = "=>", owner = "Case" } -] diff --git a/.travis.yml b/.travis.yml index 3856d1e3d..f899b658c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,7 @@ scala: - 2.12.3 script: -# drop scalafmt to dogfood latest 1.0.0-RC before there is an sbt 1.0 release of new-sbt-scalafmt -# - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test;scalafmt::test;test:scalafmt::test" - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;test" + - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;scalafmt::test;test:scalafmt::test;sbt:scalafmt::test;test" cache: directories: diff --git a/build.sbt b/build.sbt index 2b2b4bd16..8b2911f74 100644 --- a/build.sbt +++ b/build.sbt @@ -18,7 +18,8 @@ def commonSettings: Seq[Setting[_]] = Seq( scalacOptions := { val old = scalacOptions.value scalaVersion.value match { - case sv if sv.startsWith("2.10") => old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") + case sv if sv.startsWith("2.10") => + old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } @@ -39,13 +40,13 @@ lazy val lmRoot = (project in file(".")) Seq( homepage := Some(url("https://github.com/sbt/librarymanagement")), description := "Library management module for sbt", - scmInfo := Some(ScmInfo( - url("https://github.com/sbt/librarymanagement"), "git@github.com:sbt/librarymanagement.git" - )), + scmInfo := { + val slug = "sbt/librarymanagement" + Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) + }, bintrayPackage := "librarymanagement", - // scalafmtOnCompile := true, - // scalafmtVersion 1.0.0-RC3 has regression - // scalafmtVersion := "0.6.8", + scalafmtOnCompile := true, + scalafmtVersion := "1.1.0", git.baseVersion := baseVersion, version := { val v = version.value @@ -67,21 +68,28 @@ lazy val lmCore = (project in file("core")) .settings( commonSettings, name := "librarymanagement-core", - libraryDependencies ++= Seq(jsch, - scalaReflect.value, - scalaCompiler.value, - launcherInterface, - gigahorseOkhttp, - okhttpUrlconnection, - sjsonnewScalaJson.value % Optional, - scalaTest, - scalaCheck), + libraryDependencies ++= Seq( + jsch, + scalaReflect.value, + scalaCompiler.value, + launcherInterface, + gigahorseOkhttp, + okhttpUrlconnection, + sjsonnewScalaJson.value % Optional, + scalaTest, + scalaCheck + ), libraryDependencies ++= scalaXml.value, - resourceGenerators in Compile += Def.task( - Util.generateVersionFile( - version.value, resourceManaged.value, streams.value, (compile in Compile).value + resourceGenerators in Compile += Def + .task( + Util.generateVersionFile( + version.value, + resourceManaged.value, + streams.value, + (compile in Compile).value + ) ) - ).taskValue, + .taskValue, managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", @@ -108,7 +116,8 @@ lazy val lmIvy = (project in file("ivy")) baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, - scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), + scalacOptions in (Compile, console) --= + Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, ) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index b9e784a51..c95f035f1 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -42,7 +42,7 @@ object CrossVersionUtil { Some(sbtApiVersion(x.toLong, y.toLong)) case NonReleaseV_n(x, y, z, _) if x.toLong > 0 && (y.toLong > 0 || z.toLong > 0) => Some(sbtApiVersion(x.toLong, y.toLong)) - case _ => None + case _ => None } private def sbtApiVersion(x: Long, y: Long) = { diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 36aebaccb..ba0a1318e 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -83,8 +83,7 @@ object EvictionWarningOptions { defaultGuess ) - lazy val defaultGuess - : Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = + lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessSecondSegment orElse guessSemVer orElse guessFalse lazy val guessSecondSegment : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { diff --git a/core/src/main/scala/sbt/librarymanagement/Extra.scala b/core/src/main/scala/sbt/librarymanagement/Extra.scala index 8c6eebf16..03d0971f7 100644 --- a/core/src/main/scala/sbt/librarymanagement/Extra.scala +++ b/core/src/main/scala/sbt/librarymanagement/Extra.scala @@ -17,8 +17,7 @@ abstract class InclExclRuleFunctions { apply(organization.organization) implicit def stringToExclusionRule(organization: String): InclExclRule = apply(organization) - implicit def organizationArtifactNameToExclusionRule( - oa: OrganizationArtifactName): InclExclRule = + implicit def organizationArtifactNameToExclusionRule(oa: OrganizationArtifactName): InclExclRule = InclExclRule(oa.organization, oa.name, "*", Vector.empty, oa.crossVersion) implicit def moduleIDToExclusionRule(moduleID: ModuleID): InclExclRule = { diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala index 87f0a5cc5..b8e7b46fc 100644 --- a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -77,8 +77,7 @@ final class MakePomConfiguration private (val file: Option[File], def withProcess(process: XNode => XNode): MakePomConfiguration = { copy(process = process) } - def withFilterRepositories( - filterRepositories: MavenRepository => Boolean): MakePomConfiguration = { + def withFilterRepositories(filterRepositories: MavenRepository => Boolean): MakePomConfiguration = { copy(filterRepositories = filterRepositories) } def withAllRepositories(allRepositories: Boolean): MakePomConfiguration = { diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 144b67a66..f6a95527c 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -145,8 +145,7 @@ object VersionNumber { case (v1, v2) if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { - case (x1 @ _, y1 @ _, 0, ts1, x2 @ _, y2 @ _, 0, ts2) - if ts1.nonEmpty || ts2.nonEmpty => + case (x1 @ _, y1 @ _, 0, ts1, x2 @ _, y2 @ _, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers equalsIgnoreExtra(v1, v2) case (x1, y1, _, _, x2, y2, _, _) => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index a90399b8b..30b8c8b1b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -9,11 +9,7 @@ import java.util.Collections import org.apache.ivy.core.module.descriptor.DependencyDescriptor import org.apache.ivy.core.resolve.ResolveData import org.apache.ivy.core.settings.IvySettings -import org.apache.ivy.plugins.repository.{ - RepositoryCopyProgressListener, - Resource, - TransferEvent -} +import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, Resource, TransferEvent } import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver, @@ -402,7 +398,8 @@ private[sbt] object ConvertResolver { case e: java.io.IOException if e.getMessage.contains("destination already exists") => val overwriteWarning = if (destination contains "-SNAPSHOT") s"Attempting to overwrite $destination" - else "Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." + else + "Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." import org.apache.ivy.util.Message Message.warn(overwriteWarning) super.put(source, destination, true) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index dcf5f3327..c2b5b6cfb 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -344,21 +344,43 @@ final class IvySbt(val configuration: IvyConfiguration) { self => // Todo: We just need writing side of this codec. We can clean up the reads. private[sbt] object AltLibraryManagementCodec extends IvyLibraryManagementCodec { import sbt.io.Hash - type InlineIvyHL = (Option[IvyPaths], Vector[Resolver], Vector[Resolver], Vector[ - ModuleConfiguration], Vector[String], Boolean) + type InlineIvyHL = ( + Option[IvyPaths], + Vector[Resolver], + Vector[Resolver], + Vector[ModuleConfiguration], + Vector[String], + Boolean + ) def inlineIvyToHL(i: InlineIvyConfiguration): InlineIvyHL = - (i.paths, i.resolvers, i.otherResolvers, i.moduleConfigurations, - i.checksums, i.managedChecksums) + ( + i.paths, + i.resolvers, + i.otherResolvers, + i.moduleConfigurations, + i.checksums, + i.managedChecksums + ) type ExternalIvyHL = (Option[PlainFileInfo], Array[Byte]) def externalIvyToHL(e: ExternalIvyConfiguration): ExternalIvyHL = - (e.baseDirectory.map(FileInfo.exists.apply), - e.uri.map(Hash.contentsIfLocal).getOrElse(Array.empty)) + ( + e.baseDirectory.map(FileInfo.exists.apply), + e.uri.map(Hash.contentsIfLocal).getOrElse(Array.empty) + ) // Redefine to use a subset of properties, that are serialisable - override implicit lazy val InlineIvyConfigurationFormat: JsonFormat[InlineIvyConfiguration] = { + override implicit lazy val InlineIvyConfigurationFormat + : JsonFormat[InlineIvyConfiguration] = { def hlToInlineIvy(i: InlineIvyHL): InlineIvyConfiguration = { - val (paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums) = i + val ( + paths, + resolvers, + otherResolvers, + moduleConfigurations, + checksums, + managedChecksums + ) = i InlineIvyConfiguration() .withPaths(paths) .withResolvers(resolvers) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 4cebabdc4..75616642f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -21,10 +21,7 @@ import core.module.descriptor.{ ExcludeRule, IncludeRule } -import core.module.descriptor.{ - OverrideDependencyDescriptorMediator, - DependencyArtifactDescriptor -} +import core.module.descriptor.{ OverrideDependencyDescriptorMediator, DependencyArtifactDescriptor } import core.IvyPatternHelper import org.apache.ivy.util.{ Message, MessageLogger } import org.apache.ivy.plugins.latest.{ ArtifactInfo => IvyArtifactInfo } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 69ab22cf7..af5c74a83 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -25,8 +25,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { def getURLInfo(url0: URL, timeout: Int): URLInfo = { // Install the ErrorMessageAuthenticator if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() } val url = normalizeToURL(url0) @@ -72,8 +72,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { def openStream(url0: URL): InputStream = { // Install the ErrorMessageAuthenticator if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() } val url = normalizeToURL(url0) @@ -104,8 +104,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { // Install the ErrorMessageAuthenticator if ("http" == src0.getProtocol() || "https" == src0.getProtocol()) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() + IvyAuthenticator.install() + ErrorMessageAuthenticator.install() } val src = normalizeToURL(src0) @@ -143,9 +143,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { } def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { - if( ("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { - throw new UnsupportedOperationException( - "URL repository only support HTTP PUT at the moment") + if (("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { + throw new UnsupportedOperationException("URL repository only support HTTP PUT at the moment") } IvyAuthenticator.install() @@ -203,7 +202,8 @@ object GigahorseUrlHandler { private[sbt] def urlFactory = { val client0 = http.underlying[OkHttpClient] - val client = client0.newBuilder() + val client = client0 + .newBuilder() .authenticator(new JavaNetAuthenticator) .build new OkUrlFactory(client) diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/ivy/src/test/scala/VersionNumberSpec.scala index 4c1b8497a..b7fcdaa4c 100644 --- a/ivy/src/test/scala/VersionNumberSpec.scala +++ b/ivy/src/test/scala/VersionNumberSpec.scala @@ -97,7 +97,8 @@ class VersionNumberSpec extends UnitSpec { } it should "cascade" in generateCorrectCascadingNumbers( "1.0.0-alpha+001+002", - Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) + Seq("1.0.0-alpha+001+002", "1.0.0", "1.0") + ) "non.space.!?string" should "be parsed" in { beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string")) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9f92915e6..fae131ba4 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -47,8 +47,12 @@ object Dependencies { val scalaXml = scala211Module("scala-xml", "1.0.5") val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" % Test - val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } - val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } + val sjsonnew = Def.setting { + "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value + } + val sjsonnewScalaJson = Def.setting { + "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value + } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" diff --git a/project/Util.scala b/project/Util.scala index 62be2772b..5dacc7df8 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -26,8 +26,7 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" - if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, - version)) { + if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 7ddf08986..f82b39957 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") - -// addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.3") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") +addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.10") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") scalacOptions += "-language:postfixOps" From df108f7c7890bf0448b8ae27c37e07e6ee9b1ea0 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 14 Aug 2017 15:29:06 +0100 Subject: [PATCH 0680/1030] Scalafmt 1.2.0 --- build.sbt | 2 +- .../scala/sbt/librarymanagement/MakePomConfiguration.scala | 4 +++- .../sbt/internal/librarymanagement/FakeResolver.scala | 5 ++++- .../scala/sbt/internal/librarymanagement/IvyCache.scala | 7 ++++++- .../librarymanagement/ivyint/MergeDescriptors.scala | 4 +++- .../librarymanagement/ivyint/SbtChainResolver.scala | 5 ++++- 6 files changed, 21 insertions(+), 6 deletions(-) diff --git a/build.sbt b/build.sbt index 8b2911f74..df1473920 100644 --- a/build.sbt +++ b/build.sbt @@ -46,7 +46,7 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile := true, - scalafmtVersion := "1.1.0", + scalafmtVersion := "1.2.0", git.baseVersion := baseVersion, version := { val v = version.value diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala index b8e7b46fc..aec1c2a07 100644 --- a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -77,7 +77,9 @@ final class MakePomConfiguration private (val file: Option[File], def withProcess(process: XNode => XNode): MakePomConfiguration = { copy(process = process) } - def withFilterRepositories(filterRepositories: MavenRepository => Boolean): MakePomConfiguration = { + def withFilterRepositories( + filterRepositories: MavenRepository => Boolean + ): MakePomConfiguration = { copy(filterRepositories = filterRepositories) } def withAllRepositories(allRepositories: Boolean): MakePomConfiguration = { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index b8e493ee4..c84dcc50a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -104,7 +104,10 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module // we can't find the module descriptor. override def findIvyFileRef(dd: DependencyDescriptor, data: ResolveData): ResolvedResource = null - override def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = { + override def getDependency( + dd: DependencyDescriptor, + data: ResolveData + ): ResolvedModuleRevision = { val Artifact(organisation, name, revision) = dd val mrid = dd.getDependencyRevisionId() diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index c17aa283d..c21dc3a92 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -40,7 +40,12 @@ class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ - def cacheJar(moduleID: ModuleID, file: File, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { + def cacheJar( + moduleID: ModuleID, + file: File, + lock: Option[xsbti.GlobalLock], + log: Logger + ): Unit = { val artifact = defaultArtifact(moduleID) val resolved = new ResolvedResource(new FileResource(new IvyFileRepository, file), moduleID.revision) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 5f361ea5f..1c9f2e7de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -121,7 +121,9 @@ private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: Depe case _ => art } } - private[this] def defaultArtifact(a: DependencyDescriptor): Array[DependencyArtifactDescriptor] = { + private[this] def defaultArtifact( + a: DependencyDescriptor + ): Array[DependencyArtifactDescriptor] = { val dd = new DefaultDependencyArtifactDescriptor( a, a.getDependencyRevisionId.getName, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index d9f72ac18..fb2e9b1d3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -81,7 +81,10 @@ private[sbt] case class SbtChainResolver( override def locate(artifact: IArtifact): ArtifactOrigin = if (IvySbt.hasImplicitClassifier(artifact)) null else super.locate(artifact) - override def getDependency(dd: DependencyDescriptor, data: ResolveData): ResolvedModuleRevision = { + override def getDependency( + dd: DependencyDescriptor, + data: ResolveData + ): ResolvedModuleRevision = { if (data.getOptions.getLog != LogOptions.LOG_QUIET) Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") val gd = CustomSbtResolution.getDependency(dd, data) From 437165eeb51428a1949dabe6b38dcb172fb8fe6f Mon Sep 17 00:00:00 2001 From: Peter Vlugter Date: Wed, 16 Aug 2017 11:12:56 +1200 Subject: [PATCH 0681/1030] Include sbt plugin extra attributes in cached resolution --- .../librarymanagement/UpdateReportExtra.scala | 2 +- .../CachedResolutionResolveEngine.scala | 18 ++++++++--- ivy/src/test/scala/CachedResolutionSpec.scala | 32 +++++++++++++++++++ 3 files changed, 46 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 12a8fbf69..e9c9c242b 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -70,7 +70,7 @@ abstract class ModuleReportExtra { reportStr("problem", problem) + reportStr("homepage", homepage) + reportStr( - "textraAttributes", + "extraAttributes", if (extraAttributes.isEmpty) None else { Some(extraAttributes.toString) } ) + diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 75616642f..7f751ba3d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -180,17 +180,25 @@ private[sbt] class CachedResolutionResolveCache { ): Either[ResolveException, UpdateReport] = { import sbt.io.syntax._ val mrid = md.getResolvedModuleRevisionId - val (pathOrg, pathName, pathRevision) = md match { + def extraPath(id: ModuleRevisionId, key: String, pattern: String): String = + Option(id.getExtraAttribute(key)).fold(".")(pattern.format(_)) // "." has no affect on paths + def scalaVersion(id: ModuleRevisionId): String = extraPath(id, "e:scalaVersion", "scala_%s") + def sbtVersion(id: ModuleRevisionId): String = extraPath(id, "e:sbtVersion", "sbt_%s") + val (pathOrg, pathName, pathRevision, pathScalaVersion, pathSbtVersion) = md match { case x: ArtificialModuleDescriptor => val tmrid = x.targetModuleRevisionId - (tmrid.getOrganisation, tmrid.getName, tmrid.getRevision + "_" + mrid.getName) + (tmrid.getOrganisation, + tmrid.getName, + tmrid.getRevision + "_" + mrid.getName, + scalaVersion(tmrid), + sbtVersion(tmrid)) case _ => - (mrid.getOrganisation, mrid.getName, mrid.getRevision) + (mrid.getOrganisation, mrid.getName, mrid.getRevision, scalaVersion(mrid), sbtVersion(mrid)) } val staticGraphDirectory = miniGraphPath / "static" val dynamicGraphDirectory = miniGraphPath / "dynamic" - val staticGraphPath = staticGraphDirectory / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val staticGraphPath = staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" def cleanDynamicGraph(): Unit = { val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList list filterNot { d => diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/ivy/src/test/scala/CachedResolutionSpec.scala index ebab80288..e16a864ab 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/ivy/src/test/scala/CachedResolutionSpec.scala @@ -1,5 +1,6 @@ package sbt.internal.librarymanagement +import org.scalatest.LoneElement._ import sbt.util.ShowLines import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions @@ -7,6 +8,11 @@ import sbt.librarymanagement.ivy.UpdateOptions class CachedResolutionSpec extends BaseIvySpecification { import ShowLines._ + override val resolvers = Vector( + Resolver.mavenCentral, + Resolver.sbtPluginRepo("releases") + ) + "Resolving the same module twice" should "work" in { cleanIvyCache() val m = module( @@ -76,6 +82,30 @@ class CachedResolutionSpec extends BaseIvySpecification { })) } + "Resolving a module with sbt cross build" should "work" in { + cleanIvyCache() + val attributes013 = Map("e:sbtVersion" -> "0.13", "e:scalaVersion" -> "2.10") + val attributes10 = Map("e:sbtVersion" -> "1.0", "e:scalaVersion" -> "2.12") + val module013 = module( + ModuleID("com.example", "foo", "0.4.0").withConfigurations(Some("compile")), + Vector(sbtRelease.withExtraAttributes(attributes013)), + Some("2.10.6"), + UpdateOptions().withCachedResolution(true) + ) + val module10 = module( + ModuleID("com.example", "foo", "0.4.0").withConfigurations(Some("compile")), + Vector(sbtRelease.withExtraAttributes(attributes10)), + Some("2.12.3"), + UpdateOptions().withCachedResolution(true) + ) + ivyUpdate(module013).configurations.head.modules.map(_.toString).loneElement should include( + "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" + ) + ivyUpdate(module10).configurations.head.modules.map(_.toString).loneElement should include( + "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" + ) + } + def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) def mavenCayennePlugin302 = ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations( @@ -85,6 +115,8 @@ class CachedResolutionSpec extends BaseIvySpecification { ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile")) def netty320 = ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile")) + def sbtRelease = + ModuleID("com.github.gseitz", "sbt-release", "1.0.6").withConfigurations(Some("compile")) def defaultOptions = EvictionWarningOptions.default } From 03b531ca1e244d68413eac118bdb64b67c251bd9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 26 Aug 2017 13:42:11 -0400 Subject: [PATCH 0682/1030] Use sbt 1.0.0 --- build.sbt | 2 +- project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index df1473920..eba2c940e 100644 --- a/build.sbt +++ b/build.sbt @@ -30,7 +30,7 @@ def commonSettings: Seq[Setting[_]] = Seq( ) val mimaSettings = Def settings ( - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0-RC3") + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0") ) lazy val lmRoot = (project in file(".")) diff --git a/project/build.properties b/project/build.properties index 12c38d389..94005e587 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0-RC3 +sbt.version=1.0.0 From 399a511f9c99a009f1b8a48f815528bffebab0c8 Mon Sep 17 00:00:00 2001 From: David Pratt Date: Sun, 3 Sep 2017 15:30:57 -0500 Subject: [PATCH 0683/1030] Remove deprecated OkHTTP OkUrlFactory - Replace usage of OkUrlFactory with just direct calls to the OkHTTP API. This allows us to ensure that connections get properly closed, and provides finer-grained internal control of how we make http requests. - Ensure that exceptions/error status codes don't cause leaked or hanging connections. Previously, a 404 on an artifact download would cause the underlying OkHTTP client to keep the request and connection open. This has the effect of wasting resources, but also slowing down overall download/resolution time to non-pipelined HTTP servers. --- .../ivyint/GigahorseUrlHandler.scala | 318 ++++++++++-------- 1 file changed, 182 insertions(+), 136 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index af5c74a83..d2b87ed90 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -1,16 +1,26 @@ package sbt.internal.librarymanagement package ivyint -import java.net.{ URL, UnknownHostException, HttpURLConnection } -import java.io.{ File, IOException, InputStream, ByteArrayOutputStream, ByteArrayInputStream } -import org.apache.ivy.util.{ CopyProgressListener, Message, FileUtil } -import org.apache.ivy.util.url.{ URLHandler, AbstractURLHandler, BasicURLHandler, IvyAuthenticator } +import java.net.{ HttpURLConnection, URL, UnknownHostException } +import java.io._ + +import scala.util.control.NonFatal + +import okhttp3.{ MediaType, OkUrlFactory, Request, RequestBody } +import okhttp3.internal.http.HttpDate + +import okhttp3._ +import okio._ + +import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } +import org.apache.ivy.util.url.{ AbstractURLHandler, BasicURLHandler, IvyAuthenticator, URLHandler } import org.apache.ivy.util.url.URLHandler._ -import sbt.io.{ IO, Using } +import sbt.io.IO // Copied from Ivy's BasicURLHandler. class GigahorseUrlHandler extends AbstractURLHandler { - private val BUFFER_SIZE = 64 * 1024 + + import GigahorseUrlHandler._ /** * Returns the URLInfo of the given url or a #UNAVAILABLE instance, @@ -24,126 +34,136 @@ class GigahorseUrlHandler extends AbstractURLHandler { */ def getURLInfo(url0: URL, timeout: Int): URLInfo = { // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + if ("http" == url0.getProtocol || "https" == url0.getProtocol) { IvyAuthenticator.install() ErrorMessageAuthenticator.install() } val url = normalizeToURL(url0) - val con = GigahorseUrlHandler.open(url) - val infoOption = try { - con match { - case httpCon: HttpURLConnection => - if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) { - httpCon.setRequestMethod("HEAD") - } - if (checkStatusCode(url, httpCon)) { - val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) - Some( - new SbtUrlInfo(true, - httpCon.getContentLength.toLong, - con.getLastModified(), - bodyCharset)) - } else None + val request = new Request.Builder() + .url(url) - case _ => - val contentLength = con.getContentLength - if (contentLength <= 0) None - else { - // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? - val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) - Some(new SbtUrlInfo(true, contentLength.toLong, con.getLastModified(), bodyCharset)) - } + if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) request.head() else request.get() + + val response = okHttpClient.newCall(request.build()).execute() + try { + val infoOption = try { + + if (checkStatusCode(url, response)) { + val bodyCharset = + BasicURLHandler.getCharSetFromContentType(response.body().contentType().toString) + Some( + new SbtUrlInfo(true, + response.body().contentLength(), + lastModifiedTimestamp(response), + bodyCharset)) + } else None + // + // Commented out for now - can potentially be used for non HTTP urls + // + // val contentLength: Long = con.getContentLengthLong + // if (contentLength <= 0) None + // else { + // // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? + // val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) + // Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset)) + // } + + } catch { + case e: UnknownHostException => + Message.warn("Host " + e.getMessage + " not found. url=" + url) + Message.info( + "You probably access the destination server through " + + "a proxy server that is not well configured.") + None + case e: IOException => + Message.error("Server access Error: " + e.getMessage + " url=" + url) + None } - } catch { - case e: UnknownHostException => - Message.warn("Host " + e.getMessage() + " not found. url=" + url) - Message.info( - "You probably access the destination server through " - + "a proxy server that is not well configured.") - None - case e: IOException => - Message.error("Server access Error: " + e.getMessage() + " url=" + url) - None + infoOption.getOrElse(UNAVAILABLE) + } finally { + response.close() } - infoOption.getOrElse(UNAVAILABLE) } - def openStream(url0: URL): InputStream = { + //The caller of this *MUST* call Response.close() + private def getUrl(url0: URL): okhttp3.Response = { // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol() || "https" == url0.getProtocol()) { + if ("http" == url0.getProtocol || "https" == url0.getProtocol) { IvyAuthenticator.install() ErrorMessageAuthenticator.install() } val url = normalizeToURL(url0) - val conn = GigahorseUrlHandler.open(url) - conn.setRequestProperty("Accept-Encoding", "gzip,deflate") - conn match { - case httpCon: HttpURLConnection => - if (!checkStatusCode(url, httpCon)) { - throw new IOException( - "The HTTP response code for " + url + " did not indicate a success." - + " See log for more detail.") - } - case _ => + val request = new Request.Builder() + .url(url) + .get() + .build() + + val response = okHttpClient.newCall(request).execute() + try { + if (!checkStatusCode(url, response)) { + throw new IOException( + "The HTTP response code for " + url + " did not indicate a success." + + " See log for more detail.") + } + response + } catch { + case NonFatal(e) => + //ensure the response gets closed if there's an error + response.close() + throw e } - val inStream = getDecodingInputStream(conn.getContentEncoding(), conn.getInputStream()) - val outStream = new ByteArrayOutputStream() - val buffer = new Array[Byte](BUFFER_SIZE) - var len = 0 - while ({ - len = inStream.read(buffer) - len > 0 - }) { - outStream.write(buffer, 0, len) - } - new ByteArrayInputStream(outStream.toByteArray()) + } - def download(src0: URL, dest: File, l: CopyProgressListener): Unit = { - // Install the ErrorMessageAuthenticator - if ("http" == src0.getProtocol() || "https" == src0.getProtocol()) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - } + def openStream(url: URL): InputStream = { + //It's assumed that the caller of this will call close() on the supplied inputstream, + // thus closing the OkHTTP request + getUrl(url).body().byteStream() + } - val src = normalizeToURL(src0) - val srcConn = GigahorseUrlHandler.open(src) - srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate") - srcConn match { - case httpCon: HttpURLConnection => - if (!checkStatusCode(src, httpCon)) { - throw new IOException( - "The HTTP response code for " + src + " did not indicate a success." - + " See log for more detail.") - } - case _ => + def download(url: URL, dest: File, l: CopyProgressListener): Unit = { + + val response = getUrl(url) + try { + + if (l != null) { + l.start(new CopyProgressEvent()) + } + val sink = Okio.buffer(Okio.sink(dest)) + try { + sink.writeAll(response.body().source()) + sink.flush() + } finally { + sink.close() + } + + val contentLength = response.body().contentLength() + if (contentLength != -1 && dest.length != contentLength) { + IO.delete(dest) + throw new IOException( + "Downloaded file size doesn't match expected Content Length for " + url + + ". Please retry.") + } + + val lastModified = lastModifiedTimestamp(response) + if (lastModified > 0) { + dest.setLastModified(lastModified) + } + + if (l != null) { + l.end(new CopyProgressEvent(EmptyBuffer, contentLength)) + } + + } finally { + response.close() } - val inStream = getDecodingInputStream(srcConn.getContentEncoding(), srcConn.getInputStream()) - FileUtil.copy(inStream, dest, l) - // check content length only if content was not encoded - Option(srcConn.getContentEncoding) match { - case None => - val contentLength = srcConn.getContentLength - if (contentLength != -1 && dest.length != contentLength) { - IO.delete(dest) - throw new IOException( - "Downloaded file size doesn't match expected Content Length for " + src - + ". Please retry.") - } - case _ => () - } - val lastModified = srcConn.getLastModified - if (lastModified > 0) { - dest.setLastModified(lastModified) - () - } - () } def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { - if (("http" != dest0.getProtocol()) && ("https" != dest0.getProtocol())) { + + if (("http" != dest0.getProtocol) && ("https" != dest0.getProtocol)) { throw new UnsupportedOperationException("URL repository only support HTTP PUT at the moment") } @@ -151,36 +171,34 @@ class GigahorseUrlHandler extends AbstractURLHandler { ErrorMessageAuthenticator.install() val dest = normalizeToURL(dest0) - val conn = GigahorseUrlHandler.open(dest) match { - case c: HttpURLConnection => c + + val body = RequestBody.create(MediaType.parse("application/octet-stream"), source) + + val request = new Request.Builder() + .url(dest) + .put(body) + .build() + + if (l != null) { + l.start(new CopyProgressEvent()) } - conn.setDoOutput(true) - conn.setRequestMethod("PUT") - conn.setRequestProperty("Content-type", "application/octet-stream") - conn.setRequestProperty("Content-length", source.length.toLong.toString) - conn.setInstanceFollowRedirects(true) - Using.fileInputStream(source) { in => - val os = conn.getOutputStream - FileUtil.copy(in, os, l) + val response = okHttpClient.newCall(request).execute() + try { + if (l != null) { + l.end(new CopyProgressEvent(EmptyBuffer, source.length())) + } + validatePutStatusCode(dest, response.code(), response.message()) + } finally { + response.close() } - validatePutStatusCode(dest, conn.getResponseCode(), conn.getResponseMessage()) } - def checkStatusCode(url: URL, con: HttpURLConnection): Boolean = - con.getResponseCode match { - case 200 => true - case 204 if "HEAD" == con.getRequestMethod => true - case status => - Message.debug("HTTP response status: " + status + " url=" + url) - if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { - Message.warn("Your proxy requires authentication."); - } else if (String.valueOf(status).startsWith("4")) { - Message.verbose("CLIENT ERROR: " + con.getResponseMessage() + " url=" + url) - } else if (String.valueOf(status).startsWith("5")) { - Message.error("SERVER ERROR: " + con.getResponseMessage() + " url=" + url) - } - false - } +} + +object GigahorseUrlHandler { + import gigahorse.HttpClient + import gigahorse.support.okhttp.Gigahorse + import okhttp3.{ OkHttpClient, JavaNetAuthenticator } // This is requires to access the constructor of URLInfo. private[sbt] class SbtUrlInfo(available: Boolean, @@ -192,23 +210,51 @@ class GigahorseUrlHandler extends AbstractURLHandler { this(available, contentLength, lastModified, null) } } -} -object GigahorseUrlHandler { - import gigahorse._, support.okhttp.Gigahorse - import okhttp3.{ OkUrlFactory, OkHttpClient, JavaNetAuthenticator } + private val EmptyBuffer: Array[Byte] = new Array[Byte](0) lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) - private[sbt] def urlFactory = { - val client0 = http.underlying[OkHttpClient] - val client = client0 + private lazy val okHttpClient: OkHttpClient = { + http + .underlying[OkHttpClient] .newBuilder() .authenticator(new JavaNetAuthenticator) + .followRedirects(true) + .followSslRedirects(true) .build - new OkUrlFactory(client) + } + + private[sbt] def urlFactory = { + new OkUrlFactory(okHttpClient) } private[sbt] def open(url: URL): HttpURLConnection = urlFactory.open(url) + + private def checkStatusCode(url: URL, response: Response): Boolean = + response.code() match { + case 200 => true + case 204 if "HEAD" == response.request().method() => true + case status => + Message.debug("HTTP response status: " + status + " url=" + url) + if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { + Message.warn("Your proxy requires authentication.") + } else if (String.valueOf(status).startsWith("4")) { + Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) + } else if (String.valueOf(status).startsWith("5")) { + Message.error("SERVER ERROR: " + response.message() + " url=" + url) + } + false + } + + private def lastModifiedTimestamp(response: Response): Long = { + val lastModifiedDate = + Option(response.headers().get("Last-Modified")).flatMap { headerValue => + Option(HttpDate.parse(headerValue)) + } + + lastModifiedDate.map(_.getTime).getOrElse(0) + } + } From d976980af26c04d0256f85357e456bd6a69e10ae Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Mon, 4 Sep 2017 15:46:39 +0200 Subject: [PATCH 0684/1030] Replace `ivys` and `artifacts` in comments The `ivys` and `artifacts` methods are not available anymore, now referring to `withPatterns` --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 52e0b7fd2..b49b934b5 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -295,7 +295,7 @@ abstract class ResolverFunctions { /** * Constructs a file resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object. + * using the `withPatterns` method on the constructed resolver object. */ def apply(name: String): FileRepository = FileRepository(name, defaultFileConfiguration, Patterns(false)) @@ -310,7 +310,7 @@ abstract class ResolverFunctions { /** * Constructs a URL resolver with the given name. The patterns to use must be explicitly specified - * using the `ivys` or `artifacts` methods on the constructed resolver object. + * using the `withPatterns` method on the constructed resolver object. */ def apply(name: String): URLRepository = URLRepository(name, Patterns(false)) From 204f0dcd6cd237da1437b112df9ba57e3026721f Mon Sep 17 00:00:00 2001 From: David Pratt Date: Mon, 4 Sep 2017 16:48:56 -0500 Subject: [PATCH 0685/1030] Filter spurious mima errors. --- build.sbt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index eba2c940e..d0ade0876 100644 --- a/build.sbt +++ b/build.sbt @@ -30,7 +30,16 @@ def commonSettings: Seq[Setting[_]] = Seq( ) val mimaSettings = Def settings ( - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0") + mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0"), + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._ + import com.typesafe.tools.mima.core.ProblemFilters._ + Seq( + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode") + ) + } ) lazy val lmRoot = (project in file(".")) From 5d32ec29664f19be1df35c9777573c352da15865 Mon Sep 17 00:00:00 2001 From: David Pratt Date: Mon, 4 Sep 2017 16:57:13 -0500 Subject: [PATCH 0686/1030] Add deprecation annotations. --- .../internal/librarymanagement/ivyint/GigahorseUrlHandler.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index d2b87ed90..a1109dc91 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -225,10 +225,12 @@ object GigahorseUrlHandler { .build } + @deprecated("Use the Gigahorse HttpClient directly instead.", "librarymanagement-ivy 1.0.1") private[sbt] def urlFactory = { new OkUrlFactory(okHttpClient) } + @deprecated("Use the Gigahorse HttpClient directly instead.", "librarymanagement-ivy 1.0.1") private[sbt] def open(url: URL): HttpURLConnection = urlFactory.open(url) From b480c9c65b2220443b030823208ca3036df69b96 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 14 Sep 2017 16:07:02 +0200 Subject: [PATCH 0687/1030] Add flag sbt.gigahorse.enabled, to optionally disable Gigahorse. Default is true. --- .../main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index f09436e6b..4feb6c021 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -109,7 +109,7 @@ object UpdateOptions { interProjectFirst = true, latestSnapshots = true, cachedResolution = false, - gigahorse = true, + gigahorse = sys.props.get("sbt.gigahorse.enabled") map { _.toLowerCase == "true" } getOrElse true, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) From 0630b43374f7b65b5ceb291b526a833af4528044 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Sat, 16 Sep 2017 01:07:35 -0400 Subject: [PATCH 0688/1030] Updated the flag to sbt.gigahorse --- .../main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 4feb6c021..6f12ba053 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -109,7 +109,7 @@ object UpdateOptions { interProjectFirst = true, latestSnapshots = true, cachedResolution = false, - gigahorse = sys.props.get("sbt.gigahorse.enabled") map { _.toLowerCase == "true" } getOrElse true, + gigahorse = sys.props.get("sbt.gigahorse") map { _.toLowerCase == "true" } getOrElse true, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) From 364ba9b44b676012ab655c3dae9d894a16bd6a84 Mon Sep 17 00:00:00 2001 From: Alexey Alekhin Date: Sat, 23 Sep 2017 15:20:43 +0200 Subject: [PATCH 0689/1030] Removed extra slash in the localBasePattern When the `scala_[scalaVersion]/` segment is present and the `/[branch]` segment isn't, an extra slash appears before `/[revision]`. --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index b49b934b5..c8c3064f7 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -357,7 +357,7 @@ abstract class ResolverFunctions { def mavenStyleBasePattern = "[organisation]/[module](_[scalaVersion])(_[sbtVersion])/[revision]/[artifact]-[revision](-[classifier]).[ext]" def localBasePattern = - "[organisation]/[module]/" + PluginPattern + "(/[branch])/[revision]/[type]s/[artifact](-[classifier]).[ext]" + "[organisation]/[module]/" + PluginPattern + "([branch]/)[revision]/[type]s/[artifact](-[classifier]).[ext]" def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" From 08fedf787b490c736cc32025fd86ccbae732b33e Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 26 Sep 2017 10:43:34 +0200 Subject: [PATCH 0690/1030] Add file name to exception message --- .../scala/sbt/internal/librarymanagement/ConvertResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 30b8c8b1b..fb84d2468 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -367,7 +367,7 @@ private[sbt] object ConvertResolver { // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler val resource = getResource(destination) if (!overwrite && resource.exists()) { - throw new IOException("destination file exists and overwrite == false"); + throw new IOException(s"Destination file $destination exists and overwrite == false"); } fireTransferInitiated(resource, TransferEvent.REQUEST_PUT); try { From 340b4ab9ecad21fc14e353bf2d0fb035dd43ccb3 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Fri, 13 Oct 2017 15:00:38 +0100 Subject: [PATCH 0691/1030] Add a missing string interp Fixes sbt/sbt#3637 --- .../scala/sbt/internal/librarymanagement/ConvertResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 30b8c8b1b..aa88f6af4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -399,7 +399,7 @@ private[sbt] object ConvertResolver { val overwriteWarning = if (destination contains "-SNAPSHOT") s"Attempting to overwrite $destination" else - "Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." + s"Attempting to overwrite $destination (non-SNAPSHOT)\n\tYou need to remove it from the cache manually to take effect." import org.apache.ivy.util.Message Message.warn(overwriteWarning) super.put(source, destination, true) From fd0d53851124bd0afeb1ccdcc48c6822b5e3f769 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 13 Oct 2017 14:08:17 +0100 Subject: [PATCH 0692/1030] On JDK 9 call java.net.Authenticator.getDefault JDK 9 complains when java.lang.reflect.Field#setAccessible is called. So on JDK 9 to get the default Authenticator on JDK you can just call Authenticator.getDefault(). However lm targets JDK 8.. So on JDK 8 we do what we've always done, and on JDK 9 we use java reflection to call Authenticator.getDefault(), which is public and doesn't require setAccessible(true). Fixes #169 --- .../ivyint/ErrorMessageAuthenticator.scala | 45 ++++++++++++++++--- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 78e1154dc..1e842c458 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -1,6 +1,7 @@ package sbt.internal.librarymanagement package ivyint +import java.lang.reflect.InvocationTargetException import java.net.{ Authenticator, PasswordAuthentication } import org.apache.ivy.util.Message @@ -14,18 +15,41 @@ object ErrorMessageAuthenticator { private var securityWarningLogged = false private def originalAuthenticator: Option[Authenticator] = { - try { + if (isJavaVersion9Plus) getDefaultAuthenticator else getTheAuthenticator + } + + private[this] def getTheAuthenticator: Option[Authenticator] = { + withJavaReflectErrorHandling { val field = classOf[Authenticator].getDeclaredField("theAuthenticator") field.setAccessible(true) Option(field.get(null).asInstanceOf[Authenticator]) - } catch { - // TODO - Catch more specific errors. - case t: Throwable => - Message.debug("Error occurred while getting the original authenticator: " + t.getMessage) - None } } + private[this] def getDefaultAuthenticator: Option[Authenticator] = + withJavaReflectErrorHandling { + val method = classOf[Authenticator].getDeclaredMethod("getDefault") + Option(method.invoke(null).asInstanceOf[Authenticator]) + } + + private[this] def withJavaReflectErrorHandling[A](t: => Option[A]): Option[A] = { + try t + catch { + case e: ReflectiveOperationException => handleReflectionException(e) + case e: SecurityException => handleReflectionException(e) + case e: InvocationTargetException => handleReflectionException(e) + case e: ExceptionInInitializerError => handleReflectionException(e) + case e: IllegalArgumentException => handleReflectionException(e) + case e: NullPointerException => handleReflectionException(e) + case e: ClassCastException => handleReflectionException(e) + } + } + + private[this] def handleReflectionException(t: Throwable) = { + Message.debug("Error occurred while getting the original authenticator: " + t.getMessage) + None + } + private lazy val ivyOriginalField = { val field = classOf[IvyAuthenticator].getDeclaredField("original") field.setAccessible(true) @@ -76,6 +100,15 @@ object ErrorMessageAuthenticator { } doInstallIfIvy(originalAuthenticator) } + + private[this] def isJavaVersion9Plus = javaVersion > 8 + private[this] def javaVersion = { + // See Oracle section 1.5.3 at: + // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html + val version = sys.props("java.specification.version").split("\\.").map(_.toInt) + if (version(0) == 1) version(1) else version(0) + } + } /** From dcdbcd4979e97115d018928a0b9666c7e5d35ce8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 24 Oct 2017 03:15:49 -0400 Subject: [PATCH 0693/1030] Bump Ivy to 2.3.0-sbt-1b57d3bbc08ecf671169fd548918da18c91f77be Ref https://github.com/sbt/ivy/pull/26 Ref sbt/launcher#38 JDK 9 complains when java.lang.reflect.Field#setAccessible is called. So on JDK 9 to get the default Authenticator on JDK you can just call Authenticator.getDefault(). However ivy targets JDK 6.. So on JDK < 9 we do what we've always done, and on JDK 9+ we use java reflection to call Authenticator.getDefault(), which is public and doesn't require setAccessible(true). --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index fae131ba4..b4b7d372e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -40,7 +40,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a3314352b638afbf0dca19f127e8263ed6f898bd" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-1b57d3bbc08ecf671169fd548918da18c91f77be" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } From ac583b43c99e8f53a66fe72460c1c2b9a4b0bd30 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 25 Oct 2017 02:48:13 -0400 Subject: [PATCH 0694/1030] Fix JavaNetAuthenticator with null check Fixes sbt/sbt#3519 --- .../JavaNetAuthenticator.java | 82 +++++++++++++++++++ .../ivyint/GigahorseUrlHandler.scala | 6 +- 2 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java diff --git a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java new file mode 100644 index 000000000..10a0e6285 --- /dev/null +++ b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2013 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package sbt.internal.librarymanagement; + +import java.io.IOException; +import java.net.Authenticator.RequestorType; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.PasswordAuthentication; +import java.net.Proxy; +import java.util.List; +import okhttp3.Authenticator; +import okhttp3.Route; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.HttpUrl; +import okhttp3.Challenge; +import okhttp3.Credentials; + +/** + * Adapts {@link java.net.Authenticator} to {@link Authenticator}. Configure OkHttp to use {@link + * java.net.Authenticator} with {@link OkHttpClient.Builder#authenticator} or {@link + * OkHttpClient.Builder#proxyAuthenticator(Authenticator)}. + */ +public final class JavaNetAuthenticator implements Authenticator { + @Override public Request authenticate(Route route, Response response) throws IOException { + List challenges = response.challenges(); + Request request = response.request(); + HttpUrl url = request.url(); + boolean proxyAuthorization = response.code() == 407; + Proxy proxy = null; + if (route != null) { + proxy = route.proxy(); + } + + for (int i = 0, size = challenges.size(); i < size; i++) { + Challenge challenge = challenges.get(i); + if (!"Basic".equalsIgnoreCase(challenge.scheme())) continue; + + PasswordAuthentication auth; + if (proxyAuthorization) { + InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address(); + auth = java.net.Authenticator.requestPasswordAuthentication( + proxyAddress.getHostName(), getConnectToInetAddress(proxy, url), proxyAddress.getPort(), + url.scheme(), challenge.realm(), challenge.scheme(), url.url(), + RequestorType.PROXY); + } else { + auth = java.net.Authenticator.requestPasswordAuthentication( + url.host(), getConnectToInetAddress(proxy, url), url.port(), url.scheme(), + challenge.realm(), challenge.scheme(), url.url(), RequestorType.SERVER); + } + + if (auth != null) { + String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword())); + return request.newBuilder() + .header(proxyAuthorization ? "Proxy-Authorization" : "Authorization", credential) + .build(); + } + } + + return null; // No challenges were satisfied! + } + + private InetAddress getConnectToInetAddress(Proxy proxy, HttpUrl url) throws IOException { + return (proxy != null && proxy.type() != Proxy.Type.DIRECT) + ? ((InetSocketAddress) proxy.address()).getAddress() + : InetAddress.getByName(url.host()); + } +} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index a1109dc91..e760483a8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -9,7 +9,7 @@ import scala.util.control.NonFatal import okhttp3.{ MediaType, OkUrlFactory, Request, RequestBody } import okhttp3.internal.http.HttpDate -import okhttp3._ +import okhttp3.{ JavaNetAuthenticator => _, _ } import okio._ import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } @@ -198,7 +198,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { object GigahorseUrlHandler { import gigahorse.HttpClient import gigahorse.support.okhttp.Gigahorse - import okhttp3.{ OkHttpClient, JavaNetAuthenticator } + import okhttp3.OkHttpClient // This is requires to access the constructor of URLInfo. private[sbt] class SbtUrlInfo(available: Boolean, @@ -219,7 +219,7 @@ object GigahorseUrlHandler { http .underlying[OkHttpClient] .newBuilder() - .authenticator(new JavaNetAuthenticator) + .authenticator(new sbt.internal.librarymanagement.JavaNetAuthenticator) .followRedirects(true) .followSslRedirects(true) .build From a385a13fa5039f3953e0806b11a3f6db419cb9c0 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Thu, 2 Nov 2017 15:10:05 +0900 Subject: [PATCH 0695/1030] fix incorrect eviction warning message --- .../main/scala/sbt/librarymanagement/EvictionWarning.scala | 2 +- ivy/src/test/scala/EvictionWarningSpec.scala | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index ba0a1318e..1aeb40ebf 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -283,7 +283,7 @@ object EvictionWarning { out += "Scala version was updated by one of library dependencies:" out ++= (a.scalaEvictions flatMap { _.lines }) out += "To force scalaVersion, add the following:" - out += "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }" + out += "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" } if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/EvictionWarningSpec.scala index 1601962d9..48ef1ff0a 100644 --- a/ivy/src/test/scala/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/EvictionWarningSpec.scala @@ -93,7 +93,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "", "To force scalaVersion, add the following:", - "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", "Run 'evicted' to see detailed eviction warnings" ) } @@ -109,7 +109,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", "", "To force scalaVersion, add the following:", - "\tivyScala := ivyScala.value map { _.copy(overrideScalaVersion = true) }", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", "Run 'evicted' to see detailed eviction warnings" ) } From bbbb300ba1b115492373bfe3330824547d6070af Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Mon, 13 Nov 2017 16:19:00 +0900 Subject: [PATCH 0696/1030] add Java 9 test --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index f899b658c..86e2057cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,11 @@ scala: - 2.11.11 - 2.12.3 +matrix: + include: + - scala: 2.12.3 + jdk: oraclejdk9 + script: - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;scalafmt::test;test:scalafmt::test;sbt:scalafmt::test;test" From f4241c4d6524846e0a1e0c1078f6ba106189dc17 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 15 Nov 2017 15:58:29 +0000 Subject: [PATCH 0697/1030] Bump to latest Ivy Includes sbt/ivy#27 which fixes a JDK 9 issue. Similar to PR sbt/launcher#46. --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b4b7d372e..2c38cb532 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -40,7 +40,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-1b57d3bbc08ecf671169fd548918da18c91f77be" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-b18f59ea3bc914a297bb6f1a4f7fb0ace399e310" val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } From 8330d164316540b4b6aba89b5833a0c96a9035e9 Mon Sep 17 00:00:00 2001 From: Tim Underwood Date: Wed, 22 Nov 2017 10:48:59 -0800 Subject: [PATCH 0698/1030] Be friendly to SBT plugins that also use URLHandlerRegistry.setDefault Other plugins (for example: https://github.com/frugalmechanic/fm-sbt-s3-resolver) also make use of the URLHandlerRegistry.setDefault mechanism to register handlers for other protocols (e.g. "s3"). This change makes it so that SBT will only register the http/https protocols and will preserve any other protocol handlers that have already been registered. --- .../sbt/internal/librarymanagement/Ivy.scala | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index c2b5b6cfb..95c4d3db2 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -80,16 +80,29 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } private lazy val basicUrlHandler: URLHandler = new BasicURLHandler - private lazy val gigahorseUrlHandler: URLHandler = { - val dispatcher = new URLHandlerDispatcher - val handler = new GigahorseUrlHandler - dispatcher.setDownloader("http", handler) - dispatcher.setDownloader("https", handler) - dispatcher - } + private lazy val gigahorseUrlHandler: URLHandler = new GigahorseUrlHandler + private lazy val settings: IvySettings = { - if (configuration.updateOptions.gigahorse) URLHandlerRegistry.setDefault(gigahorseUrlHandler) - else URLHandlerRegistry.setDefault(basicUrlHandler) + val dispatcher: URLHandlerDispatcher = URLHandlerRegistry.getDefault match { + // If the default is already a URLHandlerDispatcher then just use that + case disp: URLHandlerDispatcher => disp + + // Otherwise wrap the existing URLHandler in a URLHandlerDispatcher + // while retaining the existing URLHandler as the default. + case default => + val disp: URLHandlerDispatcher = new URLHandlerDispatcher() + disp.setDefault(default) + URLHandlerRegistry.setDefault(disp) + disp + } + + val urlHandler: URLHandler = if (configuration.updateOptions.gigahorse) gigahorseUrlHandler else basicUrlHandler + + // Only set the urlHandler for the http/https protocols so we do not conflict with any other plugins + // that might register other protocol handlers. + // For example https://github.com/frugalmechanic/fm-sbt-s3-resolver registers "s3" + dispatcher.setDownloader("http", urlHandler) + dispatcher.setDownloader("https", urlHandler) val is = new IvySettings is.setCircularDependencyStrategy( From 7f3954d8bbb62f28af86530e64ee439aa55b84bb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 24 Nov 2017 17:14:46 -0500 Subject: [PATCH 0699/1030] Bump IO and Util --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b4b7d372e..62c33378c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,11 +3,11 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala211 = "2.11.11" - val scala212 = "2.12.3" + val scala211 = "2.11.12" + val scala212 = "2.12.4" - private val ioVersion = "1.0.0" - private val utilVersion = "1.0.0" + private val ioVersion = "1.0.2" + private val utilVersion = "1.0.3" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From df177ff56eedbf674c4fe00f7567fcd9950a07d9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 24 Nov 2017 20:16:36 -0500 Subject: [PATCH 0700/1030] Formatting --- ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 95c4d3db2..cdbfd2ee3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -96,7 +96,8 @@ final class IvySbt(val configuration: IvyConfiguration) { self => disp } - val urlHandler: URLHandler = if (configuration.updateOptions.gigahorse) gigahorseUrlHandler else basicUrlHandler + val urlHandler: URLHandler = + if (configuration.updateOptions.gigahorse) gigahorseUrlHandler else basicUrlHandler // Only set the urlHandler for the http/https protocols so we do not conflict with any other plugins // that might register other protocol handlers. From 9c1566dfa18c8aaea1fb8928148eeabca9dfaf4c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 29 Nov 2017 20:02:37 -0500 Subject: [PATCH 0701/1030] Fix false positive on sbt 1.x module eviction warnings Fixes #187 --- .../librarymanagement/EvictionWarning.scala | 19 +++++++++++- ivy/src/test/scala/EvictionWarningSpec.scala | 29 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 1aeb40ebf..6245b5f6c 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -84,7 +84,8 @@ object EvictionWarningOptions { ) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = - guessSecondSegment orElse guessSemVer orElse guessFalse + guessSbtOne orElse guessSecondSegment orElse guessSemVer orElse guessFalse + lazy val guessSecondSegment : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), Some(scalaModuleInfo)) @@ -98,6 +99,21 @@ object EvictionWarningOptions { case _ => false } } + + lazy val guessSbtOne + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (m1, Some(m2), Some(scalaModuleInfo)) + if (m2.organization == "org.scala-sbt") && + (m2.name.endsWith("_" + scalaModuleInfo.scalaFullVersion) || + m2.name.endsWith("_" + scalaModuleInfo.scalaBinaryVersion)) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.SemVer + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + lazy val guessSemVer : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), _) => @@ -108,6 +124,7 @@ object EvictionWarningOptions { case _ => false } } + lazy val guessFalse : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (_, _, _) => false diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/EvictionWarningSpec.scala index 48ef1ff0a..e5eceacad 100644 --- a/ivy/src/test/scala/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/EvictionWarningSpec.scala @@ -1,6 +1,9 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.internal.librarymanagement.cross.CrossVersionUtil +import sbt.librarymanagement.syntax._ +import org.scalatest.Assertions._ class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings @@ -42,6 +45,22 @@ class EvictionWarningSpec extends BaseIvySpecification { """ should "be detected as eviction" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() + "Comparing sbt 0.x" should "use Second Segment Variation semantics" in { + val m1 = "org.scala-sbt" % "util-logging" % "0.13.16" + val m2 = "org.scala-sbt" % "util-logging" % "0.13.1" + assert( + EvictionWarningOptions + .defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.10.6")))) == false) + } + + "Comparing sbt 1.x" should "use Semantic Versioning semantics" in { + val m1 = "org.scala-sbt" % "util-logging_2.12" % "1.0.0" + val m2 = "org.scala-sbt" % "util-logging_2.12" % "1.1.0" + assert( + EvictionWarningOptions + .defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.12.4"))))) + } + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary def akkaActor230 = @@ -265,4 +284,14 @@ class EvictionWarningSpec extends BaseIvySpecification { "Run 'evicted' to see detailed eviction warnings" ) } + + def dummyScalaModuleInfo(v: String): ScalaModuleInfo = + ScalaModuleInfo( + scalaFullVersion = v, + scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(v), + configurations = Vector.empty, + checkExplicit = true, + filterImplicit = false, + overrideScalaVersion = true + ) } From ca2617e99e8342bc97fae5e2073c7d8b3dd7be59 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 30 Nov 2017 04:22:15 +0100 Subject: [PATCH 0702/1030] Convert lastModified/setLastModified calls to sbt.io.Milli calls (more precise) --- .../main/scala/sbt/librarymanagement/RichUpdateReport.scala | 3 ++- .../librarymanagement/ivyint/GigahorseUrlHandler.scala | 3 ++- project/Util.scala | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 297611b64..39c4cd8f8 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -2,6 +2,7 @@ package sbt package librarymanagement import java.io.File +import sbt.io.Milli.getModifiedTime /** * Provides extra methods for filtering the contents of an `UpdateReport` @@ -10,7 +11,7 @@ import java.io.File final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles - val stamps = files.map(f => (f, f.lastModified)).toMap + val stamps = files.map(f => (f, getModifiedTime(f))).toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index a1109dc91..a2b4cb7a2 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -16,6 +16,7 @@ import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } import org.apache.ivy.util.url.{ AbstractURLHandler, BasicURLHandler, IvyAuthenticator, URLHandler } import org.apache.ivy.util.url.URLHandler._ import sbt.io.IO +import sbt.io.Milli.setModifiedTime // Copied from Ivy's BasicURLHandler. class GigahorseUrlHandler extends AbstractURLHandler { @@ -149,7 +150,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { val lastModified = lastModifiedTimestamp(response) if (lastModified > 0) { - dest.setLastModified(lastModified) + setModifiedTime(dest, lastModified) } if (l != null) { diff --git a/project/Util.scala b/project/Util.scala index 5dacc7df8..2ef855762 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -26,6 +26,8 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" + // TODO: replace lastModified() with sbt.io.Milli.getModifiedTime(), once the build + // has been upgraded to a version of sbt that includes sbt.io.Milli. if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) From 340f1684c209a213fadadbddf54cc81437179f5f Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Fri, 1 Dec 2017 14:58:27 +0100 Subject: [PATCH 0703/1030] Temporary workaround to FileNotFoundException in RichUpdateReport() --- .../sbt/librarymanagement/RichUpdateReport.scala | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 39c4cd8f8..2ceb8de95 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -2,6 +2,7 @@ package sbt package librarymanagement import java.io.File +import java.io.FileNotFoundException import sbt.io.Milli.getModifiedTime /** @@ -11,7 +12,20 @@ import sbt.io.Milli.getModifiedTime final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles - val stamps = files.map(f => (f, getModifiedTime(f))).toMap + val stamps = files + .map( + f => + (f, + // TODO: this used to be a lastModified(), without error checking. + // On occasion, "files" contains files like "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml", + // which do not actually exist, so getModifiedTime() correctly throws an exception. For the moment, the behavior of + // lastModified() is reproduced, but the non-existent file should really not be there to begin with. so, FIXME. + try { + getModifiedTime(f) + } catch { + case _: FileNotFoundException => 0L + })) + .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) } From 41980634a4feb0c6e123c7e6c9b6b120fa31a428 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Mon, 4 Dec 2017 22:06:12 +0100 Subject: [PATCH 0704/1030] Moved Milli._ to IO. --- .../main/scala/sbt/librarymanagement/RichUpdateReport.scala | 2 +- .../librarymanagement/ivyint/GigahorseUrlHandler.scala | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 2ceb8de95..518bc6979 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -3,7 +3,7 @@ package librarymanagement import java.io.File import java.io.FileNotFoundException -import sbt.io.Milli.getModifiedTime +import sbt.io.IO.getModifiedTime /** * Provides extra methods for filtering the contents of an `UpdateReport` diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index a2b4cb7a2..32bbaf516 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -16,7 +16,6 @@ import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } import org.apache.ivy.util.url.{ AbstractURLHandler, BasicURLHandler, IvyAuthenticator, URLHandler } import org.apache.ivy.util.url.URLHandler._ import sbt.io.IO -import sbt.io.Milli.setModifiedTime // Copied from Ivy's BasicURLHandler. class GigahorseUrlHandler extends AbstractURLHandler { @@ -150,7 +149,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { val lastModified = lastModifiedTimestamp(response) if (lastModified > 0) { - setModifiedTime(dest, lastModified) + IO.setModifiedTime(dest, lastModified) } if (l != null) { From 02c2ab5203554cac62a8e34cdef421f2ccb0b199 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 13 Dec 2017 16:00:41 +0000 Subject: [PATCH 0705/1030] Use IO.getModified over importing the method --- .../sbt/librarymanagement/RichUpdateReport.scala | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 518bc6979..189137008 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -3,7 +3,7 @@ package librarymanagement import java.io.File import java.io.FileNotFoundException -import sbt.io.IO.getModifiedTime +import sbt.io.IO /** * Provides extra methods for filtering the contents of an `UpdateReport` @@ -20,11 +20,10 @@ final class RichUpdateReport(report: UpdateReport) { // On occasion, "files" contains files like "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml", // which do not actually exist, so getModifiedTime() correctly throws an exception. For the moment, the behavior of // lastModified() is reproduced, but the non-existent file should really not be there to begin with. so, FIXME. - try { - getModifiedTime(f) - } catch { - case _: FileNotFoundException => 0L - })) + try IO.getModifiedTime(f) + catch { case _: FileNotFoundException => 0L } + ) + ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) } From 68356306ec492b375c4c573c5c00c42f119d5c4e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 15 Dec 2017 14:02:31 -0500 Subject: [PATCH 0706/1030] bump modules and plugins --- build.sbt | 1 + .../sbt/librarymanagement/CrossVersion.scala | 2 +- .../contraband-scala/sbt/librarymanagement/Disabled.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Patch.scala | 2 +- .../sbt/librarymanagement/SshAuthentication.scala | 2 +- .../main/scala/sbt/librarymanagement/RichUpdateReport.scala | 3 +-- project/Dependencies.scala | 4 ++-- project/plugins.sbt | 6 ++---- 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/build.sbt b/build.sbt index d0ade0876..65b5c0ad2 100644 --- a/build.sbt +++ b/build.sbt @@ -55,6 +55,7 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile := true, + scalafmtOnCompile in Sbt := false, scalafmtVersion := "1.2.0", git.baseVersion := baseVersion, version := { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala index 321be7615..2c890a27b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala @@ -11,7 +11,7 @@ abstract class CrossVersion() extends Serializable { override def equals(o: Any): Boolean = o match { - case x: CrossVersion => true + case _: CrossVersion => true case _ => false } override def hashCode: Int = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala index 1c03d422e..6a3ccde72 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala @@ -10,7 +10,7 @@ final class Disabled private () extends sbt.librarymanagement.CrossVersion() wit override def equals(o: Any): Boolean = o match { - case x: Disabled => true + case _: Disabled => true case _ => false } override def hashCode: Int = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala index ffdf666eb..65ec50436 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala @@ -13,7 +13,7 @@ final class Patch private () extends sbt.librarymanagement.CrossVersion() with S override def equals(o: Any): Boolean = o match { - case x: Patch => true + case _: Patch => true case _ => false } override def hashCode: Int = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala index af49207c4..2ad8a3f57 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala @@ -10,7 +10,7 @@ abstract class SshAuthentication() extends Serializable { override def equals(o: Any): Boolean = o match { - case x: SshAuthentication => true + case _: SshAuthentication => true case _ => false } override def hashCode: Int = { diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 189137008..d8e5ca795 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -21,8 +21,7 @@ final class RichUpdateReport(report: UpdateReport) { // which do not actually exist, so getModifiedTime() correctly throws an exception. For the moment, the behavior of // lastModified() is reproduced, but the non-existent file should really not be there to begin with. so, FIXME. try IO.getModifiedTime(f) - catch { case _: FileNotFoundException => 0L } - ) + catch { case _: FileNotFoundException => 0L }) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 6a7a0f7b6..1a71abf72 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.4" - private val ioVersion = "1.0.2" - private val utilVersion = "1.0.3" + private val ioVersion = "1.1.2" + private val utilVersion = "1.1.1" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/plugins.sbt b/project/plugins.sbt index f82b39957..7a0426d32 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,4 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.3") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.0") -addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.10") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.17") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.4") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") scalacOptions += "-language:postfixOps" From 8fb23b4fe56c92ee52170739ed4ea7570020e241 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 18 Dec 2017 16:25:32 +0000 Subject: [PATCH 0707/1030] Add 1.1.1 to mimaPreviousArtifacts, & backfill --- build.sbt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 65b5c0ad2..c40786055 100644 --- a/build.sbt +++ b/build.sbt @@ -30,7 +30,13 @@ def commonSettings: Seq[Setting[_]] = Seq( ) val mimaSettings = Def settings ( - mimaPreviousArtifacts := Set(organization.value %% moduleName.value % "1.0.0"), + mimaPreviousArtifacts := Set( + "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", + "1.1.0", "1.1.1", + ) map (version => + organization.value %% moduleName.value % version + cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) + ), mimaBinaryIssueFilters ++= { import com.typesafe.tools.mima.core._ import com.typesafe.tools.mima.core.ProblemFilters._ From abf370adc305b2d29fcc733f6338eb42008af7f8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 19 Dec 2017 13:23:44 +0000 Subject: [PATCH 0708/1030] Upgrade to sbt-houserules 0.3.5 --- build.sbt | 2 -- project/plugins.sbt | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c40786055..3b35213c5 100644 --- a/build.sbt +++ b/build.sbt @@ -60,9 +60,7 @@ lazy val lmRoot = (project in file(".")) Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) }, bintrayPackage := "librarymanagement", - scalafmtOnCompile := true, scalafmtOnCompile in Sbt := false, - scalafmtVersion := "1.2.0", git.baseVersion := baseVersion, version := { val v = version.value diff --git a/project/plugins.sbt b/project/plugins.sbt index 7a0426d32..8e2abce43 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.4") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") scalacOptions += "-language:postfixOps" From 42f23e62aa46b811e4fbf03b14a8365c5da9cf92 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Mon, 18 Dec 2017 17:24:22 +0100 Subject: [PATCH 0709/1030] Revert *ModifiedTime() calls to *lastModified*() calls There are just too many instances in which sbt's code relies on the `lastModified`/`setLastModified` semantics, so instead of moving to `get`/`setModifiedTime`, we use new IO calls that offer the new timestamp precision, but retain the old semantics. --- .../sbt/librarymanagement/RichUpdateReport.scala | 11 +++++------ .../ivyint/GigahorseUrlHandler.scala | 2 +- project/Util.scala | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index d8e5ca795..3d7eb933c 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -16,12 +16,11 @@ final class RichUpdateReport(report: UpdateReport) { .map( f => (f, - // TODO: this used to be a lastModified(), without error checking. - // On occasion, "files" contains files like "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml", - // which do not actually exist, so getModifiedTime() correctly throws an exception. For the moment, the behavior of - // lastModified() is reproduced, but the non-existent file should really not be there to begin with. so, FIXME. - try IO.getModifiedTime(f) - catch { case _: FileNotFoundException => 0L }) + // TODO: The list of files may also contain some odd files that do not actually exist like: + // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". + // IO.lastModified() will just return zero, but the list of files should not contain such + // files to begin with, in principle. + IO.lastModified(f) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 32bbaf516..1a25a3202 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -149,7 +149,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { val lastModified = lastModifiedTimestamp(response) if (lastModified > 0) { - IO.setModifiedTime(dest, lastModified) + IO.setLastModified(dest, lastModified) } if (l != null) { diff --git a/project/Util.scala b/project/Util.scala index 2ef855762..5c63dd1de 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -26,8 +26,8 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" - // TODO: replace lastModified() with sbt.io.Milli.getModifiedTime(), once the build - // has been upgraded to a version of sbt that includes sbt.io.Milli. + // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // has been upgraded to a version of sbt that includes that call. if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) From 72dd0064c3791ad4a6a2ba1904d8cf12322aede3 Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Fri, 22 Dec 2017 00:24:48 +0100 Subject: [PATCH 0710/1030] Change modifiedTime definitions --- .../main/scala/sbt/librarymanagement/RichUpdateReport.scala | 4 ++-- .../librarymanagement/ivyint/GigahorseUrlHandler.scala | 2 +- project/Util.scala | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 3d7eb933c..97f672faa 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -18,9 +18,9 @@ final class RichUpdateReport(report: UpdateReport) { (f, // TODO: The list of files may also contain some odd files that do not actually exist like: // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". - // IO.lastModified() will just return zero, but the list of files should not contain such + // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such // files to begin with, in principle. - IO.lastModified(f) + IO.getModifiedTimeOrZero(f)) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 1a25a3202..b8da74aab 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -149,7 +149,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { val lastModified = lastModifiedTimestamp(response) if (lastModified > 0) { - IO.setLastModified(dest, lastModified) + IO.setModifiedTimeOrFalse(dest, lastModified) } if (l != null) { diff --git a/project/Util.scala b/project/Util.scala index 5c63dd1de..3b1ead60a 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -26,7 +26,7 @@ object Util { val timestamp = formatter.format(new Date) val content = versionLine(version) + "\ntimestamp=" + timestamp val f = dir / "xsbt.version.properties" - // TODO: replace lastModified() with sbt.io.IO.lastModified(), once the build + // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build // has been upgraded to a version of sbt that includes that call. if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { s.log.info("Writing version information to " + f + " :\n" + content) From b53c37b54f9f94703f2efb2e4f60da2d4532d3ab Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Dec 2017 08:35:11 -0500 Subject: [PATCH 0711/1030] IO 1.1.3 and Util 1.1.2 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 1a71abf72..3d4a59e93 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.4" - private val ioVersion = "1.1.2" - private val utilVersion = "1.1.1" + private val ioVersion = "1.1.3" + private val utilVersion = "1.1.2" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From fa472179f5aa7deb07e0126cca4e7a9c07bf268b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Dec 2017 08:35:26 -0500 Subject: [PATCH 0712/1030] sbt 1.0.4 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 94005e587..394cb75cf 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.0 +sbt.version=1.0.4 From aa26ae64b9ae12ae9aef17de327efe8bdf3036af Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 10 Jan 2018 15:42:42 +0000 Subject: [PATCH 0713/1030] Add version 1.1.2 to mimaPreviousArtifacts --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 3b35213c5..a32a71f16 100644 --- a/build.sbt +++ b/build.sbt @@ -32,7 +32,7 @@ def commonSettings: Seq[Setting[_]] = Seq( val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", - "1.1.0", "1.1.1", + "1.1.0", "1.1.1", "1.1.2", ) map (version => organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) From 0c187fa9eccf4a1e4ff1b282777feab0e3a61ebf Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 10 Jan 2018 16:06:25 +0000 Subject: [PATCH 0714/1030] Upgrade to sbt 1.1.0 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 394cb75cf..8b697bbb9 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.4 +sbt.version=1.1.0 From 039cb1591eb334e0a03e7c7de2c977e8aff1af44 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 11 Jan 2018 14:02:45 +0000 Subject: [PATCH 0715/1030] Add, configure & enforce sbt-whitesource --- .travis.yml | 22 +++++++++++++++------- build.sbt | 9 +++++++++ project/plugins.sbt | 5 +++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 86e2057cf..c72857301 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,16 +2,24 @@ language: scala jdk: oraclejdk8 scala: - - 2.11.11 - - 2.12.3 + - 2.11.12 + - 2.12.4 matrix: include: - - scala: 2.12.3 + - scala: 2.12.4 jdk: oraclejdk9 -script: - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;scalafmt::test;test:scalafmt::test;sbt:scalafmt::test;test" +script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M + ++$TRAVIS_SCALA_VERSION + mimaReportBinaryIssues + scalafmt::test test:scalafmt::test sbt:scalafmt::test + whitesourceCheckPolicies + test + +env: + global: + - secure: D9Ckfxq/5n+41REwuPBwb0CHRVSPtCJRN+N1FWNFjUnfCHZQCeclP8Ydp9ql/fZxICG8rnCOI5XW0j2YeAiR+abpQNmQ42pKMEjNT0VQDZ0I1lQfiDL071Kj+ui9AH+TqAvBT011u72ML52iDfV0WaL/Skf1Noh0lXc+IscRI56OLRv+YU5n5aNZhXon6AZHU11rRCg4aMwaHr+U9ISSUXc6OtJeFC/SAYNUNYEOZwTOJ4Y2+VrKAmKuIZ2jjkMF13eKMzXw5g+u8V3AmOpIm1RiyS2dAgAoc+r2ucF9RUMsfiZIF0XBu65iv9hZP5m0q11n6IFEKC9bpLsTYCAwX2MgVayoHvDQv1gkL/cA1gkqmf0Kkx3oc33aYLgsCydj2Lbg/myKD+GeHxr5WhyeSEee3Bwj+KGNwvjfcaPEECCor6yilKGdIsuYbfHzu8B8moNjwH7ui5f5w/1xuWrdaSA23LOIYbhP+2rM894JIYNNt5vlMLoYMzmC9N1E/qyBRYSdfMr+Uh8qI+j85hkKKgEffSu9f55IH6bk6Lq08Nc4d64KXUISDNJj59MrJcadatsS2vp+u39zR/iIewW4a017bAFfv57AJb6SwLdvASG+psFH8MRPD6xYPZKNw4Al/4YMc+oXONplSXyOu/jQYjSfK9tyvJwpoY7tLh6vEBc= cache: directories: @@ -19,5 +27,5 @@ cache: - $HOME/.sbt before_cache: - - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete - - find $HOME/.sbt -name "*.lock" -print -delete + - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete + - find $HOME/.sbt -name "*.lock" -delete diff --git a/build.sbt b/build.sbt index 3b35213c5..30902fb60 100644 --- a/build.sbt +++ b/build.sbt @@ -144,3 +144,12 @@ def customCommands: Seq[Setting[_]] = Seq( state } ) + +inThisBuild(Seq( + whitesourceProduct := "Lightbend Reactive Platform", + whitesourceAggregateProjectName := "sbt-lm-master", + whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", + whitesourceIgnoredScopes += "scalafmt", + whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present + whitesourceForceCheckAllDependencies := true, +)) diff --git a/project/plugins.sbt b/project/plugins.sbt index 8e2abce43..5603caf15 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,5 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") +addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") scalacOptions += "-language:postfixOps" From c0ac7061dbb155d75f57af782397800b9a98d6f7 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 12 Jan 2018 20:06:24 -0500 Subject: [PATCH 0716/1030] Reorganize existing tests --- build.sbt | 22 ++++-- .../AbstractEngineSpec.scala | 21 ++++++ .../librarymanagement/ResolutionSpec.scala | 73 ++++++++----------- .../internal/librarymanagement/UnitSpec.scala | 5 ++ .../internal/librarymanagement/UnitSpec.scala | 0 .../librarymanagement}/CrossVersionTest.scala | 0 .../sbt/librarymanagement}/ModuleIdTest.scala | 0 .../sbt/librarymanagement}/ResolverTest.scala | 0 .../VersionNumberSpec.scala | 0 .../librarymanagement/VersionRangeSpec.scala | 0 .../BaseCachedResolutionSpec.scala | 14 ++++ .../BaseIvySpecification.scala | 40 ++++++---- .../CachedResolutionSpec.scala | 10 +++ .../ComponentManagerTest.scala | 0 .../CustomPomParserTest.scala | 0 .../DMSerializationSpec.scala | 5 +- .../EvictionWarningSpec.scala | 5 +- .../librarymanagement}/FrozenModeSpec.scala | 4 +- .../librarymanagement}/InclExclSpec.scala | 6 +- .../InconsistentDuplicateSpec.scala | 0 .../librarymanagement/IvyResolutionSpec.scala | 10 +++ .../librarymanagement}/MakePomSpec.scala | 4 +- .../ManagedChecksumsSpec.scala | 4 +- .../MergeDescriptorSpec.scala | 0 .../ModuleResolversTest.scala | 6 +- .../librarymanagement}/OfflineModeSpec.scala | 4 +- .../ScalaOverrideTest.scala | 7 +- .../UpdateOptionsSpec.scala | 4 +- project/Dependencies.scala | 4 +- 29 files changed, 160 insertions(+), 88 deletions(-) create mode 100644 common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala rename ivy/src/test/scala/CachedResolutionSpec.scala => common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala (57%) create mode 100644 common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala rename {ivy => core}/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala (100%) rename {ivy/src/test/scala => core/src/test/scala/sbt/librarymanagement}/CrossVersionTest.scala (100%) rename {ivy/src/test/scala => core/src/test/scala/sbt/librarymanagement}/ModuleIdTest.scala (100%) rename {ivy/src/test/scala => core/src/test/scala/sbt/librarymanagement}/ResolverTest.scala (100%) rename {ivy/src/test/scala => core/src/test/scala/sbt/librarymanagement}/VersionNumberSpec.scala (100%) rename {ivy/src/test/scala/sbt/internal => core/src/test/scala/sbt}/librarymanagement/VersionRangeSpec.scala (100%) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/BaseIvySpecification.scala (77%) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/CachedResolutionSpec.scala rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/ComponentManagerTest.scala (100%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/CustomPomParserTest.scala (100%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/DMSerializationSpec.scala (97%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/EvictionWarningSpec.scala (99%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/FrozenModeSpec.scala (97%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/InclExclSpec.scala (96%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/InconsistentDuplicateSpec.scala (100%) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/IvyResolutionSpec.scala rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/MakePomSpec.scala (96%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/MergeDescriptorSpec.scala (100%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/ModuleResolversTest.scala (95%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/OfflineModeSpec.scala (97%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/ScalaOverrideTest.scala (97%) rename ivy/src/test/scala/{ => sbt/internal/librarymanagement}/UpdateOptionsSpec.scala (89%) diff --git a/build.sbt b/build.sbt index 30902fb60..4458752e9 100644 --- a/build.sbt +++ b/build.sbt @@ -90,8 +90,8 @@ lazy val lmCore = (project in file("core")) gigahorseOkhttp, okhttpUrlconnection, sjsonnewScalaJson.value % Optional, - scalaTest, - scalaCheck + scalaTest % Test, + scalaCheck % Test ), libraryDependencies ++= scalaXml.value, resourceGenerators in Compile += Def @@ -119,13 +119,25 @@ lazy val lmCore = (project in file("core")) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) -lazy val lmIvy = (project in file("ivy")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) +lazy val lmCommonTest = (project in file("common-test")) .dependsOn(lmCore) + .settings( + commonSettings, + skip in publish := true, + name := "common-test", + libraryDependencies ++= Seq(scalaTest, scalaCheck), + scalacOptions in (Compile, console) --= + Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), + mimaSettings, + ) + +lazy val lmIvy = (project in file("ivy")) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + .dependsOn(lmCore, lmCommonTest) .settings( commonSettings, name := "librarymanagement-ivy", - libraryDependencies ++= Seq(ivy, scalaTest, scalaCheck), + libraryDependencies ++= Seq(ivy, scalaTest % Test, scalaCheck % Test), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala new file mode 100644 index 000000000..614f8d34a --- /dev/null +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala @@ -0,0 +1,21 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ + +abstract class AbstractEngineSpec extends UnitSpec { + def cleanCache(): Unit + + def module(moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String]): ModuleDescriptor + + def updateEither(module: ModuleDescriptor): Either[UnresolvedWarning, UpdateReport] + + def update(module: ModuleDescriptor) = + updateEither(module) match { + case Right(r) => r + case Left(w) => throw w.resolveException + } + + def cleanCachedResolutionCache(module: ModuleDescriptor): Unit = () +} diff --git a/ivy/src/test/scala/CachedResolutionSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala similarity index 57% rename from ivy/src/test/scala/CachedResolutionSpec.scala rename to common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala index e16a864ab..fe14d1370 100644 --- a/ivy/src/test/scala/CachedResolutionSpec.scala +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala @@ -3,27 +3,21 @@ package sbt.internal.librarymanagement import org.scalatest.LoneElement._ import sbt.util.ShowLines import sbt.librarymanagement._ -import sbt.librarymanagement.ivy.UpdateOptions +import sbt.librarymanagement.syntax._ -class CachedResolutionSpec extends BaseIvySpecification { +abstract class ResolutionSpec extends AbstractEngineSpec { import ShowLines._ - override val resolvers = Vector( - Resolver.mavenCentral, - Resolver.sbtPluginRepo("releases") - ) - "Resolving the same module twice" should "work" in { - cleanIvyCache() + cleanCache() val m = module( - ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), + exampleModuleId("0.1.0"), Vector(commonsIo13), - Some("2.10.2"), - UpdateOptions().withCachedResolution(true) + Some("2.10.2") ) - val report = ivyUpdate(m) + val report = update(m) cleanCachedResolutionCache(m) - val _ = ivyUpdate(m) + val _ = update(m) // first resolution creates the minigraph println(report) // second resolution reads from the minigraph @@ -34,17 +28,16 @@ class CachedResolutionSpec extends BaseIvySpecification { "Resolving the unsolvable module should" should "not work" in { // log.setLevel(Level.Debug) val m = module( - ModuleID("com.example", "foo", "0.2.0").withConfigurations(Some("compile")), + exampleModuleId("0.2.0"), Vector(mavenCayennePlugin302), - Some("2.10.2"), - UpdateOptions().withCachedResolution(true) + Some("2.10.2") ) - ivyUpdateEither(m) match { + updateEither(m) match { case Right(_) => sys.error("this should've failed") case Left(uw) => println(uw.lines.mkString("\n")) } - ivyUpdateEither(m) match { + updateEither(m) match { case Right(_) => sys.error("this should've failed 2") case Left(uw) => uw.lines should contain allOf ("\n\tNote: Unresolved dependencies path:", @@ -61,18 +54,17 @@ class CachedResolutionSpec extends BaseIvySpecification { // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final "Resolving a module with a pseudo-conflict" should "work" in { // log.setLevel(Level.Debug) - cleanIvyCache() + cleanCache() val m = module( - ModuleID("com.example", "foo", "0.3.0").withConfigurations(Some("compile")), + exampleModuleId("0.3.0"), Vector(avro177, dataAvro1940, netty320), - Some("2.10.2"), - UpdateOptions().withCachedResolution(true) + Some("2.10.2") ) // first resolution creates the minigraph - val _ = ivyUpdate(m) + val _ = update(m) cleanCachedResolutionCache(m) // second resolution reads from the minigraph - val report = ivyUpdate(m) + val report = update(m) val modules: Seq[String] = report.configurations.head.modules map { _.toString } assert(modules exists { x: String => x contains """org.jboss.netty:netty:3.2.0.Final""" @@ -83,40 +75,37 @@ class CachedResolutionSpec extends BaseIvySpecification { } "Resolving a module with sbt cross build" should "work" in { - cleanIvyCache() + cleanCache() val attributes013 = Map("e:sbtVersion" -> "0.13", "e:scalaVersion" -> "2.10") val attributes10 = Map("e:sbtVersion" -> "1.0", "e:scalaVersion" -> "2.12") val module013 = module( - ModuleID("com.example", "foo", "0.4.0").withConfigurations(Some("compile")), + exampleModuleId("0.4.0"), Vector(sbtRelease.withExtraAttributes(attributes013)), - Some("2.10.6"), - UpdateOptions().withCachedResolution(true) + Some("2.10.6") ) val module10 = module( - ModuleID("com.example", "foo", "0.4.0").withConfigurations(Some("compile")), + exampleModuleId("0.4.1"), Vector(sbtRelease.withExtraAttributes(attributes10)), - Some("2.12.3"), - UpdateOptions().withCachedResolution(true) + Some("2.12.3") ) - ivyUpdate(module013).configurations.head.modules.map(_.toString).loneElement should include( + update(module013).configurations.head.modules.map(_.toString).loneElement should include( "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" ) - ivyUpdate(module10).configurations.head.modules.map(_.toString).loneElement should include( + update(module10).configurations.head.modules.map(_.toString).loneElement should include( "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" ) } - def commonsIo13 = ModuleID("commons-io", "commons-io", "1.3").withConfigurations(Some("compile")) + def exampleModuleId(v: String): ModuleID = ("com.example" % "foo" % v % Compile) + + def commonsIo13 = ("commons-io" % "commons-io" % "1.3" % Compile) def mavenCayennePlugin302 = - ModuleID("org.apache.cayenne.plugins", "maven-cayenne-plugin", "3.0.2").withConfigurations( - Some("compile")) - def avro177 = ModuleID("org.apache.avro", "avro", "1.7.7").withConfigurations(Some("compile")) + ("org.apache.cayenne.plugins" % "maven-cayenne-plugin" % "3.0.2" % Compile) + def avro177 = ("org.apache.avro" % "avro" % "1.7.7" % Compile) def dataAvro1940 = - ModuleID("com.linkedin.pegasus", "data-avro", "1.9.40").withConfigurations(Some("compile")) - def netty320 = - ModuleID("org.jboss.netty", "netty", "3.2.0.Final").withConfigurations(Some("compile")) - def sbtRelease = - ModuleID("com.github.gseitz", "sbt-release", "1.0.6").withConfigurations(Some("compile")) + ("com.linkedin.pegasus" % "data-avro" % "1.9.40" % Compile) + def netty320 = ("org.jboss.netty" % "netty" % "3.2.0.Final" % Compile) + def sbtRelease = ("com.github.gseitz" % "sbt-release" % "1.0.6" % Compile) def defaultOptions = EvictionWarningOptions.default } diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala new file mode 100644 index 000000000..dfd947c8f --- /dev/null +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala @@ -0,0 +1,5 @@ +package sbt.internal.librarymanagement + +import org.scalatest._ + +abstract class UnitSpec extends FlatSpec with Matchers diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala b/core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala similarity index 100% rename from ivy/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala rename to core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala diff --git a/ivy/src/test/scala/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala similarity index 100% rename from ivy/src/test/scala/CrossVersionTest.scala rename to core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala diff --git a/ivy/src/test/scala/ModuleIdTest.scala b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala similarity index 100% rename from ivy/src/test/scala/ModuleIdTest.scala rename to core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala diff --git a/ivy/src/test/scala/ResolverTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala similarity index 100% rename from ivy/src/test/scala/ResolverTest.scala rename to core/src/test/scala/sbt/librarymanagement/ResolverTest.scala diff --git a/ivy/src/test/scala/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala similarity index 100% rename from ivy/src/test/scala/VersionNumberSpec.scala rename to core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionRangeSpec.scala similarity index 100% rename from ivy/src/test/scala/sbt/internal/librarymanagement/VersionRangeSpec.scala rename to core/src/test/scala/sbt/librarymanagement/VersionRangeSpec.scala diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala new file mode 100644 index 000000000..f53454c5f --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala @@ -0,0 +1,14 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ +import sbt.librarymanagement.ivy._ + +trait BaseCachedResolutionSpec extends BaseIvySpecification { + override def module(moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String]): ModuleDescriptor = { + val uo: UpdateOptions = UpdateOptions() + .withCachedResolution(true) + module(moduleId, deps, scalaFullVersion, uo, true) + } +} diff --git a/ivy/src/test/scala/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala similarity index 77% rename from ivy/src/test/scala/BaseIvySpecification.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index 4dd23afe3..b8034995a 100644 --- a/ivy/src/test/scala/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -3,13 +3,13 @@ package sbt.internal.librarymanagement import sbt.io.IO import sbt.io.syntax._ import java.io.File -import cross.CrossVersionUtil import sbt.internal.util.ConsoleLogger import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ +import cross.CrossVersionUtil import Configurations._ -trait BaseIvySpecification extends UnitSpec { +trait BaseIvySpecification extends AbstractEngineSpec { def currentBase: File = new File(".") def currentTarget: File = currentBase / "target" / "ivyhome" def currentManaged: File = currentBase / "target" / "lib_managed" @@ -22,6 +22,13 @@ trait BaseIvySpecification extends UnitSpec { IvyDependencyResolution(mkIvyConfiguration(uo)) def configurations = Vector(Compile, Test, Runtime) + + def module(moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String]): ModuleDescriptor = { + module(moduleId, deps, scalaFullVersion, UpdateOptions(), true) + } + def module(moduleId: ModuleID, deps: Vector[ModuleID], scalaFullVersion: Option[String], @@ -77,23 +84,28 @@ trait BaseIvySpecification extends UnitSpec { .withMetadataDirectory(metadataDirectory) } - def ivyUpdateEither(module: IvySbt#Module): Either[UnresolvedWarning, UpdateReport] = { - // IO.delete(currentTarget) - val config = makeUpdateConfiguration(false, Some(currentDependency)) - IvyActions.updateEither(module, config, UnresolvedWarningConfiguration(), log) + def updateEither(module: ModuleDescriptor): Either[UnresolvedWarning, UpdateReport] = + ivyUpdateEither(module) + + def ivyUpdateEither(module: ModuleDescriptor): Either[UnresolvedWarning, UpdateReport] = { + module match { + case m: IvySbt#Module => + val config = makeUpdateConfiguration(false, Some(currentDependency)) + IvyActions.updateEither(m, config, UnresolvedWarningConfiguration(), log) + } } + def cleanCache: Unit = cleanIvyCache() def cleanIvyCache(): Unit = IO.delete(currentTarget / "cache") - def cleanCachedResolutionCache(module: IvySbt#Module): Unit = - IvyActions.cleanCachedResolutionCache(module, log) - - def ivyUpdate(module: IvySbt#Module) = - ivyUpdateEither(module) match { - case Right(r) => r - case Left(w) => - throw w.resolveException + override def cleanCachedResolutionCache(module: ModuleDescriptor): Unit = { + module match { + case m: IvySbt#Module => IvyActions.cleanCachedResolutionCache(m, log) } + } + + def ivyUpdate(module: ModuleDescriptor): UpdateReport = + update(module) def mkPublishConfiguration(resolver: Resolver, artifacts: Map[Artifact, File]): PublishConfiguration = { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CachedResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CachedResolutionSpec.scala new file mode 100644 index 000000000..dbb23fbe0 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CachedResolutionSpec.scala @@ -0,0 +1,10 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ + +class CachedResolutionSpec extends ResolutionSpec with BaseCachedResolutionSpec { + override val resolvers = Vector( + Resolver.mavenCentral, + Resolver.sbtPluginRepo("releases") + ) +} diff --git a/ivy/src/test/scala/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala similarity index 100% rename from ivy/src/test/scala/ComponentManagerTest.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala diff --git a/ivy/src/test/scala/CustomPomParserTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala similarity index 100% rename from ivy/src/test/scala/CustomPomParserTest.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala diff --git a/ivy/src/test/scala/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala similarity index 97% rename from ivy/src/test/scala/DMSerializationSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 937fa3537..f5c6379b8 100644 --- a/ivy/src/test/scala/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -1,13 +1,12 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement import java.net.URL import java.io.File -import sbt.internal._, librarymanagement._ +import sbt.librarymanagement._ import sjsonnew.shaded.scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ import org.scalatest.Assertion - import LibraryManagementCodec._ class DMSerializationSpec extends UnitSpec { diff --git a/ivy/src/test/scala/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala similarity index 99% rename from ivy/src/test/scala/EvictionWarningSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index e5eceacad..488ead1f3 100644 --- a/ivy/src/test/scala/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -1,9 +1,8 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement -import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.librarymanagement._ import sbt.internal.librarymanagement.cross.CrossVersionUtil import sbt.librarymanagement.syntax._ -import org.scalatest.Assertions._ class EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings diff --git a/ivy/src/test/scala/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala similarity index 97% rename from ivy/src/test/scala/FrozenModeSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index cd9a30799..c6c18c6cf 100644 --- a/ivy/src/test/scala/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -1,7 +1,7 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement +import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions -import sbt.internal.librarymanagement._ import sbt.librarymanagement.syntax._ class FrozenModeSpec extends BaseIvySpecification { diff --git a/ivy/src/test/scala/InclExclSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala similarity index 96% rename from ivy/src/test/scala/InclExclSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala index 62856f0c1..a0cc150bd 100644 --- a/ivy/src/test/scala/InclExclSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala @@ -1,8 +1,8 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement -import org.scalatest.Assertion -import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ +import org.scalatest.Assertion import DependencyBuilders.OrganizationArtifactName class InclExclSpec extends BaseIvySpecification { diff --git a/ivy/src/test/scala/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala similarity index 100% rename from ivy/src/test/scala/InconsistentDuplicateSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyResolutionSpec.scala new file mode 100644 index 000000000..d94c276e3 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyResolutionSpec.scala @@ -0,0 +1,10 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ + +class IvyResolutionSpec extends ResolutionSpec with BaseIvySpecification { + override val resolvers = Vector( + Resolver.mavenCentral, + Resolver.sbtPluginRepo("releases") + ) +} diff --git a/ivy/src/test/scala/MakePomSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala similarity index 96% rename from ivy/src/test/scala/MakePomSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala index eb9c353cb..886b2018e 100644 --- a/ivy/src/test/scala/MakePomSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala @@ -66,8 +66,10 @@ class MakePomSpec extends UnitSpec { "foo+" should "convert to foo+" in beParsedAsError("foo+") val mp = new MakePom(ConsoleLogger()) - def convertTo(s: String, expected: String): Unit = + def convertTo(s: String, expected: String): Unit = { MakePom.makeDependencyVersion(s) shouldBe expected + () + } def beParsedAsError(s: String): Unit = { intercept[Throwable] { MakePom.makeDependencyVersion(s) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index fab7016df..7ef540583 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -1,9 +1,9 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement import java.io.File import org.apache.ivy.util.Message -import sbt.internal.librarymanagement.{ BaseIvySpecification, IvyActions } +import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ import sbt.io.IO diff --git a/ivy/src/test/scala/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala similarity index 100% rename from ivy/src/test/scala/MergeDescriptorSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala diff --git a/ivy/src/test/scala/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala similarity index 95% rename from ivy/src/test/scala/ModuleResolversTest.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index dea739b03..8519a6d95 100644 --- a/ivy/src/test/scala/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -1,8 +1,8 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement -import sbt.librarymanagement.ivy.UpdateOptions -import sbt.internal.librarymanagement.BaseIvySpecification +import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ +import sbt.librarymanagement.ivy.UpdateOptions import Resolver._ class ModuleResolversTest extends BaseIvySpecification { diff --git a/ivy/src/test/scala/OfflineModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala similarity index 97% rename from ivy/src/test/scala/OfflineModeSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala index 5bf20732b..5b0b7ed34 100644 --- a/ivy/src/test/scala/OfflineModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala @@ -1,8 +1,8 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement +import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions import org.scalatest.Assertion -import sbt.internal.librarymanagement._ import sbt.io.IO class OfflineModeSpec extends BaseIvySpecification { diff --git a/ivy/src/test/scala/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala similarity index 97% rename from ivy/src/test/scala/ScalaOverrideTest.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index 57ee011cc..cbc5765c0 100644 --- a/ivy/src/test/scala/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -1,12 +1,11 @@ -package sbt.librarymanagement +package sbt.internal.librarymanagement import org.apache.ivy.core.module.id.ModuleRevisionId import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor -import sbt.internal.librarymanagement.UnitSpec - import sbt.internal.librarymanagement.IvyScalaUtil.OverrideScalaMediator -import ScalaArtifacts._ +import sbt.librarymanagement._ +import sbt.librarymanagement.ScalaArtifacts._ class ScalaOverrideTest extends UnitSpec { val OtherOrgID = "other.org" diff --git a/ivy/src/test/scala/UpdateOptionsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala similarity index 89% rename from ivy/src/test/scala/UpdateOptionsSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala index 831d2934e..9b7c9c126 100644 --- a/ivy/src/test/scala/UpdateOptionsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala @@ -1,6 +1,6 @@ -package sbt.librarymanagement.ivy +package sbt.internal.librarymanagement -import sbt.internal.librarymanagement.UnitSpec +import sbt.librarymanagement.ivy._ class UpdateOptionsSpec extends UnitSpec { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 3d4a59e93..ef197fc47 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -45,8 +45,8 @@ object Dependencies { val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") - val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test - val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" % Test + val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" + val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } From 375333144cb6aeed5b5cdea464d951e978ee2d85 Mon Sep 17 00:00:00 2001 From: Stephen Nancekivell Date: Sun, 14 Jan 2018 19:19:20 +1100 Subject: [PATCH 0717/1030] Add a warning for resolver access denied errors. --- .../internal/librarymanagement/ivyint/GigahorseUrlHandler.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index b8da74aab..866808c58 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -242,6 +242,8 @@ object GigahorseUrlHandler { Message.debug("HTTP response status: " + status + " url=" + url) if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { Message.warn("Your proxy requires authentication.") + } else if (status == 401) { + Message.warn("CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password.") } else if (String.valueOf(status).startsWith("4")) { Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) } else if (String.valueOf(status).startsWith("5")) { From 86c59d8f72b716492f021367ac572a2618af0b6b Mon Sep 17 00:00:00 2001 From: OlegYch Date: Thu, 18 Jan 2018 16:04:37 +0300 Subject: [PATCH 0718/1030] avoid deadlocks on spotty connections, fix https://github.com/sbt/sbt/issues/3738 --- .../librarymanagement/ivyint/ParallelResolveEngine.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) mode change 100644 => 100755 ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala old mode 100644 new mode 100755 index 4e3b4bedd..326c500b2 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -38,7 +38,9 @@ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, val allDownloads = dependencies.par.flatMap { dep => if (!(dep.isCompletelyEvicted || dep.hasProblem) && dep.getModuleRevision != null) { - ParArray(downloadNodeArtifacts(dep, artifactFilter, options)) + scala.concurrent.blocking { + ParArray(downloadNodeArtifacts(dep, artifactFilter, options)) + } } else ParArray.empty[DownloadResult] } From d267b6fda5970fb0a465579c2698605512048736 Mon Sep 17 00:00:00 2001 From: OlegYch Date: Thu, 18 Jan 2018 18:27:03 +0300 Subject: [PATCH 0719/1030] clarify intent --- .../librarymanagement/ivyint/ParallelResolveEngine.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 326c500b2..f461d0cdf 100755 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -38,6 +38,7 @@ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, val allDownloads = dependencies.par.flatMap { dep => if (!(dep.isCompletelyEvicted || dep.hasProblem) && dep.getModuleRevision != null) { + //don't block in global ec to avoid deadlocks scala.concurrent.blocking { ParArray(downloadNodeArtifacts(dep, artifactFilter, options)) } From 5e275da2a9c25a975c2304089f9bf389f1b0f430 Mon Sep 17 00:00:00 2001 From: Andreas Jim-Hartmann Date: Tue, 30 Jan 2018 08:50:08 +0100 Subject: [PATCH 0720/1030] Fix typo. --- core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 6245b5f6c..90de0250f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -331,6 +331,6 @@ object EvictionWarning { } } if (out.isEmpty) Nil - else List("Here are other depedency conflicts that were resolved:", "") ::: out.toList + else List("Here are other dependency conflicts that were resolved:", "") ::: out.toList } else Nil } From bfe347cd22f9b362e2f12b501ba6c6c16b1af85f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Feb 2018 10:46:24 +0000 Subject: [PATCH 0721/1030] Update version/mimaPreviousArtifacts/sbt.version --- build.sbt | 6 ++---- project/build.properties | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index a32a71f16..642a91b22 100644 --- a/build.sbt +++ b/build.sbt @@ -2,8 +2,6 @@ import Dependencies._ import Path._ //import com.typesafe.tools.mima.core._, ProblemFilters._ -def baseVersion = "1.0.0-SNAPSHOT" - def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, // publishArtifact in packageDoc := false, @@ -32,7 +30,7 @@ def commonSettings: Seq[Setting[_]] = Seq( val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", - "1.1.0", "1.1.1", "1.1.2", + "1.1.0", "1.1.1", "1.1.2", "1.1.3", ) map (version => organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) @@ -61,7 +59,7 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile in Sbt := false, - git.baseVersion := baseVersion, + git.baseVersion := "1.1.3", version := { val v = version.value if (v contains "SNAPSHOT") git.baseVersion.value diff --git a/project/build.properties b/project/build.properties index 394cb75cf..31334bbd3 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.0.4 +sbt.version=1.1.1 From 06c3d22319c5b780d5f6b10ac05d20382a1999dc Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Feb 2018 08:03:41 +0000 Subject: [PATCH 0722/1030] Define lmCommonTest as a test-only dependency --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index cd22ba230..b240ea8f3 100644 --- a/build.sbt +++ b/build.sbt @@ -131,7 +131,7 @@ lazy val lmCommonTest = (project in file("common-test")) lazy val lmIvy = (project in file("ivy")) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(lmCore, lmCommonTest) + .dependsOn(lmCore, lmCommonTest % Test) .settings( commonSettings, name := "librarymanagement-ivy", From 60b9c7dacba908a8c79f5f25353ba76fb4dd6ecf Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Feb 2018 08:28:22 +0000 Subject: [PATCH 0723/1030] Remove a bunch of compilation warnings --- build.sbt | 28 +++++--- .../AbstractEngineSpec.scala | 2 +- .../librarymanagement/EvictionWarning.scala | 7 ++ .../librarymanagement/RichUpdateReport.scala | 1 - .../ivy/InlineIvyConfiguration.scala | 1 + ivy/src/main/contraband/lm-ivy.json | 1 + .../librarymanagement/ConvertResolver.scala | 3 +- .../sbt/internal/librarymanagement/Ivy.scala | 20 ++---- .../librarymanagement/IvyActions.scala | 12 ++-- .../librarymanagement/IvyRetrieve.scala | 5 +- .../librarymanagement/IvyScalaUtil.scala | 3 +- .../CachedResolutionResolveEngine.scala | 72 +++++++++---------- .../ivyint/GigahorseUrlHandler.scala | 3 +- .../ivyint/ParallelResolveEngine.scala | 0 .../ivyint/SbtChainResolver.scala | 3 +- .../EvictionWarningSpec.scala | 55 +++++++------- 16 files changed, 107 insertions(+), 109 deletions(-) mode change 100755 => 100644 ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala diff --git a/build.sbt b/build.sbt index b240ea8f3..40a6424b8 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,5 @@ import Dependencies._ import Path._ -//import com.typesafe.tools.mima.core._, ProblemFilters._ def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, @@ -35,15 +34,6 @@ val mimaSettings = Def settings ( organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) ), - mimaBinaryIssueFilters ++= { - import com.typesafe.tools.mima.core._ - import com.typesafe.tools.mima.core.ProblemFilters._ - Seq( - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode") - ) - } ) lazy val lmRoot = (project in file(".")) @@ -143,6 +133,24 @@ lazy val lmIvy = (project in file("ivy")) scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._, ProblemFilters._ + Seq( + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), + + // sbt.internal methods that changed type signatures and aren't used elsewhere in production code + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt#ParallelCachedResolutionResolveEngine.mergeErrors"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.cleanCachedResolutionCache"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyRetrieve.artifacts"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyScalaUtil.checkModule"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptor"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptors"), + exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors") + ) + }, ) def customCommands: Seq[Setting[_]] = Seq( diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala index 614f8d34a..f8b404e9f 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala @@ -17,5 +17,5 @@ abstract class AbstractEngineSpec extends UnitSpec { case Left(w) => throw w.resolveException } - def cleanCachedResolutionCache(module: ModuleDescriptor): Unit = () + def cleanCachedResolutionCache(@deprecated("unused", "") module: ModuleDescriptor): Unit = () } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 90de0250f..6b782bf8b 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -192,11 +192,18 @@ final class EvictionWarning private[sbt] ( } object EvictionWarning { + @deprecated("Use variant that doesn't take an unused logger", "1.2.0") def apply( module: ModuleDescriptor, options: EvictionWarningOptions, report: UpdateReport, log: Logger + ): EvictionWarning = apply(module, options, report) + + def apply( + module: ModuleDescriptor, + options: EvictionWarningOptions, + report: UpdateReport ): EvictionWarning = { val evictions = buildEvictions(options, report) processEvictions(module, options, evictions) diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 97f672faa..c97bf9da1 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement import java.io.File -import java.io.FileNotFoundException import sbt.io.IO /** diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index 0d781c437..0ec6e904b 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -76,6 +76,7 @@ final class InlineIvyConfiguration private ( } object InlineIvyConfiguration { /** Provided for backward compatibility. */ + @deprecated("Use an alternative apply", "1.2.0") def apply( paths: sbt.librarymanagement.ivy.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], diff --git a/ivy/src/main/contraband/lm-ivy.json b/ivy/src/main/contraband/lm-ivy.json index dc239f8d8..383e17549 100644 --- a/ivy/src/main/contraband/lm-ivy.json +++ b/ivy/src/main/contraband/lm-ivy.json @@ -78,6 +78,7 @@ ], "extraCompanion": [ "/** Provided for backward compatibility. */", + "@deprecated(\"Use an alternative apply\", \"1.2.0\")", "def apply(", " paths: sbt.librarymanagement.ivy.IvyPaths,", " resolvers: Vector[sbt.librarymanagement.Resolver],", diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index cc13ea745..0cc3bbbe1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -246,7 +246,6 @@ private[sbt] object ConvertResolver { import sbt.io.syntax._ private def downloadChecksum(resource: Resource, - target: File, targetChecksumFile: File, algorithm: String): Boolean = { if (!ChecksumHelper.isKnownAlgorithm(algorithm)) @@ -278,7 +277,7 @@ private[sbt] object ConvertResolver { // Continue checking until we hit a failure val checksumFile = new File(targetPath.stripSuffix(PartEnd) + s".$algorithm") if (checked) checked - else downloadChecksum(resource, target, checksumFile, algorithm) + else downloadChecksum(resource, checksumFile, algorithm) } // -ivy deviation size diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index cdbfd2ee3..5a257844e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -207,12 +207,8 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } } - /** - * Cleans cached resolution cache. - * - * @param md - module descriptor of the original Ivy graph. - */ - private[sbt] def cleanCachedResolutionCache(md: ModuleDescriptor, log: Logger): Unit = { + /** Cleans cached resolution cache. */ + private[sbt] def cleanCachedResolutionCache(): Unit = { if (!configuration.updateOptions.cachedResolution) () else IvySbt.cachedResolutionResolveCache.clean() } @@ -260,12 +256,9 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } val configs = configurations - moduleSettings.scalaModuleInfo match { - case Some(is) => - val svc = configs.toVector filter Configurations.underScalaVersion map { _.name } - IvyScalaUtil.checkModule(baseModule, baseConfiguration, svc, getLog(configuration.log))( - is) - case _ => // do nothing + moduleSettings.scalaModuleInfo foreach { is => + val svc = configs filter Configurations.underScalaVersion map { _.name } + IvyScalaUtil.checkModule(baseModule, svc, getLog(configuration.log))(is) } IvySbt.addExtraNamespace(baseModule) (baseModule, baseConfiguration) @@ -278,8 +271,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => "Default", ModuleDescriptor.DEFAULT_CONFIGURATION) log.debug( - "Using inline dependencies specified in Scala" + (if (ivyXML.isEmpty) "." - else " and XML.") + s"Using inline dependencies specified in Scala${(if (ivyXML.isEmpty) "" else " and XML")}." ) val parser = IvySbt.parseIvyXML( diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index e62d7b0ca..e5b31cad4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -51,8 +51,8 @@ object IvyActions { * This is called by clean. */ private[sbt] def cleanCachedResolutionCache(module: IvySbt#Module, log: Logger): Unit = - module.withModule(log) { (ivy, md, default) => - module.owner.cleanCachedResolutionCache(md, log) + module.withModule(log) { (_, _, _) => + module.owner.cleanCachedResolutionCache() } /** Creates a Maven pom from the given Ivy configuration*/ @@ -188,7 +188,7 @@ object IvyActions { log: Logger ): Either[UnresolvedWarning, UpdateReport] = { module.withModule(log) { - case (ivy, moduleDescriptor, defaultConf) => + case (ivy, moduleDescriptor, _) => // Warn about duplicated and inconsistent dependencies val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) iw.foreach(log.warn(_)) @@ -202,7 +202,7 @@ object IvyActions { val cache = metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) cachedResolveAndRetrieve(inputs, cache) - } else resolveAndRetrieve(inputs, defaultConf) + } else resolveAndRetrieve(inputs) } // Convert to unresolved warning or retrieve update report @@ -287,12 +287,10 @@ object IvyActions { * like its counterpart [[CachedResolutionResolveEngine.customResolve]]. * * @param inputs The resolution inputs. - * @param defaultModuleConfiguration The default ivy configuration. * @return The result of the resolution. */ private[this] def resolveAndRetrieve( - inputs: ResolutionInputs, - defaultModuleConfiguration: String + inputs: ResolutionInputs ): Either[ResolveException, UpdateReport] = { // Populate resolve options from the passed arguments val ivyInstance = inputs.ivy diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 728ffde1b..e38618ddd 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -28,12 +28,11 @@ object IvyRetrieve { @deprecated("Internal only. No longer in use.", "0.13.6") def artifactReports(mid: ModuleID, artReport: Seq[ArtifactDownloadReport]): ModuleReport = { - val (resolved, missing) = artifacts(mid, artReport) + val (resolved, missing) = artifacts(artReport) ModuleReport(mid, resolved, missing) } private[sbt] def artifacts( - mid: ModuleID, artReport: Seq[ArtifactDownloadReport] ): (Vector[(Artifact, File)], Vector[Artifact]) = { val missing = new mutable.ListBuffer[Artifact] @@ -180,7 +179,7 @@ object IvyRetrieve { case _ => Vector.empty } val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } - val (resolved, missing) = artifacts(moduleId, confReport getDownloadReports revId) + val (resolved, missing) = artifacts(confReport getDownloadReports revId) ModuleReport( moduleId, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index ed21d56ae..bc53f3256 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -6,7 +6,7 @@ package sbt.internal.librarymanagement import java.util.Collections.emptyMap import scala.collection.mutable.HashSet -import org.apache.ivy.core.module.descriptor.{ Configuration => _, _ } +import org.apache.ivy.core.module.descriptor._ import org.apache.ivy.core.module.id.{ ArtifactId, ModuleId, ModuleRevisionId } import org.apache.ivy.plugins.matcher.ExactPatternMatcher import org.apache.ivy.plugins.namespace.NamespaceTransformer @@ -19,7 +19,6 @@ object IvyScalaUtil { /** Performs checks/adds filters on Scala dependencies (if enabled in ScalaModuleInfo). */ def checkModule( module: DefaultModuleDescriptor, - conf: String, scalaVersionConfigs: Vector[String], log: Logger )(check: ScalaModuleInfo): Unit = { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7f751ba3d..d2d8086ba 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -65,10 +65,10 @@ private[sbt] class CachedResolutionResolveCache { def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector + // Returns a vector of (module descriptor, changing, dd) def buildArtificialModuleDescriptors( md0: ModuleDescriptor, - data: ResolveData, prOpt: Option[ProjectResolver], log: Logger ): Vector[(DefaultModuleDescriptor, Boolean, DependencyDescriptor)] = { @@ -80,9 +80,10 @@ private[sbt] class CachedResolutionResolveCache { s"""${x.getName}:${x.getType}:${x.getExt}:${x.getExtraAttributes}""" } log.debug(s"::: dd: $dd (artifacts: ${arts.mkString(",")})") - buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt, log) + buildArtificialModuleDescriptor(dd, rootModuleConfigs, md0, prOpt) } } + def internalDependency( dd: DependencyDescriptor, prOpt: Option[ProjectResolver] @@ -91,12 +92,12 @@ private[sbt] class CachedResolutionResolveCache { case Some(pr) => pr.getModuleDescriptor(dd.getDependencyRevisionId) case _ => None } + def buildArtificialModuleDescriptor( dd: DependencyDescriptor, rootModuleConfigs: Vector[IvyConfiguration], parent: ModuleDescriptor, - prOpt: Option[ProjectResolver], - log: Logger + prOpt: Option[ProjectResolver] ): (DefaultModuleDescriptor, Boolean, DependencyDescriptor) = { def excludeRuleString(rule: ExcludeRule): String = s"""Exclude(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" @@ -363,7 +364,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val os = cache.extractOverrides(md0) val options1 = new ResolveOptions(options0) val data = new ResolveData(this, options1) - val mds = cache.buildArtificialModuleDescriptors(md0, data, projectResolver, log) + val mds = cache.buildArtificialModuleDescriptors(md0, projectResolver, log) def doWork( md: ModuleDescriptor, @@ -475,15 +476,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { os: Vector[IvyOverride], log: Logger ): Either[ResolveException, UpdateReport] = - if (!missingOk && (results exists { _.isLeft })) Left(mergeErrors(md0, results collect { - case Left(re) => re - }, log)) + if (!missingOk && (results exists { _.isLeft })) + Left(mergeErrors(md0, results collect { case Left(re) => re })) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) - def mergeErrors( - md0: ModuleDescriptor, - errors: Vector[ResolveException], - log: Logger - ): ResolveException = { + + def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException]): ResolveException = { val messages = errors flatMap { _.messages } val failed = errors flatMap { _.failed } val failedPaths = errors flatMap { @@ -497,6 +494,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } new ResolveException(messages, failed, ListMap(failedPaths: _*)) } + def mergeReports( md0: ModuleDescriptor, reports: Vector[UpdateReport], @@ -524,6 +522,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } UpdateReport(cachedDescriptor, configReports, stats, Map.empty) } + // memory usage 62%, of which 58% is in mergeOrganizationArtifactReports def mergeConfigurationReports( rootModuleConf: ConfigRef, @@ -752,12 +751,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { s":: merging module reports for $rootModuleConf: ${modules.head.module.organization}:${modules.head.module.name}" ) } - def mergeModuleReports( - org: String, - name: String, - version: String, - xs: Vector[ModuleReport] - ): ModuleReport = { + def mergeModuleReports(xs: Vector[ModuleReport]): ModuleReport = { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. @@ -773,9 +767,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) }).toSeq.toVector flatMap { - case ((org, name, version), xs) => + case (_, xs) => if (xs.size < 2) xs - else Vector(mergeModuleReports(org, name, version, xs)) + else Vector(mergeModuleReports(xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty @@ -805,26 +799,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { mr.callers forall { c => em(c.caller) } - val reports - : Seq[((String, String), Vector[OrganizationArtifactReport])] = reports0.toSeq flatMap { - case (k, v) if !(pairs contains k) => Seq() - case ((organization, name), oars0) => - val oars = oars0 map { oar => - val (affected, unaffected) = oar.modules partition { mr => - val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) - if (x) { - log.debug(s""":::: transitively evicted $rootModuleConf: ${mr.module}""") + val reports: Seq[((String, String), Vector[OrganizationArtifactReport])] = + reports0.toSeq flatMap { + case (k, _) if !(pairs contains k) => Seq() + case ((organization, name), oars0) => + val oars = oars0 map { oar => + val (affected, unaffected) = oar.modules partition { mr => + val x = !mr.evicted && mr.problem.isEmpty && isTransitivelyEvicted(mr) + if (x) { + log.debug(s""":::: transitively evicted $rootModuleConf: ${mr.module}""") + } + x } - x + val newlyEvicted = affected map { + _.withEvicted(true).withEvictedReason(Some("transitive-evict")) + } + if (affected.isEmpty) oar + else OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) } - val newlyEvicted = affected map { - _.withEvicted(true).withEvictedReason(Some("transitive-evict")) - } - if (affected.isEmpty) oar - else OrganizationArtifactReport(organization, name, unaffected ++ newlyEvicted) - } - Seq(((organization, name), oars)) - } + Seq(((organization, name), oars)) + } Map(reports: _*) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 866808c58..6a2e7acba 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -243,7 +243,8 @@ object GigahorseUrlHandler { if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { Message.warn("Your proxy requires authentication.") } else if (status == 401) { - Message.warn("CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password.") + Message.warn( + "CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password.") } else if (String.valueOf(status).startsWith("4")) { Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) } else if (String.valueOf(status).startsWith("5")) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala old mode 100755 new mode 100644 diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index fb2e9b1d3..d16ec40e3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -219,7 +219,7 @@ private[sbt] case class SbtChainResolver( Message.warn(s"Choosing $resolver for ${resolvedModule.getId}") // Now that we know the real latest revision, let's force Ivy to use it val resolvedDescriptor = resolvedModule.getDescriptor - val artifactOpt = findFirstArtifactRef(resolvedDescriptor, descriptor, data, resolver) + val artifactOpt = findFirstArtifactRef(resolvedDescriptor, data, resolver) // If `None` do nothing -- modules without artifacts. Otherwise cache. artifactOpt.foreach { artifactRef => val dep = toSystem(descriptor) @@ -385,7 +385,6 @@ private[sbt] case class SbtChainResolver( /** Ported from BasicResolver#findFirstAirfactRef. */ private[this] def findFirstArtifactRef( md: ModuleDescriptor, - dd: DependencyDescriptor, data: ResolveData, resolver: DependencyResolver ): Option[ResolvedResource] = { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 488ead1f3..e2ced784f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -48,8 +48,8 @@ class EvictionWarningSpec extends BaseIvySpecification { val m1 = "org.scala-sbt" % "util-logging" % "0.13.16" val m2 = "org.scala-sbt" % "util-logging" % "0.13.1" assert( - EvictionWarningOptions - .defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.10.6")))) == false) + !EvictionWarningOptions.defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.10.6")))) + ) } "Comparing sbt 1.x" should "use Semantic Versioning semantics" in { @@ -93,19 +93,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size (1) + EvictionWarning(m, defaultOptions, report).scalaEvictions should have size (1) } def scalaVersionWarn2() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) } def scalaVersionWarn3() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(false), report, log).lines shouldBe + EvictionWarning(m, defaultOptions.withShowCallers(false), report).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", @@ -119,7 +119,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", @@ -135,13 +135,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn5() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).scalaEvictions should have size (0) + EvictionWarning(m, defaultOptions, report).scalaEvictions should have size (0) } def scalaVersionWarn6() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report, log).scalaEvictions should have size (0) + EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) } def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) @@ -149,24 +149,25 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn1() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) } def javaLibWarn2() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, - defaultOptions - .withWarnDirectEvictions(false) - .withWarnTransitiveEvictions(false), - report, - log).reportedEvictions should have size (0) + EvictionWarning( + m, + defaultOptions + .withWarnDirectEvictions(false) + .withWarnTransitiveEvictions(false), + report + ).reportedEvictions should have size (0) } def javaLibWarn3() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -180,7 +181,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn4() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report, log).lines shouldBe + EvictionWarning(m, defaultOptions.withShowCallers(true), report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -195,14 +196,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (0) } def javaLibNoWarn2() = { val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil + EvictionWarning(m, defaultOptions, report).lines shouldBe Nil } def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) @@ -210,13 +211,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveWarn2() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) } def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", @@ -228,14 +229,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) } def scalaLibWarn2() = { val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -250,14 +251,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (0) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (0) } def scalaLibNoWarn2() = { val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe Nil + EvictionWarning(m, defaultOptions, report).lines shouldBe Nil } def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) @@ -265,13 +266,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveWarn2() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).reportedEvictions should have size (1) + EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) } def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report, log).lines shouldBe + EvictionWarning(m, defaultOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", From 091edf6ea1dc4533e6c55c0be725026516733bbb Mon Sep 17 00:00:00 2001 From: exoego Date: Thu, 15 Feb 2018 22:06:55 +0900 Subject: [PATCH 0724/1030] Add a new eviction warning summary to decide whether or not to warn eviction summary. --- .../librarymanagement/EvictionWarning.scala | 41 ++++++++++++--- .../EvictionWarningSpec.scala | 51 +++++++++++++++++-- 2 files changed, 81 insertions(+), 11 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 6b782bf8b..cccbfe801 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -11,6 +11,7 @@ final class EvictionWarningOptions private[sbt] ( val warnScalaVersionEviction: Boolean, val warnDirectEvictions: Boolean, val warnTransitiveEvictions: Boolean, + val warnEvictionSummary: Boolean, val infoAllEvictions: Boolean, val showCallers: Boolean, val guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] @@ -23,6 +24,8 @@ final class EvictionWarningOptions private[sbt] ( copy(warnDirectEvictions = warnDirectEvictions) def withWarnTransitiveEvictions(warnTransitiveEvictions: Boolean): EvictionWarningOptions = copy(warnTransitiveEvictions = warnTransitiveEvictions) + def withWarnEvictionSummary(warnEvictionSummary: Boolean): EvictionWarningOptions = + copy(warnEvictionSummary = warnEvictionSummary) def withInfoAllEvictions(infoAllEvictions: Boolean): EvictionWarningOptions = copy(infoAllEvictions = infoAllEvictions) def withShowCallers(showCallers: Boolean): EvictionWarningOptions = @@ -37,6 +40,7 @@ final class EvictionWarningOptions private[sbt] ( warnScalaVersionEviction: Boolean = warnScalaVersionEviction, warnDirectEvictions: Boolean = warnDirectEvictions, warnTransitiveEvictions: Boolean = warnTransitiveEvictions, + warnEvictionSummary: Boolean = warnEvictionSummary, infoAllEvictions: Boolean = infoAllEvictions, showCallers: Boolean = showCallers, guessCompatible: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = @@ -47,6 +51,7 @@ final class EvictionWarningOptions private[sbt] ( warnScalaVersionEviction = warnScalaVersionEviction, warnDirectEvictions = warnDirectEvictions, warnTransitiveEvictions = warnTransitiveEvictions, + warnEvictionSummary = warnEvictionSummary, infoAllEvictions = infoAllEvictions, showCallers = showCallers, guessCompatible = guessCompatible @@ -55,19 +60,23 @@ final class EvictionWarningOptions private[sbt] ( object EvictionWarningOptions { def empty: EvictionWarningOptions = - new EvictionWarningOptions(Vector(), - warnScalaVersionEviction = false, - warnDirectEvictions = false, - warnTransitiveEvictions = false, - infoAllEvictions = false, - showCallers = false, - defaultGuess) + new EvictionWarningOptions( + Vector(), + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + warnEvictionSummary = false, + infoAllEvictions = false, + showCallers = false, + defaultGuess + ) def default: EvictionWarningOptions = new EvictionWarningOptions( Vector(Compile), warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, + warnEvictionSummary = false, infoAllEvictions = false, showCallers = true, defaultGuess @@ -78,10 +87,22 @@ object EvictionWarningOptions { warnScalaVersionEviction = true, warnDirectEvictions = true, warnTransitiveEvictions = true, + warnEvictionSummary = false, infoAllEvictions = true, showCallers = true, defaultGuess ) + def summary: EvictionWarningOptions = + new EvictionWarningOptions( + Vector(Compile), + warnScalaVersionEviction = false, + warnDirectEvictions = false, + warnTransitiveEvictions = false, + warnEvictionSummary = true, + infoAllEvictions = false, + showCallers = false, + defaultGuess + ) lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessSbtOne orElse guessSecondSegment orElse guessSemVer orElse guessFalse @@ -303,6 +324,10 @@ object EvictionWarning { implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => import ShowLines._ val out: mutable.ListBuffer[String] = mutable.ListBuffer() + if (a.options.warnEvictionSummary && a.allEvictions.nonEmpty) { + out += "There may be incompatibilities among your library dependencies." + } + if (a.scalaEvictions.nonEmpty) { out += "Scala version was updated by one of library dependencies:" out ++= (a.scalaEvictions flatMap { _.lines }) @@ -317,7 +342,7 @@ object EvictionWarning { out ++= (a.transitiveEvictions flatMap { _.lines }) } - if (a.allEvictions.nonEmpty && a.reportedEvictions.nonEmpty) { + if (a.allEvictions.nonEmpty && (a.options.warnEvictionSummary || a.reportedEvictions.nonEmpty)) { out += "Run 'evicted' to see detailed eviction warnings" } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index e2ced784f..ffc6e1f70 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -12,16 +12,18 @@ class EvictionWarningSpec extends BaseIvySpecification { it should "not be detected if it's disabled" in scalaVersionWarn2() it should "print out message about the eviction" in scalaVersionWarn3() it should "print out message about the eviction with callers" in scalaVersionWarn4() + it should "print out summary about the eviction if warn eviction summary enabled" in scalaVersionWarn5() """Non-eviction of overridden scala-library whose scalaVersion - """ should "not be detected if it's enabled" in scalaVersionWarn5() - it should "not be detected if it's disabled" in scalaVersionWarn6() + """ should "not be detected if it's enabled" in scalaVersionNoWarn1() + it should "not be detected if it's disabled" in scalaVersionNoWarn2() """Including two (suspect) binary incompatible Java libraries to direct dependencies """ should "be detected as eviction" in javaLibWarn1() it should "not be detected if it's disabled" in javaLibWarn2() it should "print out message about the eviction" in javaLibWarn3() it should "print out message about the eviction with callers" in javaLibWarn4() + it should "print out summary about the eviction if warn eviction summary enabled" in javaLibWarn5() """Including two (suspect) binary compatible Java libraries to direct dependencies """ should "not be detected as eviction" in javaLibNoWarn1() @@ -35,6 +37,7 @@ class EvictionWarningSpec extends BaseIvySpecification { """Including two (suspect) binary incompatible Scala libraries to direct dependencies """ should "be detected as eviction" in scalaLibWarn1() it should "print out message about the eviction" in scalaLibWarn2() + it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibWarn3() """Including two (suspect) binary compatible Scala libraries to direct dependencies """ should "not be detected as eviction" in scalaLibNoWarn1() @@ -43,6 +46,7 @@ class EvictionWarningSpec extends BaseIvySpecification { """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies """ should "be detected as eviction" in scalaLibTransitiveWarn2() it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() + it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibTransitiveWarn4() "Comparing sbt 0.x" should "use Second Segment Variation semantics" in { val m1 = "org.scala-sbt" % "util-logging" % "0.13.16" @@ -133,12 +137,22 @@ class EvictionWarningSpec extends BaseIvySpecification { } def scalaVersionWarn5() = { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe + List( + "There may be incompatibilities among your library dependencies.", + "Run 'evicted' to see detailed eviction warnings" + ) + } + + def scalaVersionNoWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions, report).scalaEvictions should have size (0) } - def scalaVersionWarn6() = { + def scalaVersionNoWarn2() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) @@ -192,6 +206,16 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } + def javaLibWarn5() = { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe + List( + "There may be incompatibilities among your library dependencies.", + "Run 'evicted' to see detailed eviction warnings" + ) + } + def javaLibNoWarn1() = { val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) @@ -247,6 +271,17 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } + def scalaLibWarn3() = { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe + List( + "There may be incompatibilities among your library dependencies.", + "Run 'evicted' to see detailed eviction warnings" + ) + } + def scalaLibNoWarn1() = { val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) @@ -285,6 +320,16 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } + def scalaLibTransitiveWarn4() = { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe + List( + "There may be incompatibilities among your library dependencies.", + "Run 'evicted' to see detailed eviction warnings" + ) + } + def dummyScalaModuleInfo(v: String): ScalaModuleInfo = ScalaModuleInfo( scalaFullVersion = v, From f8dbbd85b98e80e23faa5dec9191dd58dce5b2bc Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 17 Feb 2018 10:42:53 +0900 Subject: [PATCH 0725/1030] Add mima filter --- build.sbt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 40a6424b8..56b41dadc 100644 --- a/build.sbt +++ b/build.sbt @@ -104,6 +104,14 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, + mimaBinaryIssueFilters ++= { + import com.typesafe.tools.mima.core._, ProblemFilters._ + Seq( + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.this"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.copy"), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.EvictionWarningOptions.copy$default$7") + ) + } ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -116,7 +124,7 @@ lazy val lmCommonTest = (project in file("common-test")) libraryDependencies ++= Seq(scalaTest, scalaCheck), scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), - mimaSettings, + mimaSettings ) lazy val lmIvy = (project in file("ivy")) From 4f2933d3646af1bb7218b5592991a94b19447fb6 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 20 Feb 2018 18:50:22 +1000 Subject: [PATCH 0726/1030] Cache the hashCode of Configuration I noticed this was showing up in profiles when SBT's task engine was using Keys, etc (that contain Configurations) in HashMap's. Let's cache it instead. I don't think there is a need to use a lazy val for this, we can compute it eagerly. --- core/src/main/scala/sbt/librarymanagement/Configuration.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index 9f642efd6..2306efdda 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -31,7 +31,7 @@ final class Configuration private[sbt] ( (this.transitive == x.transitive) case _ => false } - override def hashCode: Int = { + override val hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + id.##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) } override def toString: String = { From 42e23e54ff99e4e97d9c7c31256a4378a7533ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A5le=20Undheim?= Date: Sat, 24 Feb 2018 00:25:34 +0100 Subject: [PATCH 0727/1030] Fix to issue #180 to handle null contentType If the content type is null, the call for .toString on it will cause an NPE. This fixes this issue by wrapping the call in an Option, then mapping toString or falling back to null. getCharSetFromContentType handles null by returning ISO-8859-1 --- .../internal/librarymanagement/ivyint/GigahorseUrlHandler.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index b8da74aab..e83f55177 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -51,7 +51,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { if (checkStatusCode(url, response)) { val bodyCharset = - BasicURLHandler.getCharSetFromContentType(response.body().contentType().toString) + BasicURLHandler.getCharSetFromContentType(Option(response.body().contentType()).map(_.toString).orNull) Some( new SbtUrlInfo(true, response.body().contentLength(), From c9e4ace8dee2b0e4a2eec5b4daba73d71e7f543d Mon Sep 17 00:00:00 2001 From: Dennis Hoersch Date: Fri, 2 Mar 2018 19:54:02 +0100 Subject: [PATCH 0728/1030] allow wildcards in groupId or artifactId According to https://maven.apache.org/pom.html#Exclusions (and https://maven.apache.org/docs/3.2.1/release-notes.html) wildcards are allowed in Maven POM's schema --- ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 3ec739e48..f91589c9d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -425,7 +425,7 @@ class MakePom(val log: Logger) { def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = { val m = exclRule.getId.getModuleId val (g, a) = (m.getOrganisation, m.getName) - if (g == null || g.isEmpty || g == "*" || a.isEmpty || a == "*") + if (g == null || g.isEmpty || a == null || a.isEmpty) Left( "Skipped generating '' for %s. Dependency exclusion should have both 'org' and 'module' to comply with Maven POM's schema." .format(m) From 245997c84ee4f05c73d7f60fe5edc4ad476a4ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20H=C3=B6rsch?= Date: Sat, 3 Mar 2018 13:31:26 +0100 Subject: [PATCH 0729/1030] Added test for wildcards in org and name --- ivy/src/test/scala/InclExclSpec.scala | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ivy/src/test/scala/InclExclSpec.scala b/ivy/src/test/scala/InclExclSpec.scala index 62856f0c1..076e22b27 100644 --- a/ivy/src/test/scala/InclExclSpec.scala +++ b/ivy/src/test/scala/InclExclSpec.scala @@ -27,6 +27,13 @@ class InclExclSpec extends BaseIvySpecification { ) } + def testScalaLibraryIsMissing(report: UpdateReport): Assertion = { + assert( + !report.allModules.exists(_.name.contains("scala-library")), + "scala-library has not been excluded." + ) + } + def testScalahostIsMissing(report: UpdateReport): Assertion = { assert( !report.allModules.exists(_.name.contains("scalahost")), @@ -65,4 +72,16 @@ class InclExclSpec extends BaseIvySpecification { val report = getIvyReport(createMetaDep(excluded), scala2122) testScalahostIsMissing(report) } + + it should "exclude any version of scala-library via * artifact id" in { + val toExclude = ExclusionRule("org.scala-lang", "*") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } + + it should "exclude any version of scala-library via * org id" in { + val toExclude = ExclusionRule("*", "scala-library") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } } From 16553efb8ed937d33da103f1dbae6cc8dabcea51 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 16:19:37 +0000 Subject: [PATCH 0730/1030] Move lm-ivy MiMa issues to lm-ivy --- build.sbt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/build.sbt b/build.sbt index 642a91b22..71568c59e 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ import Dependencies._ import Path._ -//import com.typesafe.tools.mima.core._, ProblemFilters._ +import com.typesafe.tools.mima.core._, ProblemFilters._ def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, @@ -35,15 +35,6 @@ val mimaSettings = Def settings ( organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) ), - mimaBinaryIssueFilters ++= { - import com.typesafe.tools.mima.core._ - import com.typesafe.tools.mima.core.ProblemFilters._ - Seq( - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode") - ) - } ) lazy val lmRoot = (project in file(".")) @@ -131,6 +122,11 @@ lazy val lmIvy = (project in file("ivy")) scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, + mimaBinaryIssueFilters ++= Seq( + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), + ), ) def customCommands: Seq[Setting[_]] = Seq( From b969f7362cca20bfc511176997b14aa992b37898 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 9 Mar 2018 10:08:36 +0000 Subject: [PATCH 0731/1030] Make *Extra & *Functions classes private[librarymanagement] They were never meant to be public types: they're implementation detail. --- build.sbt | 6 ++++++ .../ModuleDescriptorConfiguration.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- .../librarymanagement/IvyConfigurations.scala | 6 ++---- .../scala/sbt/librarymanagement/ArtifactExtra.scala | 4 ++-- .../sbt/librarymanagement/ConfigurationExtra.scala | 4 ++-- .../sbt/librarymanagement/CrossVersionExtra.scala | 2 +- .../src/main/scala/sbt/librarymanagement/Extra.scala | 8 ++++---- .../scala/sbt/librarymanagement/ModuleIDExtra.scala | 4 ++-- .../scala/sbt/librarymanagement/ResolverExtra.scala | 12 ++++++------ .../sbt/librarymanagement/UpdateReportExtra.scala | 6 +++--- 11 files changed, 30 insertions(+), 26 deletions(-) diff --git a/build.sbt b/build.sbt index 71568c59e..84c718b8b 100644 --- a/build.sbt +++ b/build.sbt @@ -105,6 +105,12 @@ lazy val lmCore = (project in file("core")) (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, mimaSettings, + mimaBinaryIssueFilters ++= Seq( + // internal class moved + exclude[MissingClassProblem]("sbt.internal.librarymanagement.InlineConfigurationFunctions"), + // dropped internal class parent (InlineConfigurationFunctions) + exclude[MissingTypesProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration$"), + ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 92c7a3a92..552b2ae61 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -72,7 +72,7 @@ final class ModuleDescriptorConfiguration private ( copy(conflictManager = conflictManager) } } -object ModuleDescriptorConfiguration extends sbt.internal.librarymanagement.InlineConfigurationFunctions { +object ModuleDescriptorConfiguration extends sbt.librarymanagement.InlineConfigurationFunctions { def apply(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(false, None, module, moduleInfo, Vector.empty, Vector.empty, Vector.empty, scala.xml.NodeSeq.Empty, sbt.librarymanagement.Configurations.default, Option(sbt.librarymanagement.Configurations.Compile), sbt.librarymanagement.ConflictManager.default) def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Vector[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index c7a04ede8..b31b9a856 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -572,7 +572,7 @@ }, { "name": "conflictManager", "type": "sbt.librarymanagement.ConflictManager", "default": "sbt.librarymanagement.ConflictManager.default", "since": "0.0.1" } ], - "parentsCompanion": "sbt.internal.librarymanagement.InlineConfigurationFunctions" + "parentsCompanion": "sbt.librarymanagement.InlineConfigurationFunctions" } ] }, diff --git a/core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala b/core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala index 71c527322..aac26548d 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/IvyConfigurations.scala @@ -1,11 +1,9 @@ /* sbt -- Simple Build Tool * Copyright 2008, 2009, 2010 Mark Harrah */ -package sbt.internal.librarymanagement +package sbt.librarymanagement -import sbt.librarymanagement._ - -abstract class InlineConfigurationFunctions { +private[librarymanagement] abstract class InlineConfigurationFunctions { def configurations( explicitConfigurations: Iterable[Configuration], defaultConfiguration: Option[Configuration] diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 3bd58fe53..44db18be9 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement import java.io.File import java.net.URL -abstract class ArtifactExtra { +private[librarymanagement] abstract class ArtifactExtra { def name: String def `type`: String def extension: String @@ -33,7 +33,7 @@ abstract class ArtifactExtra { import Configurations.{ Optional, Pom, Test } -abstract class ArtifactFunctions { +private[librarymanagement] abstract class ArtifactFunctions { def apply(name: String, extra: Map[String, String]): Artifact = Artifact(name, DefaultType, DefaultExtension, None, Vector.empty, None, extra, None) def apply(name: String, classifier: String): Artifact = diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 83cdd2bcd..00acf7305 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -76,7 +76,7 @@ object Configurations { } } -abstract class ConfigurationExtra { +private[librarymanagement] abstract class ConfigurationExtra { def id: String def name: String def description: String @@ -142,7 +142,7 @@ private[sbt] object ConfigurationMacro { .map(_.tree.asInstanceOf[c.Tree]) } -abstract class ConfigRefFunctions { +private[librarymanagement] abstract class ConfigRefFunctions { implicit def configToConfigRef(c: Configuration): ConfigRef = c.toConfigRef } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index a57a9f4f3..725573e41 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -5,7 +5,7 @@ import sbt.librarymanagement.syntax._ final case class ScalaVersion(full: String, binary: String) -abstract class CrossVersionFunctions { +private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ final val Disabled = sbt.librarymanagement.Disabled diff --git a/core/src/main/scala/sbt/librarymanagement/Extra.scala b/core/src/main/scala/sbt/librarymanagement/Extra.scala index 03d0971f7..3d0feb29c 100644 --- a/core/src/main/scala/sbt/librarymanagement/Extra.scala +++ b/core/src/main/scala/sbt/librarymanagement/Extra.scala @@ -5,7 +5,7 @@ package sbt.librarymanagement import sbt.librarymanagement.DependencyBuilders.{ Organization, OrganizationArtifactName } -abstract class InclExclRuleFunctions { +private[librarymanagement] abstract class InclExclRuleFunctions { def everything = InclExclRule("*", "*", "*", Vector.empty, Disabled()) def apply(organization: String, name: String): InclExclRule = @@ -29,7 +29,7 @@ abstract class InclExclRuleFunctions { } } -abstract class ArtifactTypeFilterExtra { +private[librarymanagement] abstract class ArtifactTypeFilterExtra { def types: Set[String] def inverted: Boolean @@ -41,12 +41,12 @@ abstract class ArtifactTypeFilterExtra { def invert = copy(inverted = !inverted) } -abstract class ArtifactTypeFilterFunctions { +private[librarymanagement] abstract class ArtifactTypeFilterFunctions { def allow(types: Set[String]) = ArtifactTypeFilter(types, false) def forbid(types: Set[String]) = ArtifactTypeFilter(types, true) } -abstract class ConflictManagerFunctions { +private[librarymanagement] abstract class ConflictManagerFunctions { // To avoid NPE (or making the val's below lazy) // For case classes refchecks rewrites apply calls to constructor calls, we have to do it manually def apply(name: String, organization: String = "*", module: String = "*"): ConflictManager diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 7d9bfece2..60b818a30 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -9,7 +9,7 @@ import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer import sbt.librarymanagement.syntax._ -abstract class ModuleIDExtra { +private[librarymanagement] abstract class ModuleIDExtra { def organization: String def name: String def revision: String @@ -181,7 +181,7 @@ abstract class ModuleIDExtra { def branch(branchName: Option[String]) = copy(branchName = branchName) } -abstract class ModuleIDFunctions { +private[librarymanagement] abstract class ModuleIDFunctions { /** Prefixes all keys with `e:` if they are not already so prefixed. */ def checkE(attributes: Seq[(String, String)]) = diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index c8c3064f7..03974baba 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -24,12 +24,12 @@ final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(n } } -abstract class MavenRepositoryFunctions { +private[librarymanagement] abstract class MavenRepositoryFunctions { def apply(name: String, root: String, localIfFile: Boolean = true): MavenRepository = MavenRepo(name, root, localIfFile) } -abstract class PatternsFunctions { +private[librarymanagement] abstract class PatternsFunctions { implicit def defaultPatterns: Patterns = Resolver.defaultPatterns def apply(artifactPatterns: String*): Patterns = Patterns(true, artifactPatterns: _*) @@ -42,7 +42,7 @@ abstract class PatternsFunctions { } } -trait SshBasedRepositoryExtra { +private[librarymanagement] trait SshBasedRepositoryExtra { /** The object representing the configured ssh connection for this repository. */ def connection: SshConnection @@ -67,7 +67,7 @@ trait SshBasedRepositoryExtra { copy(KeyFileAuthentication(user, keyfile, password)) } -trait SshRepositoryExtra extends SshBasedRepositoryExtra { +private[librarymanagement] trait SshRepositoryExtra extends SshBasedRepositoryExtra { def name: String def patterns: sbt.librarymanagement.Patterns def publishPermissions: Option[String] @@ -78,7 +78,7 @@ trait SshRepositoryExtra extends SshBasedRepositoryExtra { SshRepository(name, connection, patterns, publishPermissions) } -trait SftpRepositoryExtra extends SshBasedRepositoryExtra { +private[librarymanagement] trait SftpRepositoryExtra extends SshBasedRepositoryExtra { def name: String def patterns: sbt.librarymanagement.Patterns @@ -93,7 +93,7 @@ private[sbt] class FakeRepository(resolver: AnyRef, name: String) extends xsbti. def rawRepository = new RawRepository(resolver, name) } -abstract class ResolverFunctions { +private[librarymanagement] abstract class ResolverFunctions { private[sbt] def useSecureResolvers = sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index e9c9c242b..cf146287b 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -6,7 +6,7 @@ package sbt.librarymanagement import java.io.File import java.{ util => ju } -abstract class ConfigurationReportExtra { +private[librarymanagement] abstract class ConfigurationReportExtra { def configuration: ConfigRef def modules: Vector[ModuleReport] def details: Vector[OrganizationArtifactReport] @@ -34,7 +34,7 @@ abstract class ConfigurationReportExtra { }, details) } -abstract class ModuleReportExtra { +private[librarymanagement] abstract class ModuleReportExtra { def module: ModuleID def artifacts: Vector[(Artifact, File)] def missingArtifacts: Vector[Artifact] @@ -126,7 +126,7 @@ abstract class ModuleReportExtra { ): ModuleReport } -abstract class UpdateReportExtra { +private[librarymanagement] abstract class UpdateReportExtra { def cachedDescriptor: File def configurations: Vector[ConfigurationReport] def stats: UpdateStats From 866b0a1d3f6037beba36e628292e74b76ceb9c3c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 15:34:48 +0000 Subject: [PATCH 0732/1030] Upgrade to contraband 0.3.3 --- .../contraband-scala/sbt/librarymanagement/Artifact.scala | 2 +- .../contraband-scala/sbt/librarymanagement/Binary.scala | 2 +- .../sbt/librarymanagement/ConflictManager.scala | 2 +- .../contraband-scala/sbt/librarymanagement/Constant.scala | 2 +- .../main/contraband-scala/sbt/librarymanagement/Full.scala | 2 +- .../sbt/librarymanagement/InclExclRule.scala | 2 +- .../sbt/librarymanagement/IvyFileConfiguration.scala | 2 +- .../contraband-scala/sbt/librarymanagement/MavenCache.scala | 2 +- .../contraband-scala/sbt/librarymanagement/MavenRepo.scala | 2 +- .../librarymanagement/ModuleDescriptorConfiguration.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ModuleID.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ModuleInfo.scala | 2 +- .../sbt/librarymanagement/ModuleReport.scala | 2 +- .../contraband-scala/sbt/librarymanagement/Patterns.scala | 2 +- .../sbt/librarymanagement/PomConfiguration.scala | 2 +- .../sbt/librarymanagement/PublishConfiguration.scala | 2 +- .../sbt/librarymanagement/RetrieveConfiguration.scala | 6 +++--- .../sbt/librarymanagement/ScalaModuleInfo.scala | 2 +- .../contraband-scala/sbt/librarymanagement/ScmInfo.scala | 2 +- .../sbt/librarymanagement/UpdateConfiguration.scala | 2 +- .../librarymanagement/ivy/ExternalIvyConfiguration.scala | 2 +- .../sbt/librarymanagement/ivy/InlineIvyConfiguration.scala | 2 +- project/plugins.sbt | 2 +- 23 files changed, 25 insertions(+), 25 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index a676be246..92c623050 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -56,6 +56,6 @@ final class Artifact private ( } object Artifact extends sbt.librarymanagement.ArtifactFunctions { - def apply(name: String): Artifact = new Artifact(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) + def apply(name: String): Artifact = new Artifact(name) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala index f06902d22..b66b5f737 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala @@ -38,6 +38,6 @@ final class Binary private ( } object Binary { - def apply(): Binary = new Binary("", "") + def apply(): Binary = new Binary() def apply(prefix: String, suffix: String): Binary = new Binary(prefix, suffix) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala index d7adb8829..97e9737bf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -37,6 +37,6 @@ final class ConflictManager private ( } object ConflictManager extends sbt.librarymanagement.ConflictManagerFunctions { - def apply(name: String): ConflictManager = new ConflictManager(name, "*", "*") + def apply(name: String): ConflictManager = new ConflictManager(name) def apply(name: String, organization: String, module: String): ConflictManager = new ConflictManager(name, organization, module) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala index 25ca45c3b..148546958 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala @@ -29,6 +29,6 @@ final class Constant private ( } object Constant { - def apply(): Constant = new Constant("") + def apply(): Constant = new Constant() def apply(value: String): Constant = new Constant(value) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala index c51ccd0db..71ea0fc87 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala @@ -38,6 +38,6 @@ final class Full private ( } object Full { - def apply(): Full = new Full("", "") + def apply(): Full = new Full() def apply(prefix: String, suffix: String): Full = new Full(prefix, suffix) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index e93c8ac2c..a6f1ec1dd 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -53,6 +53,6 @@ final class InclExclRule private ( } object InclExclRule extends sbt.librarymanagement.InclExclRuleFunctions { - def apply(): InclExclRule = new InclExclRule("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) + def apply(): InclExclRule = new InclExclRule() def apply(organization: String, name: String, artifact: String, configurations: Vector[sbt.librarymanagement.ConfigRef], crossVersion: sbt.librarymanagement.CrossVersion): InclExclRule = new InclExclRule(organization, name, artifact, configurations, crossVersion) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala index cd0a38aff..1136de05c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -43,7 +43,7 @@ final class IvyFileConfiguration private ( } object IvyFileConfiguration { - def apply(file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(false, None, file, autoScalaTools) + def apply(file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(file, autoScalaTools) def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, scalaModuleInfo, file, autoScalaTools) def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, file: java.io.File, autoScalaTools: Boolean): IvyFileConfiguration = new IvyFileConfiguration(validate, Option(scalaModuleInfo), file, autoScalaTools) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index a99bb5da9..3f10f8e04 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -45,6 +45,6 @@ final class MavenCache private ( } object MavenCache { def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile) - def apply(name: String, root: String, rootFile: java.io.File): MavenCache = new MavenCache(name, root, true, rootFile) + def apply(name: String, root: String, rootFile: java.io.File): MavenCache = new MavenCache(name, root, rootFile) def apply(name: String, root: String, localIfFile: Boolean, rootFile: java.io.File): MavenCache = new MavenCache(name, root, localIfFile, rootFile) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index f964670f1..db4a4d64b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -36,6 +36,6 @@ final class MavenRepo private ( } object MavenRepo { - def apply(name: String, root: String): MavenRepo = new MavenRepo(name, root, true) + def apply(name: String, root: String): MavenRepo = new MavenRepo(name, root) def apply(name: String, root: String, localIfFile: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 552b2ae61..215a0c367 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -74,7 +74,7 @@ final class ModuleDescriptorConfiguration private ( } object ModuleDescriptorConfiguration extends sbt.librarymanagement.InlineConfigurationFunctions { - def apply(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(false, None, module, moduleInfo, Vector.empty, Vector.empty, Vector.empty, scala.xml.NodeSeq.Empty, sbt.librarymanagement.Configurations.default, Option(sbt.librarymanagement.Configurations.Compile), sbt.librarymanagement.ConflictManager.default) + def apply(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(module, moduleInfo) def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Vector[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: Option[sbt.librarymanagement.Configuration], conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID], overrides: Vector[sbt.librarymanagement.ModuleID], excludes: Vector[sbt.librarymanagement.InclExclRule], ivyXML: scala.xml.NodeSeq, configurations: Vector[sbt.librarymanagement.Configuration], defaultConfiguration: sbt.librarymanagement.Configuration, conflictManager: sbt.librarymanagement.ConflictManager): ModuleDescriptorConfiguration = new ModuleDescriptorConfiguration(validate, Option(scalaModuleInfo), module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, Option(defaultConfiguration), conflictManager) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index 822f7d2d6..eafa0dd95 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -76,6 +76,6 @@ final class ModuleID private ( } object ModuleID extends sbt.librarymanagement.ModuleIDFunctions { - def apply(organization: String, name: String, revision: String): ModuleID = new ModuleID(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None) + def apply(organization: String, name: String, revision: String): ModuleID = new ModuleID(organization, name, revision) def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, isForce: Boolean, explicitArtifacts: Vector[sbt.librarymanagement.Artifact], inclusions: Vector[sbt.librarymanagement.InclExclRule], exclusions: Vector[sbt.librarymanagement.InclExclRule], extraAttributes: Map[String, String], crossVersion: sbt.librarymanagement.CrossVersion, branchName: Option[String]): ModuleID = new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index ae7d42f5c..e41ca76fb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -61,6 +61,6 @@ final class ModuleInfo private ( } object ModuleInfo { - def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal, "", None, None, Vector.empty, "", None, None, Vector.empty) + def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal) def apply(nameFormal: String, description: String, homepage: Option[java.net.URL], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URL]], organizationName: String, organizationHomepage: Option[java.net.URL], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 0c2526b1d..3de609527 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -101,6 +101,6 @@ final class ModuleReport private ( } object ModuleReport { - def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map.empty, None, None, Vector.empty, Vector.empty, Vector.empty) + def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts) def apply(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact], status: Option[String], publicationDate: Option[java.util.Calendar], resolver: Option[String], artifactResolver: Option[String], evicted: Boolean, evictedData: Option[String], evictedReason: Option[String], problem: Option[String], homepage: Option[String], extraAttributes: Map[String, String], isDefault: Option[Boolean], branch: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], licenses: Vector[scala.Tuple2[String, Option[String]]], callers: Vector[sbt.librarymanagement.Caller]): ModuleReport = new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala index ea43d5525..de2a54d98 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -45,6 +45,6 @@ final class Patterns private ( } object Patterns extends sbt.librarymanagement.PatternsFunctions { - def apply(): Patterns = new Patterns(Vector.empty, Vector.empty, true, false, false) + def apply(): Patterns = new Patterns() def apply(ivyPatterns: Vector[String], artifactPatterns: Vector[String], isMavenCompatible: Boolean, descriptorOptional: Boolean, skipConsistencyCheck: Boolean): Patterns = new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala index 93fdbc39c..e9cbf9219 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -43,7 +43,7 @@ final class PomConfiguration private ( } object PomConfiguration { - def apply(file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(false, None, file, autoScalaTools) + def apply(file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(file, autoScalaTools) def apply(validate: Boolean, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo], file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, scalaModuleInfo, file, autoScalaTools) def apply(validate: Boolean, scalaModuleInfo: sbt.librarymanagement.ScalaModuleInfo, file: java.io.File, autoScalaTools: Boolean): PomConfiguration = new PomConfiguration(validate, Option(scalaModuleInfo), file, autoScalaTools) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala index 8dcd7d7aa..3adc81fcf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -75,7 +75,7 @@ final class PublishConfiguration private ( } object PublishConfiguration { - def apply(): PublishConfiguration = new PublishConfiguration(true, None, None, None, None, Vector(), Vector("sha1", "md5"), None, false) + def apply(): PublishConfiguration = new PublishConfiguration() def apply(publishMavenStyle: Boolean, deliverIvyPattern: Option[String], status: Option[String], configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]], resolverName: Option[String], artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], checksums: scala.Vector[String], logging: Option[sbt.librarymanagement.UpdateLogging], overwrite: Boolean): PublishConfiguration = new PublishConfiguration(publishMavenStyle, deliverIvyPattern, status, configurations, resolverName, artifacts, checksums, logging, overwrite) def apply(publishMavenStyle: Boolean, deliverIvyPattern: String, status: String, configurations: scala.Vector[sbt.librarymanagement.ConfigRef], resolverName: String, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], checksums: scala.Vector[String], logging: sbt.librarymanagement.UpdateLogging, overwrite: Boolean): PublishConfiguration = new PublishConfiguration(publishMavenStyle, Option(deliverIvyPattern), Option(status), Option(configurations), Option(resolverName), artifacts, checksums, Option(logging), overwrite) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala index 7a063b474..205218b04 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -50,9 +50,9 @@ final class RetrieveConfiguration private ( } object RetrieveConfiguration { - def apply(): RetrieveConfiguration = new RetrieveConfiguration(None, None, false, None) - def apply(retrieveDirectory: Option[java.io.File], outputPattern: Option[String]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, false, None) - def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(Option(retrieveDirectory), Option(outputPattern), false, None) + def apply(): RetrieveConfiguration = new RetrieveConfiguration() + def apply(retrieveDirectory: Option[java.io.File], outputPattern: Option[String]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern) + def apply(retrieveDirectory: java.io.File, outputPattern: String): RetrieveConfiguration = new RetrieveConfiguration(Option(retrieveDirectory), Option(outputPattern)) def apply(retrieveDirectory: Option[java.io.File], outputPattern: Option[String], sync: Boolean, configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]]): RetrieveConfiguration = new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) def apply(retrieveDirectory: java.io.File, outputPattern: String, sync: Boolean, configurationsToRetrieve: scala.Vector[sbt.librarymanagement.ConfigRef]): RetrieveConfiguration = new RetrieveConfiguration(Option(retrieveDirectory), Option(outputPattern), sync, Option(configurationsToRetrieve)) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index 73afbfcb9..36431b387 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -56,6 +56,6 @@ final class ScalaModuleInfo private ( } object ScalaModuleInfo { - def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion) def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 19766ac5e..713654f4e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -40,7 +40,7 @@ final class ScmInfo private ( } object ScmInfo { - def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection, None) + def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) def apply(browseUrl: java.net.URL, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) def apply(browseUrl: java.net.URL, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index b62d6e719..39fce50be 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -76,7 +76,7 @@ final class UpdateConfiguration private ( } object UpdateConfiguration { - def apply(): UpdateConfiguration = new UpdateConfiguration(None, false, sbt.librarymanagement.UpdateLogging.Default, sbt.librarymanagement.LogicalClock.unknown, None, None, false, false) + def apply(): UpdateConfiguration = new UpdateConfiguration() def apply(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration], missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, logicalClock: sbt.librarymanagement.LogicalClock, metadataDirectory: Option[java.io.File], artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter], offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(retrieveManaged, missingOk, logging, logicalClock, metadataDirectory, artifactFilter, offline, frozen) def apply(retrieveManaged: sbt.librarymanagement.RetrieveConfiguration, missingOk: Boolean, logging: sbt.librarymanagement.UpdateLogging, logicalClock: sbt.librarymanagement.LogicalClock, metadataDirectory: java.io.File, artifactFilter: sbt.librarymanagement.ArtifactTypeFilter, offline: Boolean, frozen: Boolean): UpdateConfiguration = new UpdateConfiguration(Option(retrieveManaged), missingOk, logging, logicalClock, Option(metadataDirectory), Option(artifactFilter), offline, frozen) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala index 02456951f..a0293ea63 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -60,7 +60,7 @@ final class ExternalIvyConfiguration private ( } object ExternalIvyConfiguration { - def apply(): ExternalIvyConfiguration = new ExternalIvyConfiguration(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, None, Vector()) + def apply(): ExternalIvyConfiguration = new ExternalIvyConfiguration() def apply(lock: Option[xsbti.GlobalLock], log: Option[xsbti.Logger], updateOptions: sbt.librarymanagement.ivy.UpdateOptions, baseDirectory: Option[java.io.File], uri: Option[java.net.URI], extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) def apply(lock: xsbti.GlobalLock, log: xsbti.Logger, updateOptions: sbt.librarymanagement.ivy.UpdateOptions, baseDirectory: java.io.File, uri: java.net.URI, extraResolvers: Vector[sbt.librarymanagement.Resolver]): ExternalIvyConfiguration = new ExternalIvyConfiguration(Option(lock), Option(log), updateOptions, Option(baseDirectory), Option(uri), extraResolvers) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index 0d781c437..1baa4aeb3 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -98,7 +98,7 @@ object InlineIvyConfiguration { .withResolutionCacheDir(resolutionCacheDir) .withLog(log) } - def apply(): InlineIvyConfiguration = new InlineIvyConfiguration(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, sbt.librarymanagement.Resolver.defaults, Vector.empty, Vector.empty, sbt.librarymanagement.ivy.IvyDefaults.defaultChecksums, false, None) + def apply(): InlineIvyConfiguration = new InlineIvyConfiguration() def apply(lock: Option[xsbti.GlobalLock], log: Option[xsbti.Logger], updateOptions: sbt.librarymanagement.ivy.UpdateOptions, paths: Option[sbt.librarymanagement.ivy.IvyPaths], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: Option[java.io.File]): InlineIvyConfiguration = new InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) def apply(lock: xsbti.GlobalLock, log: xsbti.Logger, updateOptions: sbt.librarymanagement.ivy.UpdateOptions, paths: sbt.librarymanagement.ivy.IvyPaths, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration], checksums: Vector[String], managedChecksums: Boolean, resolutionCacheDir: java.io.File): InlineIvyConfiguration = new InlineIvyConfiguration(Option(lock), Option(log), updateOptions, Option(paths), resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, Option(resolutionCacheDir)) } diff --git a/project/plugins.sbt b/project/plugins.sbt index 8e2abce43..d2c95eb4c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.3") scalacOptions += "-language:postfixOps" From 14cc5ea626762a82205c581de5f453e7e13c7bc7 Mon Sep 17 00:00:00 2001 From: Ryan Bair Date: Fri, 9 Mar 2018 08:43:41 -0500 Subject: [PATCH 0733/1030] Bump to latest jsch to support stronger key exchange algorithms --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 3d4a59e93..3bddd2c42 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -41,7 +41,7 @@ object Dependencies { val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-b18f59ea3bc914a297bb6f1a4f7fb0ace399e310" - val jsch = "com.jcraft" % "jsch" % "0.1.46" intransitive () + val jsch = "com.jcraft" % "jsch" % "0.1.54" val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") From 127b90ee43d0529d8ea9073ae2182dedf160c95c Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 15:51:36 +0000 Subject: [PATCH 0734/1030] Make MakePomConfiguration a Contraband type again Requires a separate file because of https://github.com/sbt/contraband/pull/118. --- .../MakePomConfiguration.scala | 73 +++++++++ .../main/contraband/librarymanagement2.json | 22 +++ .../MakePomConfiguration.scala | 142 ++---------------- 3 files changed, 106 insertions(+), 131 deletions(-) create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala create mode 100644 core/src/main/contraband/librarymanagement2.json diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala new file mode 100644 index 000000000..5570f01c6 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -0,0 +1,73 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +final class MakePomConfiguration private ( + val file: Option[java.io.File], + val moduleInfo: Option[sbt.librarymanagement.ModuleInfo], + val configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]], + val extra: Option[scala.xml.NodeSeq], + val process: scala.Function1[scala.xml.Node, scala.xml.Node], + val filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean], + val allRepositories: Boolean, + val includeTypes: Set[String]) extends Serializable { + + + + override def equals(o: Any): Boolean = o match { + case x: MakePomConfiguration => (this.file == x.file) && (this.moduleInfo == x.moduleInfo) && (this.configurations == x.configurations) && (this.extra == x.extra) && (this.process == x.process) && (this.filterRepositories == x.filterRepositories) && (this.allRepositories == x.allRepositories) && (this.includeTypes == x.includeTypes) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MakePomConfiguration".##) + file.##) + moduleInfo.##) + configurations.##) + extra.##) + process.##) + filterRepositories.##) + allRepositories.##) + includeTypes.##) + } + override def toString: String = { + "MakePomConfiguration(" + file + ", " + moduleInfo + ", " + configurations + ", " + extra + ", " + process + ", " + filterRepositories + ", " + allRepositories + ", " + includeTypes + ")" + } + protected[this] def copy(file: Option[java.io.File] = file, moduleInfo: Option[sbt.librarymanagement.ModuleInfo] = moduleInfo, configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]] = configurations, extra: Option[scala.xml.NodeSeq] = extra, process: scala.Function1[scala.xml.Node, scala.xml.Node] = process, filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean] = filterRepositories, allRepositories: Boolean = allRepositories, includeTypes: Set[String] = includeTypes): MakePomConfiguration = { + new MakePomConfiguration(file, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, includeTypes) + } + def withFile(file: Option[java.io.File]): MakePomConfiguration = { + copy(file = file) + } + def withFile(file: java.io.File): MakePomConfiguration = { + copy(file = Option(file)) + } + def withModuleInfo(moduleInfo: Option[sbt.librarymanagement.ModuleInfo]): MakePomConfiguration = { + copy(moduleInfo = moduleInfo) + } + def withModuleInfo(moduleInfo: sbt.librarymanagement.ModuleInfo): MakePomConfiguration = { + copy(moduleInfo = Option(moduleInfo)) + } + def withConfigurations(configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]]): MakePomConfiguration = { + copy(configurations = configurations) + } + def withConfigurations(configurations: scala.Vector[sbt.librarymanagement.Configuration]): MakePomConfiguration = { + copy(configurations = Option(configurations)) + } + def withExtra(extra: Option[scala.xml.NodeSeq]): MakePomConfiguration = { + copy(extra = extra) + } + def withExtra(extra: scala.xml.NodeSeq): MakePomConfiguration = { + copy(extra = Option(extra)) + } + def withProcess(process: scala.Function1[scala.xml.Node, scala.xml.Node]): MakePomConfiguration = { + copy(process = process) + } + def withFilterRepositories(filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean]): MakePomConfiguration = { + copy(filterRepositories = filterRepositories) + } + def withAllRepositories(allRepositories: Boolean): MakePomConfiguration = { + copy(allRepositories = allRepositories) + } + def withIncludeTypes(includeTypes: Set[String]): MakePomConfiguration = { + copy(includeTypes = includeTypes) + } +} +object MakePomConfiguration extends sbt.librarymanagement.MakePomConfigurationFunctions { + + def apply(file: Option[java.io.File], moduleInfo: Option[sbt.librarymanagement.ModuleInfo], configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]], extra: Option[scala.xml.NodeSeq], process: scala.Function1[scala.xml.Node, scala.xml.Node], filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean], allRepositories: Boolean, includeTypes: Set[String]): MakePomConfiguration = new MakePomConfiguration(file, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, includeTypes) + def apply(file: java.io.File, moduleInfo: sbt.librarymanagement.ModuleInfo, configurations: scala.Vector[sbt.librarymanagement.Configuration], extra: scala.xml.NodeSeq, process: scala.Function1[scala.xml.Node, scala.xml.Node], filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean], allRepositories: Boolean, includeTypes: Set[String]): MakePomConfiguration = new MakePomConfiguration(Option(file), Option(moduleInfo), Option(configurations), Option(extra), process, filterRepositories, allRepositories, includeTypes) +} diff --git a/core/src/main/contraband/librarymanagement2.json b/core/src/main/contraband/librarymanagement2.json new file mode 100644 index 000000000..2c9d3d6cf --- /dev/null +++ b/core/src/main/contraband/librarymanagement2.json @@ -0,0 +1,22 @@ +{ + "types": [ + { + "name": "MakePomConfiguration", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "generateCodec": false, + "fields": [ + { "name": "file", "type": "java.io.File?" }, + { "name": "moduleInfo", "type": "sbt.librarymanagement.ModuleInfo?" }, + { "name": "configurations", "type": "scala.Vector[sbt.librarymanagement.Configuration]?" }, + { "name": "extra", "type": "scala.xml.NodeSeq?" }, + { "name": "process", "type": "scala.Function1[scala.xml.Node, scala.xml.Node]" }, + { "name": "filterRepositories", "type": "scala.Function1[sbt.librarymanagement.MavenRepository, Boolean]" }, + { "name": "allRepositories", "type": "boolean" }, + { "name": "includeTypes", "type": "Set[String]" } + ], + "parentsCompanion": "sbt.librarymanagement.MakePomConfigurationFunctions" + } + ] +} diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala index aec1c2a07..1b5edbb9c 100644 --- a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -1,137 +1,17 @@ package sbt.librarymanagement -import java.io.File -import scala.xml.{ Node => XNode, NodeSeq } - -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ -final class MakePomConfiguration private (val file: Option[File], - val moduleInfo: Option[ModuleInfo], - val configurations: Option[Vector[Configuration]], - val extra: Option[NodeSeq], - val process: XNode => XNode, - val filterRepositories: MavenRepository => Boolean, - val allRepositories: Boolean, - val includeTypes: Set[String]) - extends Serializable { - private def this() = - this(None, - None, - None, - None, - identity, - MakePomConfiguration.constTrue, - true, - Set(Artifact.DefaultType, Artifact.PomType)) - - override def equals(o: Any): Boolean = o match { - case x: MakePomConfiguration => - (this.file == x.file) && (this.moduleInfo == x.moduleInfo) && (this.configurations == x.configurations) && (this.extra == x.extra) && (this.process == x.process) && (this.filterRepositories == x.filterRepositories) && (this.allRepositories == x.allRepositories) && (this.includeTypes == x.includeTypes) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MakePomConfiguration".##) + file.##) + moduleInfo.##) + configurations.##) + extra.##) + process.##) + filterRepositories.##) + allRepositories.##) + includeTypes.##) - } - override def toString: String = { - "MakePomConfiguration(" + file + ", " + moduleInfo + ", " + configurations + ", " + extra + ", " + process + ", " + filterRepositories + ", " + allRepositories + ", " + includeTypes + ")" - } - protected[this] def copy(file: Option[File] = file, - moduleInfo: Option[ModuleInfo] = moduleInfo, - configurations: Option[Vector[Configuration]] = configurations, - extra: Option[NodeSeq] = extra, - process: XNode => XNode = process, - filterRepositories: MavenRepository => Boolean = filterRepositories, - allRepositories: Boolean = allRepositories, - includeTypes: Set[String] = includeTypes): MakePomConfiguration = { - new MakePomConfiguration(file, - moduleInfo, - configurations, - extra, - process, - filterRepositories, - allRepositories, - includeTypes) - } - def withFile(file: Option[File]): MakePomConfiguration = { - copy(file = file) - } - def withFile(file: File): MakePomConfiguration = { - copy(file = Option(file)) - } - def withModuleInfo(moduleInfo: Option[ModuleInfo]): MakePomConfiguration = { - copy(moduleInfo = moduleInfo) - } - def withModuleInfo(moduleInfo: ModuleInfo): MakePomConfiguration = { - copy(moduleInfo = Option(moduleInfo)) - } - def withConfigurations(configurations: Option[Vector[Configuration]]): MakePomConfiguration = { - copy(configurations = configurations) - } - def withExtra(extra: Option[NodeSeq]): MakePomConfiguration = { - copy(extra = extra) - } - def withExtra(extra: NodeSeq): MakePomConfiguration = { - copy(extra = Option(extra)) - } - def withProcess(process: XNode => XNode): MakePomConfiguration = { - copy(process = process) - } - def withFilterRepositories( - filterRepositories: MavenRepository => Boolean - ): MakePomConfiguration = { - copy(filterRepositories = filterRepositories) - } - def withAllRepositories(allRepositories: Boolean): MakePomConfiguration = { - copy(allRepositories = allRepositories) - } - def withIncludeTypes(includeTypes: Set[String]): MakePomConfiguration = { - copy(includeTypes = includeTypes) - } -} - -object MakePomConfiguration { +private[librarymanagement] abstract class MakePomConfigurationFunctions { private[sbt] lazy val constTrue: MavenRepository => Boolean = _ => true def apply(): MakePomConfiguration = - new MakePomConfiguration(None, - None, - None, - None, - identity, - constTrue, - true, - Set(Artifact.DefaultType, Artifact.PomType)) - def apply(file: Option[File], - moduleInfo: Option[ModuleInfo], - configurations: Option[Vector[Configuration]], - extra: Option[NodeSeq], - process: XNode => XNode, - filterRepositories: MavenRepository => Boolean, - allRepositories: Boolean, - includeTypes: Set[String]): MakePomConfiguration = - new MakePomConfiguration(file, - moduleInfo, - configurations, - extra, - process, - filterRepositories, - allRepositories, - includeTypes) - def apply(file: File, - moduleInfo: ModuleInfo, - configurations: Vector[Configuration], - extra: NodeSeq, - process: XNode => XNode, - filterRepositories: MavenRepository => Boolean, - allRepositories: Boolean, - includeTypes: Set[String]): MakePomConfiguration = - new MakePomConfiguration(Option(file), - Option(moduleInfo), - Option(configurations), - Option(extra), - process, - filterRepositories, - allRepositories, - includeTypes) + MakePomConfiguration( + None, + None, + None, + None, + identity(_: scala.xml.Node), + constTrue, + true, + Set(Artifact.DefaultType, Artifact.PomType) + ) } From 8d49d5163c07e76dd6b38b8231f5bb53e8cf0da1 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 14:37:10 +0000 Subject: [PATCH 0735/1030] Cleanup Configuration --- .../sbt/librarymanagement/Configuration.scala | 73 +++++++++---------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index 2306efdda..63dffb42f 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -7,20 +7,17 @@ final class Configuration private[sbt] ( val name: String, val description: String, val isPublic: Boolean, - val extendsConfigs: Vector[sbt.librarymanagement.Configuration], - val transitive: Boolean) - extends sbt.librarymanagement.ConfigurationExtra + val extendsConfigs: Vector[Configuration], + val transitive: Boolean +) extends ConfigurationExtra with Serializable { require(name != null, "name cannot be null") - require(name.size > 0, "name cannot be empty") + require(name.nonEmpty, "name cannot be empty") require(id != null, "id cannot be null") - require(id.size > 0, "id cannot be empty") + require(id.nonEmpty, "id cannot be empty") require(id.head.isUpper, s"id must be capitalized: $id") - private def this(id: String, name: String) = - this(id, name, "", true, Vector.empty, true) - override def equals(o: Any): Boolean = o match { case x: Configuration => (this.id == x.id) && @@ -31,50 +28,48 @@ final class Configuration private[sbt] ( (this.transitive == x.transitive) case _ => false } - override val hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + id.##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) - } - override def toString: String = { - name - } - protected[this] def copy(id: String = id, - name: String = name, - description: String = description, - isPublic: Boolean = isPublic, - extendsConfigs: Vector[sbt.librarymanagement.Configuration] = - extendsConfigs, - transitive: Boolean = transitive): Configuration = { + + override val hashCode: Int = + 37 * (37 * (37 * (37 * (37 * (37 * (17 + + id.##) + name.##) + description.##) + isPublic.##) + extendsConfigs.##) + transitive.##) + + override def toString: String = name + + protected[this] def copy( + id: String = id, + name: String = name, + description: String = description, + isPublic: Boolean = isPublic, + extendsConfigs: Vector[Configuration] = extendsConfigs, + transitive: Boolean = transitive + ): Configuration = new Configuration(id, name, description, isPublic, extendsConfigs, transitive) - } - def withDescription(description: String): Configuration = { - copy(description = description) - } + def withDescription(description: String): Configuration = copy(description = description) - def withIsPublic(isPublic: Boolean): Configuration = { - copy(isPublic = isPublic) - } + def withIsPublic(isPublic: Boolean): Configuration = copy(isPublic = isPublic) - def withExtendsConfigs( - extendsConfigs: Vector[sbt.librarymanagement.Configuration]): Configuration = { + def withExtendsConfigs(extendsConfigs: Vector[Configuration]): Configuration = copy(extendsConfigs = extendsConfigs) - } - def withTransitive(transitive: Boolean): Configuration = { + def withTransitive(transitive: Boolean): Configuration = copy(transitive = transitive) - } def toConfigRef: ConfigRef = ConfigRef(name) } + object Configuration { // Don't call this directly. It's intended to be used from config macro. def of(id: String, name: String): Configuration = new Configuration(id, name, "", true, Vector.empty, true) - def of(id: String, - name: String, - description: String, - isPublic: Boolean, - extendsConfigs: Vector[sbt.librarymanagement.Configuration], - transitive: Boolean): Configuration = + + def of( + id: String, + name: String, + description: String, + isPublic: Boolean, + extendsConfigs: Vector[Configuration], + transitive: Boolean + ): Configuration = new Configuration(id, name, description, isPublic, extendsConfigs, transitive) } From de360bb1390426127f8eb67bdc0faffc1a8ede64 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 14:50:17 +0000 Subject: [PATCH 0736/1030] Add notes as to why Configuration isn't managed by Contraband --- .../sbt/librarymanagement/Configuration.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index 63dffb42f..60c1cd91b 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -73,3 +73,19 @@ object Configuration { ): Configuration = new Configuration(id, name, description, isPublic, extendsConfigs, transitive) } + +/* +Configuration isn't defined with Contraband. + +The reasons that block it from being made a Contraband type (AFAIK): + * its hashCode is a val, not a def + * it doesn't have companion apply methods, but "of" instead + +Other reasons that I don't think are blocking: + * it's constructor is private[sbt] (doesn't matter, Configuration.of is public) + +Reasons that are definitely not blocking: + * it has a custom toString, supported by Contraband + * it has init requirements, supported by Contraband via parent class + * it has other methods, supported by Contraband via parent class + */ From 95544d51752ae1fdc212c43031e7a1cc76e192a3 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 14:39:20 +0000 Subject: [PATCH 0737/1030] Make Configuration's copy private[this] .. now that it doesn't need to share it with a parent type. --- build.sbt | 4 ++++ core/src/main/scala/sbt/librarymanagement/Configuration.scala | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 84c718b8b..b98b96de4 100644 --- a/build.sbt +++ b/build.sbt @@ -110,6 +110,10 @@ lazy val lmCore = (project in file("core")) exclude[MissingClassProblem]("sbt.internal.librarymanagement.InlineConfigurationFunctions"), // dropped internal class parent (InlineConfigurationFunctions) exclude[MissingTypesProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration$"), + + // Configuration's copy method was never meant to be public + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy$default$*"), ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index 60c1cd91b..e82d7513e 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -35,7 +35,7 @@ final class Configuration private[sbt] ( override def toString: String = name - protected[this] def copy( + private[this] def copy( id: String = id, name: String = name, description: String = description, From 76d1f73333f0f6d67a331bd4fccb36b4529cede0 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 8 Mar 2018 15:30:50 +0000 Subject: [PATCH 0738/1030] Replace abstract protected[this] copy with abstract withX methods --- build.sbt | 26 ++++++++++++ .../sbt/librarymanagement/ArtifactExtra.scala | 20 +-------- .../scala/sbt/librarymanagement/Extra.scala | 8 +--- .../sbt/librarymanagement/ModuleIDExtra.scala | 41 ++++++++----------- .../librarymanagement/UpdateReportExtra.scala | 25 ++--------- 5 files changed, 50 insertions(+), 70 deletions(-) diff --git a/build.sbt b/build.sbt index b98b96de4..7f98affae 100644 --- a/build.sbt +++ b/build.sbt @@ -114,6 +114,32 @@ lazy val lmCore = (project in file("core")) // Configuration's copy method was never meant to be public exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy$default$*"), + + // the data type copy methods were never meant to be public + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy$default$*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy$default$*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy$default$*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy$default$*"), + + // these abstract classes are private[librarymanagement] so it's fine if they have more methods + exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.*"), + exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.*"), + exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.*"), + exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.*"), + + // these abstract classes are private[librarymanagement] so they can lose these abstract methods + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.type"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.url"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.checksum"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.name"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.configurations"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.classifier"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 44db18be9..f90b9e29b 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -7,28 +7,12 @@ import java.io.File import java.net.URL private[librarymanagement] abstract class ArtifactExtra { - def name: String - def `type`: String - def extension: String - def classifier: Option[String] - def configurations: Vector[ConfigRef] - def url: Option[URL] def extraAttributes: Map[String, String] - def checksum: Option[Checksum] - protected[this] def copy( - name: String = name, - `type`: String = `type`, - extension: String = extension, - classifier: Option[String] = classifier, - configurations: Vector[ConfigRef] = configurations, - url: Option[URL] = url, - extraAttributes: Map[String, String] = extraAttributes, - checksum: Option[Checksum] = checksum - ): Artifact + def withExtraAttributes(extraAttributes: Map[String, String]): Artifact def extra(attributes: (String, String)*) = - copy(extraAttributes = extraAttributes ++ ModuleID.checkE(attributes)) + withExtraAttributes(extraAttributes ++ ModuleID.checkE(attributes)) } import Configurations.{ Optional, Pom, Test } diff --git a/core/src/main/scala/sbt/librarymanagement/Extra.scala b/core/src/main/scala/sbt/librarymanagement/Extra.scala index 3d0feb29c..421a40505 100644 --- a/core/src/main/scala/sbt/librarymanagement/Extra.scala +++ b/core/src/main/scala/sbt/librarymanagement/Extra.scala @@ -30,15 +30,11 @@ private[librarymanagement] abstract class InclExclRuleFunctions { } private[librarymanagement] abstract class ArtifactTypeFilterExtra { - def types: Set[String] def inverted: Boolean - protected[this] def copy( - types: Set[String] = types, - inverted: Boolean = inverted - ): ArtifactTypeFilter + def withInverted(inverted: Boolean): ArtifactTypeFilter - def invert = copy(inverted = !inverted) + def invert = withInverted(!inverted) } private[librarymanagement] abstract class ArtifactTypeFilterFunctions { diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 60b818a30..f15c5acb3 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -24,21 +24,14 @@ private[librarymanagement] abstract class ModuleIDExtra { def crossVersion: CrossVersion def branchName: Option[String] - protected[this] def copy( - organization: String = organization, - name: String = name, - revision: String = revision, - configurations: Option[String] = configurations, - isChanging: Boolean = isChanging, - isTransitive: Boolean = isTransitive, - isForce: Boolean = isForce, - explicitArtifacts: Vector[Artifact] = explicitArtifacts, - inclusions: Vector[InclusionRule] = inclusions, - exclusions: Vector[ExclusionRule] = exclusions, - extraAttributes: Map[String, String] = extraAttributes, - crossVersion: CrossVersion = crossVersion, - branchName: Option[String] = branchName - ): ModuleID + def withIsChanging(isChanging: Boolean): ModuleID + def withIsTransitive(isTransitive: Boolean): ModuleID + def withIsForce(isForce: Boolean): ModuleID + def withExplicitArtifacts(explicitArtifacts: Vector[Artifact]): ModuleID + def withExclusions(exclusions: Vector[InclExclRule]): ModuleID + def withExtraAttributes(extraAttributes: Map[String, String]): ModuleID + def withCrossVersion(crossVersion: CrossVersion): ModuleID + def withBranchName(branchName: Option[String]): ModuleID protected def toStringImpl: String = s"""$organization:$name:$revision""" + @@ -78,14 +71,14 @@ private[librarymanagement] abstract class ModuleIDExtra { def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled()) /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ - def cross(v: CrossVersion): ModuleID = copy(crossVersion = v) + def cross(v: CrossVersion): ModuleID = withCrossVersion(v) // () required for chaining /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ def notTransitive() = intransitive() /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ - def intransitive() = copy(isTransitive = false) + def intransitive() = withIsTransitive(false) /** * Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, @@ -93,13 +86,13 @@ private[librarymanagement] abstract class ModuleIDExtra { * * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. */ - def changing() = copy(isChanging = true) + def changing() = withIsChanging(true) /** * Indicates that conflict resolution should only select this module's revision. * This prevents a newer revision from being pulled in by a transitive dependency, for example. */ - def force() = copy(isForce = true) + def force() = withIsForce(true) /** * Specifies a URL from which the main artifact for this dependency can be downloaded. @@ -116,13 +109,13 @@ private[librarymanagement] abstract class ModuleIDExtra { * these artifact definitions override the information in the dependency's published metadata. */ def artifacts(newArtifacts: Artifact*) = - copy(explicitArtifacts = newArtifacts.toVector ++ explicitArtifacts) + withExplicitArtifacts(newArtifacts.toVector ++ explicitArtifacts) /** * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify * both the exact organization and name and nothing else will be included in a pom.xml. */ - def excludeAll(rules: ExclusionRule*) = copy(exclusions = this.exclusions ++ rules) + def excludeAll(rules: ExclusionRule*) = withExclusions(exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ def exclude(org: String, name: String) = @@ -133,7 +126,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * This information will only be published in an ivy.xml and not in a pom.xml. */ def extra(attributes: (String, String)*) = - copy(extraAttributes = this.extraAttributes ++ ModuleID.checkE(attributes)) + withExtraAttributes(extraAttributes ++ ModuleID.checkE(attributes)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred @@ -176,9 +169,9 @@ private[librarymanagement] abstract class ModuleIDExtra { /** * Sets the Ivy branch of this module. */ - def branch(branchName: String) = copy(branchName = Some(branchName)) + def branch(branchName: String) = withBranchName(Some(branchName)) - def branch(branchName: Option[String]) = copy(branchName = branchName) + def branch(branchName: Option[String]) = withBranchName(branchName) } private[librarymanagement] abstract class ModuleIDFunctions { diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index cf146287b..9a498c024 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -54,6 +54,8 @@ private[librarymanagement] abstract class ModuleReportExtra { def licenses: Vector[(String, Option[String])] def callers: Vector[Caller] + def withArtifacts(artifacts: Vector[(Artifact, File)]): ModuleReport + protected[this] def arts: Vector[String] = artifacts.map(_.toString) ++ missingArtifacts.map(art => "(MISSING) " + art) @@ -102,28 +104,7 @@ private[librarymanagement] abstract class ModuleReportExtra { } def retrieve(f: (ModuleID, Artifact, File) => File): ModuleReport = - copy(artifacts = artifacts.map { case (art, file) => (art, f(module, art, file)) }) - - protected[this] def copy( - module: ModuleID = module, - artifacts: Vector[(Artifact, File)] = artifacts, - missingArtifacts: Vector[Artifact] = missingArtifacts, - status: Option[String] = status, - publicationDate: Option[ju.Calendar] = publicationDate, - resolver: Option[String] = resolver, - artifactResolver: Option[String] = artifactResolver, - evicted: Boolean = evicted, - evictedData: Option[String] = evictedData, - evictedReason: Option[String] = evictedReason, - problem: Option[String] = problem, - homepage: Option[String] = homepage, - extraAttributes: Map[String, String] = extraAttributes, - isDefault: Option[Boolean] = isDefault, - branch: Option[String] = branch, - configurations: Vector[ConfigRef] = configurations, - licenses: Vector[(String, Option[String])] = licenses, - callers: Vector[Caller] = callers - ): ModuleReport + withArtifacts(artifacts.map { case (art, file) => (art, f(module, art, file)) }) } private[librarymanagement] abstract class UpdateReportExtra { From 140eed1a1804a6156223d2c9badd44c0eb785f8b Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 14 Mar 2018 16:59:09 +0000 Subject: [PATCH 0739/1030] Silence noisy compile warnings in all REPLs --- build.sbt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 40a6424b8..e1170f161 100644 --- a/build.sbt +++ b/build.sbt @@ -1,7 +1,7 @@ import Dependencies._ import Path._ -def commonSettings: Seq[Setting[_]] = Seq( +def commonSettings: Seq[Setting[_]] = Def settings ( scalaVersion := scala212, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), @@ -21,6 +21,7 @@ def commonSettings: Seq[Setting[_]] = Seq( case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } }, + inCompileAndTest(scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint")), publishArtifact in Compile := true, publishArtifact in Test := false, parallelExecution in Test := false @@ -114,8 +115,6 @@ lazy val lmCommonTest = (project in file("common-test")) skip in publish := true, name := "common-test", libraryDependencies ++= Seq(scalaTest, scalaCheck), - scalacOptions in (Compile, console) --= - Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, ) @@ -171,3 +170,6 @@ inThisBuild(Seq( whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present whitesourceForceCheckAllDependencies := true, )) + +def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] = + Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*))) From e55362e4c260f93d7387fc240752b926e05bb19c Mon Sep 17 00:00:00 2001 From: Antonio Cunei Date: Thu, 15 Mar 2018 02:26:55 +0100 Subject: [PATCH 0740/1030] Renaming MakePomConfiguration.scala The regular file has a name collision with the contraband-generated name. Fixes #219. --- ...kePomConfiguration.scala => MakePomConfigurationFormats.scala} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/src/main/scala/sbt/librarymanagement/{MakePomConfiguration.scala => MakePomConfigurationFormats.scala} (100%) diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfigurationFormats.scala similarity index 100% rename from core/src/main/scala/sbt/librarymanagement/MakePomConfiguration.scala rename to core/src/main/scala/sbt/librarymanagement/MakePomConfigurationFormats.scala From a1999a9b90ec9c278db29e60e62bab24901bd122 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 00:24:46 +0000 Subject: [PATCH 0741/1030] Cleanup VersionNumberSpec --- .../librarymanagement/VersionNumberSpec.scala | 283 ++++++++++-------- 1 file changed, 159 insertions(+), 124 deletions(-) diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index b7fcdaa4c..1b6b2cb3d 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -1,128 +1,151 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.UnitSpec +import org.scalatest.Inside -// This is a specification to check the version number parsing. -class VersionNumberSpec extends UnitSpec { - "1" should "be parsed" in beParsedAs("1", Seq(1), Seq(), Seq()) - it should "breakdown" in breakDownTo("1", Some(1)) - it should "cascade" in generateCorrectCascadingNumbers("1", Seq("1")) +// This is a specification to check VersionNumber and VersionNumberCompatibility. +class VersionNumberSpec extends UnitSpec with Inside { + import VersionNumber.{ SemVer, SecondSegment } - "1.0" should "be parsed" in beParsedAs("1.0", Seq(1, 0), Seq(), Seq()) - it should "breakdown" in breakDownTo("1.0", Some(1), Some(0)) - it should "cascade" in generateCorrectCascadingNumbers("1.0", Seq("1.0")) - - "1.0.0" should "be parsed" in beParsedAs("1.0.0", Seq(1, 0, 0), Seq(), Seq()) - it should "breakdown" in breakDownTo("1.0.0", Some(1), Some(0), Some(0)) - it should "cascade" in generateCorrectCascadingNumbers("1.0.0", Seq("1.0.0", "1.0")) - it should "be SemVer compat with 1.0.1" in beSemVerCompatWith("1.0.0", "1.0.1") - it should "be SemVer compat with 1.1.1" in beSemVerCompatWith("1.0.0", "1.1.1") - it should "not be SemVer compat with 2.0.0" in notBeSemVerCompatWith("1.0.0", "2.0.0") - it should "not be SemVer compat with 1.0.0-M1" in notBeSemVerCompatWith("1.0.0", "1.0.0-M1") - it should "be SecSeg compat with 1.0.1" in beSecSegCompatWith("1.0.0", "1.0.1") - it should "not be SecSeg compat with 1.1.1" in notBeSecSegCompatWith("1.0.0", "1.1.1") - it should "not be SecSeg compat with 2.0.0" in notBeSecSegCompatWith("1.0.0", "2.0.0") - it should "not be SecSeg compat with 1.0.0-M1" in notBeSecSegCompatWith("1.0.0", "1.0.0-M1") - - "1.0.0.0" should "be parsed" in beParsedAs("1.0.0.0", Seq(1, 0, 0, 0), Seq(), Seq()) - it should "breakdown" in breakDownTo("1.0.0.0", Some(1), Some(0), Some(0), Some(0)) - it should "cascade" in generateCorrectCascadingNumbers("1.0.0.0", Seq("1.0.0.0", "1.0.0", "1.0")) - - "0.12.0" should "be parsed" in beParsedAs("0.12.0", Seq(0, 12, 0), Seq(), Seq()) - it should "breakdown" in breakDownTo("0.12.0", Some(0), Some(12), Some(0)) - it should "cascade" in generateCorrectCascadingNumbers("0.12.0", Seq("0.12.0", "0.12")) - it should "not be SemVer compat with 0.12.0-RC1" in notBeSemVerCompatWith("0.12.0", "0.12.0-RC1") - it should "not be SemVer compat with 0.12.1" in notBeSemVerCompatWith("0.12.0", "0.12.1") - it should "not be SemVer compat with 0.12.1-M1" in notBeSemVerCompatWith("0.12.0", "0.12.1-M1") - it should "not be SecSeg compat with 0.12.0-RC1" in notBeSecSegCompatWith("0.12.0", "0.12.0-RC1") - it should "be SecSeg compat with 0.12.1" in beSecSegCompatWith("0.12.0", "0.12.1") - it should "be SecSeg compat with 0.12.1-M1" in beSecSegCompatWith("0.12.0", "0.12.1-M1") - - "0.1.0-SNAPSHOT" should "be parsed" in beParsedAs("0.1.0-SNAPSHOT", - Seq(0, 1, 0), - Seq("SNAPSHOT"), - Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-SNAPSHOT", - Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) - it should "be SemVer compat with 0.1.0-SNAPSHOT" in beSemVerCompatWith("0.1.0-SNAPSHOT", - "0.1.0-SNAPSHOT") - it should "not be SemVer compat with 0.1.0" in notBeSemVerCompatWith("0.1.0-SNAPSHOT", "0.1.0") - it should "be SemVer compat with 0.1.0-SNAPSHOT+001" in beSemVerCompatWith("0.1.0-SNAPSHOT", - "0.1.0-SNAPSHOT+001") - it should "be SecSeg compat with 0.1.0-SNAPSHOT" in beSecSegCompatWith("0.1.0-SNAPSHOT", - "0.1.0-SNAPSHOT") - it should "be not SecSeg compat with 0.1.0" in notBeSecSegCompatWith("0.1.0-SNAPSHOT", "0.1.0") - it should "be SecSeg compat with 0.1.0-SNAPSHOT+001" in beSecSegCompatWith("0.1.0-SNAPSHOT", - "0.1.0-SNAPSHOT+001") - - "0.1.0-M1" should "be parsed" in beParsedAs("0.1.0-M1", Seq(0, 1, 0), Seq("M1"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-M1", - Seq("0.1.0-M1", "0.1.0", "0.1")) - - "0.1.0-RC1" should "be parsed" in beParsedAs("0.1.0-RC1", Seq(0, 1, 0), Seq("RC1"), Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-RC1", - Seq("0.1.0-RC1", "0.1.0", "0.1")) - - "0.1.0-MSERVER-1" should "be parsed" in beParsedAs("0.1.0-MSERVER-1", - Seq(0, 1, 0), - Seq("MSERVER", "1"), - Seq()) - it should "cascade" in generateCorrectCascadingNumbers("0.1.0-MSERVER-1", - Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) - - "2.10.4-20140115-000117-b3a-sources" should "be parsed" in { - beParsedAs("2.10.4-20140115-000117-b3a-sources", - Seq(2, 10, 4), - Seq("20140115", "000117", "b3a", "sources"), - Seq()) + version("1") { implicit v => + parsesTo(Seq(1), Seq(), Seq()) + breaksDownTo(Some(1)) + cascadesTo(Seq("1")) } - it should "cascade" in generateCorrectCascadingNumbers( - "2.10.4-20140115-000117-b3a-sources", - Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) - it should "be SemVer compat with 2.0.0" in beSemVerCompatWith( - "2.10.4-20140115-000117-b3a-sources", - "2.0.0") - it should "be not SecSeg compat with 2.0.0" in notBeSecSegCompatWith( - "2.10.4-20140115-000117-b3a-sources", - "2.0.0") - "20140115000117-b3a-sources" should "be parsed" in { - beParsedAs("20140115000117-b3a-sources", Seq(20140115000117L), Seq("b3a", "sources"), Seq()) + version("1.0") { implicit v => + parsesTo(Seq(1, 0), Seq(), Seq()) + breaksDownTo(Some(1), Some(0)) + cascadesTo(Seq("1.0")) } - it should "cascade" in generateCorrectCascadingNumbers("20140115000117-b3a-sources", - Seq("20140115000117-b3a-sources")) - "1.0.0-alpha+001+002" should "be parsed" in { - beParsedAs("1.0.0-alpha+001+002", Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) + version("1.0.0") { implicit v => + parsesTo(Seq(1, 0, 0), Seq(), Seq()) + breaksDownTo(Some(1), Some(0), Some(0)) + cascadesTo(Seq("1.0.0", "1.0")) + + isCompatibleWith("1.0.1", SemVer) + isCompatibleWith("1.1.1", SemVer) + isNotCompatibleWith("2.0.0", SemVer) + isNotCompatibleWith("1.0.0-M1", SemVer) + + isCompatibleWith("1.0.1", SecondSegment) + isNotCompatibleWith("1.1.1", SecondSegment) + isNotCompatibleWith("2.0.0", SecondSegment) + isNotCompatibleWith("1.0.0-M1", SecondSegment) } - it should "cascade" in generateCorrectCascadingNumbers( - "1.0.0-alpha+001+002", - Seq("1.0.0-alpha+001+002", "1.0.0", "1.0") - ) - "non.space.!?string" should "be parsed" in { - beParsedAs("non.space.!?string", Seq(), Seq(), Seq("non.space.!?string")) + version("1.0.0.0") { implicit v => + parsesTo(Seq(1, 0, 0, 0), Seq(), Seq()) + breaksDownTo(Some(1), Some(0), Some(0), Some(0)) + cascadesTo(Seq("1.0.0.0", "1.0.0", "1.0")) } - it should "cascade" in generateCorrectCascadingNumbers("non.space.!?string", - Seq("non.space.!?string")) - "space !?string" should "be parsed as an error" in beParsedAsError("space !?string") - "blank string" should "be parsed as an error" in beParsedAsError("") + version("0.12.0") { implicit v => + parsesTo(Seq(0, 12, 0), Seq(), Seq()) + breaksDownTo(Some(0), Some(12), Some(0)) + cascadesTo(Seq("0.12.0", "0.12")) - def beParsedAs(s: String, ns: Seq[Long], ts: Seq[String], es: Seq[String]) = - s match { - case VersionNumber(ns1, ts1, es1) if (ns1 == ns && ts1 == ts && es1 == es) => - (VersionNumber(ns, ts, es).toString shouldBe s) - (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) + isNotCompatibleWith("0.12.0-RC1", SemVer) + isNotCompatibleWith("0.12.1", SemVer) + isNotCompatibleWith("0.12.1-M1", SemVer) + + isNotCompatibleWith("0.12.0-RC1", SecondSegment) + isCompatibleWith("0.12.1", SecondSegment) + isCompatibleWith("0.12.1-M1", SecondSegment) + } + + version("0.1.0-SNAPSHOT") { implicit v => + parsesTo(Seq(0, 1, 0), Seq("SNAPSHOT"), Seq()) + cascadesTo(Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) + + isCompatibleWith("0.1.0-SNAPSHOT", SemVer) + isNotCompatibleWith("0.1.0", SemVer) + isCompatibleWith("0.1.0-SNAPSHOT+001", SemVer) + + isCompatibleWith("0.1.0-SNAPSHOT", SecondSegment) + isNotCompatibleWith("0.1.0", SecondSegment) + isCompatibleWith("0.1.0-SNAPSHOT+001", SecondSegment) + } + + version("0.1.0-M1") { implicit v => + parsesTo(Seq(0, 1, 0), Seq("M1"), Seq()) + cascadesTo(Seq("0.1.0-M1", "0.1.0", "0.1")) + } + + version("0.1.0-RC1") { implicit v => + parsesTo(Seq(0, 1, 0), Seq("RC1"), Seq()) + cascadesTo(Seq("0.1.0-RC1", "0.1.0", "0.1")) + } + + version("0.1.0-MSERVER-1") { implicit v => + parsesTo(Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) + cascadesTo(Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) + } + + version("2.10.4-20140115-000117-b3a-sources") { implicit v => + parsesTo(Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) + cascadesTo(Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) + isCompatibleWith("2.0.0", SemVer) + isNotCompatibleWith("2.0.0", SecondSegment) + } + + version("20140115000117-b3a-sources") { implicit v => + parsesTo(Seq(20140115000117L), Seq("b3a", "sources"), Seq()) + cascadesTo(Seq("20140115000117-b3a-sources")) + } + + version("1.0.0-alpha+001+002") { implicit v => + parsesTo(Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) + cascadesTo(Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) + } + + version("non.space.!?string") { implicit v => + parsesTo(Seq(), Seq(), Seq("non.space.!?string")) + cascadesTo(Seq("non.space.!?string")) + } + + version("space !?string") { implicit v => + parsesToError + } + version("") { implicit v => + parsesToError + } + + //// + + // to be used as an implicit + final class VersionString(val value: String) + + private[this] def version[A](s: String)(f: VersionString => A) = { + behavior of s"""Version "$s"""" + f(new VersionString(s)) + } + + def parsesTo(ns: Seq[Long], ts: Seq[String], es: Seq[String])(implicit v: VersionString): Unit = + it should s"parse to ($ns, $ts, $es)" in inside(v.value) { case VersionNumber(ns1, ts1, es1) => - sys.error(s"$ns1, $ts1, $es1") + (ns1 shouldBe ns) + (ts1 shouldBe ts) + (es1 shouldBe es) + (VersionNumber(ns, ts, es).toString shouldBe v.value) + (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) } - def breakDownTo(s: String, - major: Option[Long], - minor: Option[Long] = None, - patch: Option[Long] = None, - buildNumber: Option[Long] = None) = - s match { + + private[this] def parsesToError(implicit v: VersionString): Unit = + it should "parse as an error" in { + v.value should not matchPattern { + case s: String if VersionNumber.unapply(s).isDefined => // because of unapply overloading + } + } + + private[this] def breaksDownTo( + major: Option[Long], + minor: Option[Long] = None, + patch: Option[Long] = None, + buildNumber: Option[Long] = None + )(implicit v: VersionString): Unit = + it should s"breakdown to ($major, $minor, $patch, $buildNumber)" in inside(v.value) { case VersionNumber(ns, ts, es) => val v = VersionNumber(ns, ts, es) (v._1 shouldBe major) @@ -130,21 +153,33 @@ class VersionNumberSpec extends UnitSpec { (v._3 shouldBe patch) (v._4 shouldBe buildNumber) } - def beParsedAsError(s: String): Unit = - s match { - case VersionNumber(_, _, _) => sys.error(s) - case _ => () + + private[this] def cascadesTo(ns: Seq[String])(implicit v: VersionString) = { + it should s"cascade to $ns" in { + val versionNumbers = ns.toVector map VersionNumber.apply + VersionNumber(v.value).cascadingVersions shouldBe versionNumbers + } + } + + def isCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) = + checkCompat(true, vnc, v2) + + def isNotCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) = + checkCompat(false, vnc, v2) + + private[this] def checkCompat( + expectOutcome: Boolean, + vnc: VersionNumberCompatibility, + v2: String + )(implicit v1: VersionString) = { + val prefix = if (expectOutcome) "" else "NOT " + val compatibilityStrategy = vnc match { + case SemVer => "SemVer" + case SecondSegment => "SecondSegment" + case _ => val s = vnc.name; if (s contains " ") s""""$s"""" else s + } + it should s"${prefix}be $compatibilityStrategy compatible with $v2" in { + vnc.isCompatible(VersionNumber(v1.value), VersionNumber(v2)) shouldBe expectOutcome } - def beSemVerCompatWith(v1: String, v2: String) = - VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true - def notBeSemVerCompatWith(v1: String, v2: String) = - VersionNumber.SemVer.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false - def beSecSegCompatWith(v1: String, v2: String) = - VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe true - def notBeSecSegCompatWith(v1: String, v2: String) = - VersionNumber.SecondSegment.isCompatible(VersionNumber(v1), VersionNumber(v2)) shouldBe false - def generateCorrectCascadingNumbers(s: String, ns: Seq[String]) = { - val versionNumbers = ns.toVector map VersionNumber.apply - VersionNumber(s).cascadingVersions shouldBe versionNumbers } } From 3ed30990175d22f27e14b79fb6e223d7bf21f216 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 12:31:53 +0000 Subject: [PATCH 0742/1030] Sync Scala versions between Travis CI & sbt --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 86e2057cf..8473b2f47 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,12 @@ language: scala jdk: oraclejdk8 scala: - - 2.11.11 - - 2.12.3 + - 2.11.12 + - 2.12.4 matrix: include: - - scala: 2.12.3 + - scala: 2.12.4 jdk: oraclejdk9 script: From e6cffafdba0f51cd560ee4d4a4d606fcaf24c67e Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 12:32:25 +0000 Subject: [PATCH 0743/1030] Wrap Travis CI build script --- .travis.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8473b2f47..d8d69b963 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,8 +10,11 @@ matrix: - scala: 2.12.4 jdk: oraclejdk9 -script: - - sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ";++$TRAVIS_SCALA_VERSION;mimaReportBinaryIssues;scalafmt::test;test:scalafmt::test;sbt:scalafmt::test;test" +script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M + ++$TRAVIS_SCALA_VERSION + mimaReportBinaryIssues + scalafmt::test test:scalafmt::test sbt:scalafmt::test + test cache: directories: @@ -19,5 +22,5 @@ cache: - $HOME/.sbt before_cache: - - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete - - find $HOME/.sbt -name "*.lock" -print -delete + - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete + - find $HOME/.sbt -name "*.lock" -delete From 862b0a773d27d713c2887939034e81c7f90c3f57 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 12:33:32 +0000 Subject: [PATCH 0744/1030] CI enforce publish artifacts package without failure --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index d8d69b963..5ba76f975 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M mimaReportBinaryIssues scalafmt::test test:scalafmt::test sbt:scalafmt::test test + packagedArtifacts # ensure that all artifacts for publish package without failure cache: directories: From dee7390117250fc0a81e65dae74d5e09cb87bea5 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 14:57:50 +0000 Subject: [PATCH 0745/1030] Rename to MakePomConfigurationExtra.scala to match See for example CrossVersionExtra.scala --- ...ConfigurationFormats.scala => MakePomConfigurationExtra.scala} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename core/src/main/scala/sbt/librarymanagement/{MakePomConfigurationFormats.scala => MakePomConfigurationExtra.scala} (100%) diff --git a/core/src/main/scala/sbt/librarymanagement/MakePomConfigurationFormats.scala b/core/src/main/scala/sbt/librarymanagement/MakePomConfigurationExtra.scala similarity index 100% rename from core/src/main/scala/sbt/librarymanagement/MakePomConfigurationFormats.scala rename to core/src/main/scala/sbt/librarymanagement/MakePomConfigurationExtra.scala From 7770fa64e9bb3b0ebcedcea7ca9c879c9506c95a Mon Sep 17 00:00:00 2001 From: IanGabes Date: Tue, 9 Jan 2018 17:29:57 -0500 Subject: [PATCH 0746/1030] Adds null check for 'sbt.managedChecksums' in ivySettings file Fixes #195 --- .../internal/librarymanagement/IvyActions.scala | 17 ++++++++++++----- .../ivyint/GigahorseUrlHandler.scala | 3 ++- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index e62d7b0ca..01d23d987 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -4,27 +4,30 @@ package sbt.internal.librarymanagement import java.io.File -import ivyint.CachedResolutionResolveEngine +import ivyint.CachedResolutionResolveEngine import org.apache.ivy.Ivy import org.apache.ivy.core.{ IvyPatternHelper, LogOptions } import org.apache.ivy.core.deliver.DeliverOptions import org.apache.ivy.core.install.InstallOptions import org.apache.ivy.core.module.descriptor.{ - Artifact => IArtifact, + DefaultModuleDescriptor, MDArtifact, ModuleDescriptor, - DefaultModuleDescriptor + Artifact => IArtifact } import org.apache.ivy.core.resolve.ResolveOptions import org.apache.ivy.plugins.resolver.{ BasicResolver, DependencyResolver } import org.apache.ivy.util.filter.{ Filter => IvyFilter } import sbt.io.{ IO, PathFinder } import sbt.util.Logger -import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ }, syntax._ +import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } +import syntax._ import InternalDefaults._ import UpdateClassifiersUtil._ +import scala.util.Try + object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ @@ -382,7 +385,11 @@ object IvyActions { report: UpdateReport, config: RetrieveConfiguration ): UpdateReport = { - val copyChecksums = ivy.getVariable(ConvertResolver.ManagedChecksums).toBoolean + val copyChecksums = + Option(ivy.getVariable(ConvertResolver.ManagedChecksums)) match { + case Some(x) => x.toBoolean + case _ => false + } val toRetrieve: Option[Vector[ConfigRef]] = config.configurationsToRetrieve val base = getRetrieveDirectory(config.retrieveDirectory) val pattern = getRetrievePattern(config.outputPattern) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index e83f55177..b7e754dda 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -51,7 +51,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { if (checkStatusCode(url, response)) { val bodyCharset = - BasicURLHandler.getCharSetFromContentType(Option(response.body().contentType()).map(_.toString).orNull) + BasicURLHandler.getCharSetFromContentType( + Option(response.body().contentType()).map(_.toString).orNull) Some( new SbtUrlInfo(true, response.body().contentLength(), From f1598463761d415bc80a3a42c18aad5daea277a9 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 19 Mar 2018 14:58:08 +0000 Subject: [PATCH 0747/1030] In VersionNumberSpec pass VersionString explicitly --- .../librarymanagement/VersionNumberSpec.scala | 141 +++++++++--------- 1 file changed, 70 insertions(+), 71 deletions(-) diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 1b6b2cb3d..ecf3e00a4 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -7,114 +7,113 @@ import org.scalatest.Inside class VersionNumberSpec extends UnitSpec with Inside { import VersionNumber.{ SemVer, SecondSegment } - version("1") { implicit v => - parsesTo(Seq(1), Seq(), Seq()) - breaksDownTo(Some(1)) - cascadesTo(Seq("1")) + version("1") { v => + parsesTo(Seq(1), Seq(), Seq())(v) + breaksDownTo(Some(1))(v) + cascadesTo(Seq("1"))(v) } - version("1.0") { implicit v => - parsesTo(Seq(1, 0), Seq(), Seq()) - breaksDownTo(Some(1), Some(0)) - cascadesTo(Seq("1.0")) + version("1.0") { v => + parsesTo(Seq(1, 0), Seq(), Seq())(v) + breaksDownTo(Some(1), Some(0))(v) + cascadesTo(Seq("1.0"))(v) } - version("1.0.0") { implicit v => - parsesTo(Seq(1, 0, 0), Seq(), Seq()) - breaksDownTo(Some(1), Some(0), Some(0)) - cascadesTo(Seq("1.0.0", "1.0")) + version("1.0.0") { v => + parsesTo(Seq(1, 0, 0), Seq(), Seq())(v) + breaksDownTo(Some(1), Some(0), Some(0))(v) + cascadesTo(Seq("1.0.0", "1.0"))(v) - isCompatibleWith("1.0.1", SemVer) - isCompatibleWith("1.1.1", SemVer) - isNotCompatibleWith("2.0.0", SemVer) - isNotCompatibleWith("1.0.0-M1", SemVer) + isCompatibleWith("1.0.1", SemVer)(v) + isCompatibleWith("1.1.1", SemVer)(v) + isNotCompatibleWith("2.0.0", SemVer)(v) + isNotCompatibleWith("1.0.0-M1", SemVer)(v) - isCompatibleWith("1.0.1", SecondSegment) - isNotCompatibleWith("1.1.1", SecondSegment) - isNotCompatibleWith("2.0.0", SecondSegment) - isNotCompatibleWith("1.0.0-M1", SecondSegment) + isCompatibleWith("1.0.1", SecondSegment)(v) + isNotCompatibleWith("1.1.1", SecondSegment)(v) + isNotCompatibleWith("2.0.0", SecondSegment)(v) + isNotCompatibleWith("1.0.0-M1", SecondSegment)(v) } - version("1.0.0.0") { implicit v => - parsesTo(Seq(1, 0, 0, 0), Seq(), Seq()) - breaksDownTo(Some(1), Some(0), Some(0), Some(0)) - cascadesTo(Seq("1.0.0.0", "1.0.0", "1.0")) + version("1.0.0.0") { v => + parsesTo(Seq(1, 0, 0, 0), Seq(), Seq())(v) + breaksDownTo(Some(1), Some(0), Some(0), Some(0))(v) + cascadesTo(Seq("1.0.0.0", "1.0.0", "1.0"))(v) } - version("0.12.0") { implicit v => - parsesTo(Seq(0, 12, 0), Seq(), Seq()) - breaksDownTo(Some(0), Some(12), Some(0)) - cascadesTo(Seq("0.12.0", "0.12")) + version("0.12.0") { v => + parsesTo(Seq(0, 12, 0), Seq(), Seq())(v) + breaksDownTo(Some(0), Some(12), Some(0))(v) + cascadesTo(Seq("0.12.0", "0.12"))(v) - isNotCompatibleWith("0.12.0-RC1", SemVer) - isNotCompatibleWith("0.12.1", SemVer) - isNotCompatibleWith("0.12.1-M1", SemVer) + isNotCompatibleWith("0.12.0-RC1", SemVer)(v) + isNotCompatibleWith("0.12.1", SemVer)(v) + isNotCompatibleWith("0.12.1-M1", SemVer)(v) - isNotCompatibleWith("0.12.0-RC1", SecondSegment) - isCompatibleWith("0.12.1", SecondSegment) - isCompatibleWith("0.12.1-M1", SecondSegment) + isNotCompatibleWith("0.12.0-RC1", SecondSegment)(v) + isCompatibleWith("0.12.1", SecondSegment)(v) + isCompatibleWith("0.12.1-M1", SecondSegment)(v) } - version("0.1.0-SNAPSHOT") { implicit v => - parsesTo(Seq(0, 1, 0), Seq("SNAPSHOT"), Seq()) - cascadesTo(Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) + version("0.1.0-SNAPSHOT") { v => + parsesTo(Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())(v) + cascadesTo(Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))(v) - isCompatibleWith("0.1.0-SNAPSHOT", SemVer) - isNotCompatibleWith("0.1.0", SemVer) - isCompatibleWith("0.1.0-SNAPSHOT+001", SemVer) + isCompatibleWith("0.1.0-SNAPSHOT", SemVer)(v) + isNotCompatibleWith("0.1.0", SemVer)(v) + isCompatibleWith("0.1.0-SNAPSHOT+001", SemVer)(v) - isCompatibleWith("0.1.0-SNAPSHOT", SecondSegment) - isNotCompatibleWith("0.1.0", SecondSegment) - isCompatibleWith("0.1.0-SNAPSHOT+001", SecondSegment) + isCompatibleWith("0.1.0-SNAPSHOT", SecondSegment)(v) + isNotCompatibleWith("0.1.0", SecondSegment)(v) + isCompatibleWith("0.1.0-SNAPSHOT+001", SecondSegment)(v) } - version("0.1.0-M1") { implicit v => - parsesTo(Seq(0, 1, 0), Seq("M1"), Seq()) - cascadesTo(Seq("0.1.0-M1", "0.1.0", "0.1")) + version("0.1.0-M1") { v => + parsesTo(Seq(0, 1, 0), Seq("M1"), Seq())(v) + cascadesTo(Seq("0.1.0-M1", "0.1.0", "0.1"))(v) } - version("0.1.0-RC1") { implicit v => - parsesTo(Seq(0, 1, 0), Seq("RC1"), Seq()) - cascadesTo(Seq("0.1.0-RC1", "0.1.0", "0.1")) + version("0.1.0-RC1") { v => + parsesTo(Seq(0, 1, 0), Seq("RC1"), Seq())(v) + cascadesTo(Seq("0.1.0-RC1", "0.1.0", "0.1"))(v) } - version("0.1.0-MSERVER-1") { implicit v => - parsesTo(Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) - cascadesTo(Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) + version("0.1.0-MSERVER-1") { v => + parsesTo(Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())(v) + cascadesTo(Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))(v) } - version("2.10.4-20140115-000117-b3a-sources") { implicit v => - parsesTo(Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) - cascadesTo(Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) - isCompatibleWith("2.0.0", SemVer) - isNotCompatibleWith("2.0.0", SecondSegment) + version("2.10.4-20140115-000117-b3a-sources") { v => + parsesTo(Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())(v) + cascadesTo(Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))(v) + isCompatibleWith("2.0.0", SemVer)(v) + isNotCompatibleWith("2.0.0", SecondSegment)(v) } - version("20140115000117-b3a-sources") { implicit v => - parsesTo(Seq(20140115000117L), Seq("b3a", "sources"), Seq()) - cascadesTo(Seq("20140115000117-b3a-sources")) + version("20140115000117-b3a-sources") { v => + parsesTo(Seq(20140115000117L), Seq("b3a", "sources"), Seq())(v) + cascadesTo(Seq("20140115000117-b3a-sources"))(v) } - version("1.0.0-alpha+001+002") { implicit v => - parsesTo(Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) - cascadesTo(Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) + version("1.0.0-alpha+001+002") { v => + parsesTo(Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))(v) + cascadesTo(Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))(v) } - version("non.space.!?string") { implicit v => - parsesTo(Seq(), Seq(), Seq("non.space.!?string")) - cascadesTo(Seq("non.space.!?string")) + version("non.space.!?string") { v => + parsesTo(Seq(), Seq(), Seq("non.space.!?string"))(v) + cascadesTo(Seq("non.space.!?string"))(v) } - version("space !?string") { implicit v => - parsesToError + version("space !?string") { v => + parsesToError(v) } - version("") { implicit v => - parsesToError + version("") { v => + parsesToError(v) } //// - // to be used as an implicit final class VersionString(val value: String) private[this] def version[A](s: String)(f: VersionString => A) = { From 4b9eb388a230f7fa291f7387ee6b2f735437e46f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 19 Mar 2018 16:00:47 +0000 Subject: [PATCH 0748/1030] In VersionNumberSpec switch to FreeSpec, add "assert" prefix --- .../librarymanagement/VersionNumberSpec.scala | 172 ++++++++++-------- 1 file changed, 93 insertions(+), 79 deletions(-) diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index ecf3e00a4..eab52f6c9 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -1,128 +1,132 @@ package sbt.librarymanagement -import sbt.internal.librarymanagement.UnitSpec -import org.scalatest.Inside +import org.scalatest.{ FreeSpec, Inside, Matchers } // This is a specification to check VersionNumber and VersionNumberCompatibility. -class VersionNumberSpec extends UnitSpec with Inside { +class VersionNumberSpec extends FreeSpec with Matchers with Inside { import VersionNumber.{ SemVer, SecondSegment } version("1") { v => - parsesTo(Seq(1), Seq(), Seq())(v) - breaksDownTo(Some(1))(v) - cascadesTo(Seq("1"))(v) + assertParsesTo(v, Seq(1), Seq(), Seq()) + assertBreaksDownTo(v, Some(1)) + assertCascadesTo(v, Seq("1")) } version("1.0") { v => - parsesTo(Seq(1, 0), Seq(), Seq())(v) - breaksDownTo(Some(1), Some(0))(v) - cascadesTo(Seq("1.0"))(v) + assertParsesTo(v, Seq(1, 0), Seq(), Seq()) + assertBreaksDownTo(v, Some(1), Some(0)) + assertCascadesTo(v, Seq("1.0")) } version("1.0.0") { v => - parsesTo(Seq(1, 0, 0), Seq(), Seq())(v) - breaksDownTo(Some(1), Some(0), Some(0))(v) - cascadesTo(Seq("1.0.0", "1.0"))(v) + assertParsesTo(v, Seq(1, 0, 0), Seq(), Seq()) + assertBreaksDownTo(v, Some(1), Some(0), Some(0)) + assertCascadesTo(v, Seq("1.0.0", "1.0")) - isCompatibleWith("1.0.1", SemVer)(v) - isCompatibleWith("1.1.1", SemVer)(v) - isNotCompatibleWith("2.0.0", SemVer)(v) - isNotCompatibleWith("1.0.0-M1", SemVer)(v) + assertIsCompatibleWith(v, "1.0.1", SemVer) + assertIsCompatibleWith(v, "1.1.1", SemVer) + assertIsNotCompatibleWith(v, "2.0.0", SemVer) + assertIsNotCompatibleWith(v, "1.0.0-M1", SemVer) - isCompatibleWith("1.0.1", SecondSegment)(v) - isNotCompatibleWith("1.1.1", SecondSegment)(v) - isNotCompatibleWith("2.0.0", SecondSegment)(v) - isNotCompatibleWith("1.0.0-M1", SecondSegment)(v) + assertIsCompatibleWith(v, "1.0.1", SecondSegment) + assertIsNotCompatibleWith(v, "1.1.1", SecondSegment) + assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) + assertIsNotCompatibleWith(v, "1.0.0-M1", SecondSegment) } version("1.0.0.0") { v => - parsesTo(Seq(1, 0, 0, 0), Seq(), Seq())(v) - breaksDownTo(Some(1), Some(0), Some(0), Some(0))(v) - cascadesTo(Seq("1.0.0.0", "1.0.0", "1.0"))(v) + assertParsesTo(v, Seq(1, 0, 0, 0), Seq(), Seq()) + assertBreaksDownTo(v, Some(1), Some(0), Some(0), Some(0)) + assertCascadesTo(v, Seq("1.0.0.0", "1.0.0", "1.0")) } version("0.12.0") { v => - parsesTo(Seq(0, 12, 0), Seq(), Seq())(v) - breaksDownTo(Some(0), Some(12), Some(0))(v) - cascadesTo(Seq("0.12.0", "0.12"))(v) + assertParsesTo(v, Seq(0, 12, 0), Seq(), Seq()) + assertBreaksDownTo(v, Some(0), Some(12), Some(0)) + assertCascadesTo(v, Seq("0.12.0", "0.12")) - isNotCompatibleWith("0.12.0-RC1", SemVer)(v) - isNotCompatibleWith("0.12.1", SemVer)(v) - isNotCompatibleWith("0.12.1-M1", SemVer)(v) + assertIsNotCompatibleWith(v, "0.12.0-RC1", SemVer) + assertIsNotCompatibleWith(v, "0.12.1", SemVer) + assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer) - isNotCompatibleWith("0.12.0-RC1", SecondSegment)(v) - isCompatibleWith("0.12.1", SecondSegment)(v) - isCompatibleWith("0.12.1-M1", SecondSegment)(v) + assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment) + assertIsCompatibleWith(v, "0.12.1", SecondSegment) + assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment) } version("0.1.0-SNAPSHOT") { v => - parsesTo(Seq(0, 1, 0), Seq("SNAPSHOT"), Seq())(v) - cascadesTo(Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1"))(v) + assertParsesTo(v, Seq(0, 1, 0), Seq("SNAPSHOT"), Seq()) + assertCascadesTo(v, Seq("0.1.0-SNAPSHOT", "0.1.0", "0.1")) - isCompatibleWith("0.1.0-SNAPSHOT", SemVer)(v) - isNotCompatibleWith("0.1.0", SemVer)(v) - isCompatibleWith("0.1.0-SNAPSHOT+001", SemVer)(v) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SemVer) + assertIsNotCompatibleWith(v, "0.1.0", SemVer) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer) - isCompatibleWith("0.1.0-SNAPSHOT", SecondSegment)(v) - isNotCompatibleWith("0.1.0", SecondSegment)(v) - isCompatibleWith("0.1.0-SNAPSHOT+001", SecondSegment)(v) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SecondSegment) + assertIsNotCompatibleWith(v, "0.1.0", SecondSegment) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SecondSegment) } version("0.1.0-M1") { v => - parsesTo(Seq(0, 1, 0), Seq("M1"), Seq())(v) - cascadesTo(Seq("0.1.0-M1", "0.1.0", "0.1"))(v) + assertParsesTo(v, Seq(0, 1, 0), Seq("M1"), Seq()) + assertCascadesTo(v, Seq("0.1.0-M1", "0.1.0", "0.1")) } version("0.1.0-RC1") { v => - parsesTo(Seq(0, 1, 0), Seq("RC1"), Seq())(v) - cascadesTo(Seq("0.1.0-RC1", "0.1.0", "0.1"))(v) + assertParsesTo(v, Seq(0, 1, 0), Seq("RC1"), Seq()) + assertCascadesTo(v, Seq("0.1.0-RC1", "0.1.0", "0.1")) } version("0.1.0-MSERVER-1") { v => - parsesTo(Seq(0, 1, 0), Seq("MSERVER", "1"), Seq())(v) - cascadesTo(Seq("0.1.0-MSERVER-1", "0.1.0", "0.1"))(v) + assertParsesTo(v, Seq(0, 1, 0), Seq("MSERVER", "1"), Seq()) + assertCascadesTo(v, Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) } version("2.10.4-20140115-000117-b3a-sources") { v => - parsesTo(Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq())(v) - cascadesTo(Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10"))(v) - isCompatibleWith("2.0.0", SemVer)(v) - isNotCompatibleWith("2.0.0", SecondSegment)(v) + assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) + assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) + assertIsCompatibleWith(v, "2.0.0", SemVer) + assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) } version("20140115000117-b3a-sources") { v => - parsesTo(Seq(20140115000117L), Seq("b3a", "sources"), Seq())(v) - cascadesTo(Seq("20140115000117-b3a-sources"))(v) + assertParsesTo(v, Seq(20140115000117L), Seq("b3a", "sources"), Seq()) + assertCascadesTo(v, Seq("20140115000117-b3a-sources")) } version("1.0.0-alpha+001+002") { v => - parsesTo(Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002"))(v) - cascadesTo(Seq("1.0.0-alpha+001+002", "1.0.0", "1.0"))(v) + assertParsesTo(v, Seq(1, 0, 0), Seq("alpha"), Seq("+001", "+002")) + assertCascadesTo(v, Seq("1.0.0-alpha+001+002", "1.0.0", "1.0")) } version("non.space.!?string") { v => - parsesTo(Seq(), Seq(), Seq("non.space.!?string"))(v) - cascadesTo(Seq("non.space.!?string"))(v) + assertParsesTo(v, Seq(), Seq(), Seq("non.space.!?string")) + assertCascadesTo(v, Seq("non.space.!?string")) } version("space !?string") { v => - parsesToError(v) + assertParsesToError(v) } version("") { v => - parsesToError(v) + assertParsesToError(v) } //// - final class VersionString(val value: String) + private[this] final class VersionString(val value: String) - private[this] def version[A](s: String)(f: VersionString => A) = { - behavior of s"""Version "$s"""" - f(new VersionString(s)) - } + private[this] def version(s: String)(f: VersionString => Unit) = + s"""Version "$s"""" - { + f(new VersionString(s)) + } - def parsesTo(ns: Seq[Long], ts: Seq[String], es: Seq[String])(implicit v: VersionString): Unit = - it should s"parse to ($ns, $ts, $es)" in inside(v.value) { + private[this] def assertParsesTo( + v: VersionString, + ns: Seq[Long], + ts: Seq[String], + es: Seq[String] + ): Unit = + s"should parse to ($ns, $ts, $es)" in inside(v.value) { case VersionNumber(ns1, ts1, es1) => (ns1 shouldBe ns) (ts1 shouldBe ts) @@ -131,20 +135,21 @@ class VersionNumberSpec extends UnitSpec with Inside { (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) } - private[this] def parsesToError(implicit v: VersionString): Unit = - it should "parse as an error" in { + private[this] def assertParsesToError(v: VersionString): Unit = + "should parse as an error" in { v.value should not matchPattern { case s: String if VersionNumber.unapply(s).isDefined => // because of unapply overloading } } - private[this] def breaksDownTo( + private[this] def assertBreaksDownTo( + v: VersionString, major: Option[Long], minor: Option[Long] = None, patch: Option[Long] = None, buildNumber: Option[Long] = None - )(implicit v: VersionString): Unit = - it should s"breakdown to ($major, $minor, $patch, $buildNumber)" in inside(v.value) { + ): Unit = + s"should breakdown to ($major, $minor, $patch, $buildNumber)" in inside(v.value) { case VersionNumber(ns, ts, es) => val v = VersionNumber(ns, ts, es) (v._1 shouldBe major) @@ -153,31 +158,40 @@ class VersionNumberSpec extends UnitSpec with Inside { (v._4 shouldBe buildNumber) } - private[this] def cascadesTo(ns: Seq[String])(implicit v: VersionString) = { - it should s"cascade to $ns" in { + private[this] def assertCascadesTo(v: VersionString, ns: Seq[String]): Unit = { + s"should cascade to $ns" in { val versionNumbers = ns.toVector map VersionNumber.apply VersionNumber(v.value).cascadingVersions shouldBe versionNumbers } } - def isCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) = - checkCompat(true, vnc, v2) + private[this] def assertIsCompatibleWith( + v1: VersionString, + v2: String, + vnc: VersionNumberCompatibility + ): Unit = + checkCompat(true, vnc, v1, v2) - def isNotCompatibleWith(v2: String, vnc: VersionNumberCompatibility)(implicit v1: VersionString) = - checkCompat(false, vnc, v2) + private[this] def assertIsNotCompatibleWith( + v1: VersionString, + v2: String, + vnc: VersionNumberCompatibility + ): Unit = + checkCompat(false, vnc, v1, v2) private[this] def checkCompat( expectOutcome: Boolean, vnc: VersionNumberCompatibility, + v1: VersionString, v2: String - )(implicit v1: VersionString) = { - val prefix = if (expectOutcome) "" else "NOT " + ) = { + val prefix = if (expectOutcome) "should" else "should NOT" val compatibilityStrategy = vnc match { case SemVer => "SemVer" case SecondSegment => "SecondSegment" case _ => val s = vnc.name; if (s contains " ") s""""$s"""" else s } - it should s"${prefix}be $compatibilityStrategy compatible with $v2" in { + s"$prefix be $compatibilityStrategy compatible with $v2" in { vnc.isCompatible(VersionNumber(v1.value), VersionNumber(v2)) shouldBe expectOutcome } } From 0f93849214f8409d785f552ae8d5e4e086c33c8f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 15 Mar 2018 01:45:45 +0000 Subject: [PATCH 0749/1030] Cleanup & tweak VersionNumber --- .../sbt/librarymanagement/VersionNumber.scala | 229 ++++++++++-------- .../librarymanagement/VersionNumberSpec.scala | 4 +- 2 files changed, 131 insertions(+), 102 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index f6a95527c..fa4f1f35f 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -5,38 +5,31 @@ final class VersionNumber private[sbt] ( val tags: Seq[String], val extras: Seq[String] ) { + def _1: Option[Long] = get(0) def _2: Option[Long] = get(1) def _3: Option[Long] = get(2) def _4: Option[Long] = get(3) - def get(idx: Int): Option[Long] = - if (size <= idx) None - else Some(numbers(idx)) + def get(idx: Int): Option[Long] = numbers lift idx def size: Int = numbers.size /** The vector of version numbers from more to less specific from this version number. */ lazy val cascadingVersions: Vector[VersionNumber] = - (Vector(this) ++ - (numbers.inits filter (_.length >= 2) map (VersionNumber(_, Nil, Nil)))).distinct + (Vector(this) ++ (numbers.inits filter (_.size >= 2) map (VersionNumber(_, Nil, Nil)))).distinct - private[this] val versionStr: String = - numbers.mkString(".") + - (tags match { - case Seq() => "" - case ts => "-" + ts.mkString("-") - }) + - extras.mkString("") - override def toString: String = versionStr - override def hashCode: Int = - numbers.hashCode * 41 * 41 + - tags.hashCode * 41 + - extras.hashCode - override def equals(o: Any): Boolean = - o match { - case v: VersionNumber => - (this.numbers == v.numbers) && (this.tags == v.tags) && (this.extras == v.extras) - case _ => false - } + override val toString: String = + numbers.mkString(".") + mkString1(tags, "-", "-", "") + extras.mkString("") + + override def hashCode: Int = numbers.## * 41 * 41 + tags.## * 41 + extras.## + + override def equals(that: Any): Boolean = that match { + case v: VersionNumber => (numbers == v.numbers) && (tags == v.tags) && (extras == v.extras) + case _ => false + } + + /** A variant of mkString that returns the empty string if the sequence is empty. */ + private[this] def mkString1[A](xs: Seq[A], start: String, sep: String, end: String): String = + if (xs.isEmpty) "" else xs.mkString(start, sep, end) } object VersionNumber { @@ -44,120 +37,156 @@ object VersionNumber { /** * @param numbers numbers delimited by a dot. * @param tags string prefixed by a dash. - * @param any other strings at the end. + * @param extras strings at the end. */ def apply(numbers: Seq[Long], tags: Seq[String], extras: Seq[String]): VersionNumber = new VersionNumber(numbers, tags, extras) - def apply(v: String): VersionNumber = - unapply(v) match { + + def apply(s: String): VersionNumber = + unapply(s) match { case Some((ns, ts, es)) => VersionNumber(ns, ts, es) - case _ => sys.error(s"Invalid version number: $v") + case _ => throw new IllegalArgumentException(s"Invalid version number: $s") } def unapply(v: VersionNumber): Option[(Seq[Long], Seq[String], Seq[String])] = Some((v.numbers, v.tags, v.extras)) - def unapply(v: String): Option[(Seq[Long], Seq[String], Seq[String])] = { - def splitDot(s: String): Vector[Long] = - Option(s) match { - case Some(x) => x.split('.').toVector.filterNot(_ == "").map(_.toLong) - case _ => Vector() - } - def splitDash(s: String): Vector[String] = - Option(s) match { - case Some(x) => x.split('-').toVector.filterNot(_ == "") - case _ => Vector() - } - def splitPlus(s: String): Vector[String] = - Option(s) match { - case Some(x) => x.split('+').toVector.filterNot(_ == "").map("+" + _) - case _ => Vector() - } + def unapply(s: String): Option[(Seq[Long], Seq[String], Seq[String])] = { + + // null safe, empty string safe + def splitOn[A](s: String, sep: Char): Vector[String] = + if (s eq null) Vector() + else s.split(sep).filterNot(_ == "").toVector + + def splitDot(s: String) = splitOn(s, '.') map (_.toLong) + def splitDash(s: String) = splitOn(s, '-') + def splitPlus(s: String) = splitOn(s, '+') map ("+" + _) + val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+)*)((?:\+.+)*)""".r val NonSpaceString = """(\S+)""".r - v match { + + s match { case TaggedVersion(m, ns, ts, es) => - Some((Vector(m.toLong) ++ splitDot(ns), splitDash(ts), splitPlus(es))) + val numbers = Vector(m.toLong) ++ splitDot(ns) + val tags = splitDash(ts) + val extras = splitPlus(es) + Some((numbers, tags, extras)) case "" => None - case NonSpaceString(s) => Some((Vector(), Vector(), Vector(s))) + case NonSpaceString(s) => Some((Vector.empty, Vector.empty, Vector(s))) case _ => None } } - /** - * Strict. Checks everythig. - */ + /** Strict. Checks everything. */ object Strict extends VersionNumberCompatibility { def name: String = "Strict" def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = v1 == v2 } - /** - * Semantic versioning. See http://semver.org/spec/v2.0.0.html - */ + /** Semantic Versioning. See http://semver.org/spec/v2.0.0.html */ object SemVer extends VersionNumberCompatibility { def name: String = "Semantic Versioning" + + /* Quotes of parts of the rules in the SemVer Spec relevant to compatibility checking: + * + * Rule 2: + * > A normal version number MUST take the form X.Y.Z + * + * Rule 4: + * > Major version zero (0.y.z) is for initial development. Anything may change at any time. + * + * Rule 6: + * > Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. + * + * Rule 7: + * > Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced. + * + * Rule 8: + * > Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced. + * + * Rule 9: + * > A pre-release version MAY be denoted by appending a hyphen and a series of + * > dot separated identifiers immediately following the patch version. + * > Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + * > Identifiers MUST NOT be empty. + * > Numeric identifiers MUST NOT include leading zeroes. + * > Pre-release versions have a lower precedence than the associated normal version. + * > A pre-release version indicates that the version is unstable and might not satisfy the + * > intended compatibility requirements as denoted by its associated normal version. + * > Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92. + * + * Rule 10: + * > Build metadata MAY be denoted by appending a plus sign and a series of + * > dot separated identifiers immediately following the patch or pre-release version. + * > Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + * > Identifiers MUST NOT be empty. + * > Build metadata SHOULD be ignored when determining version precedence. + * > Thus two versions that differ only in the build metadata, have the same precedence. + * > Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85. + * + * Rule 10 means that build metadata is never considered for compatibility + * we'll enforce this immediately by dropping them from both versions + * Rule 2 we enforce with custom extractors. + * Rule 4 we enforce by matching x = 0 & fully equals checking the two versions + * Rule 6, 7 & 8 means version compatibility is determined by comparing the two X values + * Rule 9 means pre-release versions are fully equals checked + */ def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = - doIsCompat(v1, v2) || doIsCompat(v2, v1) + doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) + private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { - case (v1, v2) - if (v1.size >= 2) && (v2.size >= 2) => // A normal version number MUST take the form X.Y.Z - ( - v1._1.get, - v1._2.get, - v1._3.getOrElse(0L), - v1.tags, - v2._1.get, - v2._2.get, - v2._3.getOrElse(0L), - v2.tags - ) match { - case (0L, _, _, _, 0L, _, _, _) => - // Major version zero (0.y.z) is for initial development. Anything may change at any time. The public API should not be considered stable. - equalsIgnoreExtra(v1, v2) - case (_, 0, 0, ts1, _, 0, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => - // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers - equalsIgnoreExtra(v1, v2) - case (x1, _, _, _, x2, _, _, _) => - // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. - // Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced - x1 == x2 - case _ => equalsIgnoreExtra(v1, v2) - } - case _ => false + case (NormalVersion(0, _, _), NormalVersion(0, _, _)) => v1 == v2 // R4 + case (NormalVersion(x1, _, _), NormalVersion(x2, _, _)) => x1 == x2 // R6, R7 & R8 + case (PrereleaseVersion(_, _, _), PrereleaseVersion(_, _, _)) => v1 == v2 // R9 + case _ => false } - // Build metadata SHOULD be ignored when determining version precedence. - private[this] def equalsIgnoreExtra(v1: VersionNumber, v2: VersionNumber): Boolean = - (v1.numbers == v2.numbers) && (v1.tags == v2.tags) + + // SemVer Spec Rule 10 (above) + private[VersionNumber] def dropBuildMetadata(v: VersionNumber) = + if (v.extras.isEmpty) v else VersionNumber(v.numbers, v.tags, Nil) + + // SemVer Spec Rule 9 (above) + private[VersionNumber] def isPrerelease(v: VersionNumber): Boolean = v.tags.nonEmpty + + // An extractor for SemVer's "normal version number" - SemVer Spec Rule 2 & Rule 9 (above) + private[VersionNumber] object NormalVersion { + def unapply(v: VersionNumber): Option[(Long, Long, Long)] = + PartialFunction.condOpt(v.numbers) { + // NOTE! We allow the z to be missing, because of legacy like commons-io 1.3 + case Seq(x, y, _*) if !isPrerelease(v) => (x, y, v._3 getOrElse 0) + } + } + + // An extractor for SemVer's "pre-release versions" - SemVer Spec Rule 2 & Rule 9 (above) + private[VersionNumber] object PrereleaseVersion { + def unapply(v: VersionNumber): Option[(Long, Long, Long)] = + PartialFunction.condOpt(v.numbers) { + // NOTE! We allow the z to be missing, because of legacy like commons-io 1.3 + case Seq(x, y, _*) if isPrerelease(v) => (x, y, v._3 getOrElse 0) + } + } } - /* A variant of SemVar that seems to be common among the Scala libraries. + /** A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. - * Also API comatibility is expected even when the first segment is zero. + * Also API compatibility is expected even when the first segment is zero. */ object SecondSegment extends VersionNumberCompatibility { + import SemVer._ + def name: String = "Second Segment Variant" + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = - doIsCompat(v1, v2) || doIsCompat(v2, v1) - private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = + doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) + + private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = { (v1, v2) match { - case (v1, v2) - if (v1.size >= 3) && (v2.size >= 3) => // A normal version number MUST take the form X.Y.Z - (v1._1.get, v1._2.get, v1._3.get, v1.tags, v2._1.get, v2._2.get, v2._3.get, v2.tags) match { - case (x1 @ _, y1 @ _, 0, ts1, x2 @ _, y2 @ _, 0, ts2) if ts1.nonEmpty || ts2.nonEmpty => - // A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers - equalsIgnoreExtra(v1, v2) - case (x1, y1, _, _, x2, y2, _, _) => - // Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible changes are introduced. - (x1 == x2) && (y1 == y2) - case _ => equalsIgnoreExtra(v1, v2) - } - case _ => false + case (NormalVersion(x1, y1, _), NormalVersion(x2, y2, _)) => (x1 == x2) && (y1 == y2) + case (PrereleaseVersion(_, _, _), PrereleaseVersion(_, _, _)) => v1 == v2 // R2 & R9 + case _ => false } - // Build metadata SHOULD be ignored when determining version precedence. - private[this] def equalsIgnoreExtra(v1: VersionNumber, v2: VersionNumber): Boolean = - (v1.numbers == v2.numbers) && (v1.tags == v2.tags) + } } } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index eab52f6c9..dee74c35b 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -51,7 +51,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment) assertIsCompatibleWith(v, "0.12.1", SecondSegment) - assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment) + assertIsNotCompatibleWith(v, "0.12.1-M1", SecondSegment) } version("0.1.0-SNAPSHOT") { v => @@ -85,7 +85,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { version("2.10.4-20140115-000117-b3a-sources") { v => assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) - assertIsCompatibleWith(v, "2.0.0", SemVer) + assertIsNotCompatibleWith(v, "2.0.0", SemVer) assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) } From f3b06bc18e532f78b50021319516db1065020f93 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 23 Mar 2018 18:13:59 +0900 Subject: [PATCH 0750/1030] bump util to 1.1.3 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 3bddd2c42..61b8756e8 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,7 +7,7 @@ object Dependencies { val scala212 = "2.12.4" private val ioVersion = "1.1.3" - private val utilVersion = "1.1.2" + private val utilVersion = "1.1.3" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From a29a12054ae8ffafd0fc1f16e4fc154b1e925f9e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 23 Mar 2018 22:21:05 +0900 Subject: [PATCH 0751/1030] bump contraband to 0.4.0 Ref https://github.com/sbt/contraband/issues/119 --- build.sbt | 53 +++++++++++++++++++ .../ConfigurationReportLite.scala | 2 +- .../librarymanagement/UpdateReportLite.scala | 2 +- .../sbt/librarymanagement/Artifact.scala | 2 +- .../ArtifactTypeFilter.scala | 2 +- .../sbt/librarymanagement/Binary.scala | 2 +- .../sbt/librarymanagement/Caller.scala | 2 +- .../librarymanagement/ChainedResolver.scala | 2 +- .../sbt/librarymanagement/Checksum.scala | 2 +- .../sbt/librarymanagement/ConfigRef.scala | 2 +- .../ConfigurationReport.scala | 2 +- .../librarymanagement/ConflictManager.scala | 2 +- .../sbt/librarymanagement/Constant.scala | 2 +- .../sbt/librarymanagement/Developer.scala | 2 +- .../sbt/librarymanagement/Disabled.scala | 2 +- .../librarymanagement/FileConfiguration.scala | 2 +- .../librarymanagement/FileRepository.scala | 2 +- .../sbt/librarymanagement/Full.scala | 2 +- .../GetClassifiersConfiguration.scala | 2 +- .../GetClassifiersModule.scala | 2 +- .../sbt/librarymanagement/InclExclRule.scala | 2 +- .../IvyFileConfiguration.scala | 2 +- .../KeyFileAuthentication.scala | 2 +- .../MakePomConfiguration.scala | 2 +- .../sbt/librarymanagement/MavenCache.scala | 2 +- .../sbt/librarymanagement/MavenRepo.scala | 2 +- .../ModuleConfiguration.scala | 2 +- .../ModuleDescriptorConfiguration.scala | 2 +- .../sbt/librarymanagement/ModuleID.scala | 2 +- .../sbt/librarymanagement/ModuleInfo.scala | 2 +- .../sbt/librarymanagement/ModuleReport.scala | 2 +- .../OrganizationArtifactReport.scala | 2 +- .../PasswordAuthentication.scala | 2 +- .../sbt/librarymanagement/Patch.scala | 2 +- .../sbt/librarymanagement/Patterns.scala | 2 +- .../librarymanagement/PomConfiguration.scala | 2 +- .../PublishConfiguration.scala | 2 +- .../RetrieveConfiguration.scala | 2 +- .../librarymanagement/ScalaModuleInfo.scala | 2 +- .../sbt/librarymanagement/ScmInfo.scala | 2 +- .../librarymanagement/SftpRepository.scala | 2 +- .../sbt/librarymanagement/SshConnection.scala | 2 +- .../sbt/librarymanagement/SshRepository.scala | 2 +- .../sbt/librarymanagement/URLRepository.scala | 2 +- .../UpdateConfiguration.scala | 2 +- .../sbt/librarymanagement/UpdateReport.scala | 2 +- .../sbt/librarymanagement/UpdateStats.scala | 2 +- .../ivy/ExternalIvyConfiguration.scala | 2 +- .../ivy/InlineIvyConfiguration.scala | 2 +- .../sbt/librarymanagement/ivy/IvyPaths.scala | 2 +- project/plugins.sbt | 2 +- 51 files changed, 103 insertions(+), 50 deletions(-) diff --git a/build.sbt b/build.sbt index 7f98affae..15b9d73b0 100644 --- a/build.sbt +++ b/build.sbt @@ -140,6 +140,54 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.classifier"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), + + // contraband issue + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.UpdateReportLite.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Artifact.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilter.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Binary.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Caller.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ChainedResolver.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Checksum.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ConfigRef.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ConfigurationReport.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ConflictManager.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Constant.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Developer.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Disabled.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileRepository.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Full.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersModule.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.InclExclRule.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.IvyFileConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.KeyFileAuthentication.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MakePomConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenCache.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenRepo.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleID.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleInfo.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReport.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.OrganizationArtifactReport.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.PasswordAuthentication.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Patch.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Patterns.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.PomConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.PublishConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.RetrieveConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaModuleInfo.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScmInfo.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.SftpRepository.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.SshConnection.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.SshRepository.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateReport.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateStats.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.URLRepository.copy*"), ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -162,6 +210,11 @@ lazy val lmIvy = (project in file("ivy")) exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), + + // contraband issue + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.InlineIvyConfiguration.copy*"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPaths.copy*"), ), ) diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala index 7570d3356..e43ee8de8 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala @@ -20,7 +20,7 @@ final class ConfigurationReportLite private ( override def toString: String = { "ConfigurationReportLite(" + configuration + ", " + details + ")" } - protected[this] def copy(configuration: String = configuration, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReportLite = { + private[this] def copy(configuration: String = configuration, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReportLite = { new ConfigurationReportLite(configuration, details) } def withConfiguration(configuration: String): ConfigurationReportLite = { diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala index 350fff041..864709b5d 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala @@ -19,7 +19,7 @@ final class UpdateReportLite private ( override def toString: String = { "UpdateReportLite(" + configurations + ")" } - protected[this] def copy(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite] = configurations): UpdateReportLite = { + private[this] def copy(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite] = configurations): UpdateReportLite = { new UpdateReportLite(configurations) } def withConfigurations(configurations: Vector[sbt.internal.librarymanagement.ConfigurationReportLite]): UpdateReportLite = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 92c623050..d337cb364 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -26,7 +26,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" } - protected[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) } def withName(name: String): Artifact = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala index 3086e498e..fa68be8f1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -27,7 +27,7 @@ final class ArtifactTypeFilter private ( override def toString: String = { "ArtifactTypeFilter(" + types + ", " + inverted + ")" } - protected[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter = { + private[this] def copy(types: Set[String] = types, inverted: Boolean = inverted): ArtifactTypeFilter = { new ArtifactTypeFilter(types, inverted) } def withTypes(types: Set[String]): ArtifactTypeFilter = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala index b66b5f737..3cc75b328 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala @@ -26,7 +26,7 @@ final class Binary private ( override def toString: String = { "Binary(" + prefix + ", " + suffix + ")" } - protected[this] def copy(prefix: String = prefix, suffix: String = suffix): Binary = { + private[this] def copy(prefix: String = prefix, suffix: String = suffix): Binary = { new Binary(prefix, suffix) } def withPrefix(prefix: String): Binary = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala index cbf57fa13..b29caaf26 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -25,7 +25,7 @@ final class Caller private ( override def toString: String = { s"$caller" } - protected[this] def copy(caller: sbt.librarymanagement.ModuleID = caller, callerConfigurations: Vector[sbt.librarymanagement.ConfigRef] = callerConfigurations, callerExtraAttributes: Map[String, String] = callerExtraAttributes, isForceDependency: Boolean = isForceDependency, isChangingDependency: Boolean = isChangingDependency, isTransitiveDependency: Boolean = isTransitiveDependency, isDirectlyForceDependency: Boolean = isDirectlyForceDependency): Caller = { + private[this] def copy(caller: sbt.librarymanagement.ModuleID = caller, callerConfigurations: Vector[sbt.librarymanagement.ConfigRef] = callerConfigurations, callerExtraAttributes: Map[String, String] = callerExtraAttributes, isForceDependency: Boolean = isForceDependency, isChangingDependency: Boolean = isChangingDependency, isTransitiveDependency: Boolean = isTransitiveDependency, isDirectlyForceDependency: Boolean = isDirectlyForceDependency): Caller = { new Caller(caller, callerConfigurations, callerExtraAttributes, isForceDependency, isChangingDependency, isTransitiveDependency, isDirectlyForceDependency) } def withCaller(caller: sbt.librarymanagement.ModuleID): Caller = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index 19215a7c8..d98e6d1cb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -20,7 +20,7 @@ final class ChainedResolver private ( override def toString: String = { "ChainedResolver(" + name + ", " + resolvers + ")" } - protected[this] def copy(name: String = name, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers): ChainedResolver = { + private[this] def copy(name: String = name, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers): ChainedResolver = { new ChainedResolver(name, resolvers) } def withName(name: String): ChainedResolver = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala index 2a699be36..20f136226 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala @@ -20,7 +20,7 @@ final class Checksum private ( override def toString: String = { "Checksum(" + digest + ", " + `type` + ")" } - protected[this] def copy(digest: String = digest, `type`: String = `type`): Checksum = { + private[this] def copy(digest: String = digest, `type`: String = `type`): Checksum = { new Checksum(digest, `type`) } def withDigest(digest: String): Checksum = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index 78e47af49..30cba07f5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -21,7 +21,7 @@ final class ConfigRef private ( override def toString: String = { name } - protected[this] def copy(name: String = name): ConfigRef = { + private[this] def copy(name: String = name): ConfigRef = { new ConfigRef(name) } def withName(name: String): ConfigRef = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index a11155f73..228a8fdbe 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -27,7 +27,7 @@ final class ConfigurationReport private ( (if (details.isEmpty) modules.mkString + details.flatMap(_.modules).filter(_.evicted).map("\t\t(EVICTED) " + _ + "\n").mkString else details.mkString) } - protected[this] def copy(configuration: sbt.librarymanagement.ConfigRef = configuration, modules: Vector[sbt.librarymanagement.ModuleReport] = modules, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReport = { + private[this] def copy(configuration: sbt.librarymanagement.ConfigRef = configuration, modules: Vector[sbt.librarymanagement.ModuleReport] = modules, details: Vector[sbt.librarymanagement.OrganizationArtifactReport] = details): ConfigurationReport = { new ConfigurationReport(configuration, modules, details) } def withConfiguration(configuration: sbt.librarymanagement.ConfigRef): ConfigurationReport = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala index 97e9737bf..b4022dda4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -22,7 +22,7 @@ final class ConflictManager private ( override def toString: String = { "ConflictManager(" + name + ", " + organization + ", " + module + ")" } - protected[this] def copy(name: String = name, organization: String = organization, module: String = module): ConflictManager = { + private[this] def copy(name: String = name, organization: String = organization, module: String = module): ConflictManager = { new ConflictManager(name, organization, module) } def withName(name: String): ConflictManager = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala index 148546958..8380dccf5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala @@ -20,7 +20,7 @@ final class Constant private ( override def toString: String = { "Constant(" + value + ")" } - protected[this] def copy(value: String = value): Constant = { + private[this] def copy(value: String = value): Constant = { new Constant(value) } def withValue(value: String): Constant = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index d1c69eec9..30c20f3b9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - protected[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala index 6a3ccde72..f53c8b541 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala @@ -19,7 +19,7 @@ override def hashCode: Int = { override def toString: String = { "Disabled()" } -protected[this] def copy(): Disabled = { +private[this] def copy(): Disabled = { new Disabled() } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala index 4787d4bfb..376efe8e4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala @@ -21,7 +21,7 @@ final class FileConfiguration private ( override def toString: String = { "FileConfiguration(" + isLocal + ", " + isTransactional + ")" } - protected[this] def copy(isLocal: Boolean = isLocal, isTransactional: Option[Boolean] = isTransactional): FileConfiguration = { + private[this] def copy(isLocal: Boolean = isLocal, isTransactional: Option[Boolean] = isTransactional): FileConfiguration = { new FileConfiguration(isLocal, isTransactional) } def withIsLocal(isLocal: Boolean): FileConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala index 8bbf9f976..75790b075 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala @@ -23,7 +23,7 @@ final class FileRepository private ( override def toString: String = { "FileRepository(" + name + ", " + patterns + ", " + configuration + ")" } - protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, configuration: sbt.librarymanagement.FileConfiguration = configuration): FileRepository = { + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, configuration: sbt.librarymanagement.FileConfiguration = configuration): FileRepository = { new FileRepository(name, patterns, configuration) } def withName(name: String): FileRepository = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala index 71ea0fc87..cd2416d7e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala @@ -26,7 +26,7 @@ final class Full private ( override def toString: String = { "Full(" + prefix + ", " + suffix + ")" } - protected[this] def copy(prefix: String = prefix, suffix: String = suffix): Full = { + private[this] def copy(prefix: String = prefix, suffix: String = suffix): Full = { new Full(prefix, suffix) } def withPrefix(prefix: String): Full = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala index 200aa87fe..1448c1d9e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala @@ -23,7 +23,7 @@ final class GetClassifiersConfiguration private ( override def toString: String = { "GetClassifiersConfiguration(" + module + ", " + excludes + ", " + updateConfiguration + ", " + sourceArtifactTypes + ", " + docArtifactTypes + ")" } - protected[this] def copy(module: sbt.librarymanagement.GetClassifiersModule = module, excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]] = excludes, updateConfiguration: sbt.librarymanagement.UpdateConfiguration = updateConfiguration, sourceArtifactTypes: Vector[String] = sourceArtifactTypes, docArtifactTypes: Vector[String] = docArtifactTypes): GetClassifiersConfiguration = { + private[this] def copy(module: sbt.librarymanagement.GetClassifiersModule = module, excludes: Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]] = excludes, updateConfiguration: sbt.librarymanagement.UpdateConfiguration = updateConfiguration, sourceArtifactTypes: Vector[String] = sourceArtifactTypes, docArtifactTypes: Vector[String] = docArtifactTypes): GetClassifiersConfiguration = { new GetClassifiersConfiguration(module, excludes, updateConfiguration, sourceArtifactTypes, docArtifactTypes) } def withModule(module: sbt.librarymanagement.GetClassifiersModule): GetClassifiersConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala index 147ba44ae..3f69e3a36 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala @@ -23,7 +23,7 @@ final class GetClassifiersModule private ( override def toString: String = { "GetClassifiersModule(" + id + ", " + scalaModuleInfo + ", " + dependencies + ", " + configurations + ", " + classifiers + ")" } - protected[this] def copy(id: sbt.librarymanagement.ModuleID = id, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, classifiers: Vector[String] = classifiers): GetClassifiersModule = { + private[this] def copy(id: sbt.librarymanagement.ModuleID = id, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, classifiers: Vector[String] = classifiers): GetClassifiersModule = { new GetClassifiersModule(id, scalaModuleInfo, dependencies, configurations, classifiers) } def withId(id: sbt.librarymanagement.ModuleID): GetClassifiersModule = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index a6f1ec1dd..f37f2de74 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -32,7 +32,7 @@ final class InclExclRule private ( override def toString: String = { "InclExclRule(" + organization + ", " + name + ", " + artifact + ", " + configurations + ", " + crossVersion + ")" } - protected[this] def copy(organization: String = organization, name: String = name, artifact: String = artifact, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion): InclExclRule = { + private[this] def copy(organization: String = organization, name: String = name, artifact: String = artifact, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion): InclExclRule = { new InclExclRule(organization, name, artifact, configurations, crossVersion) } def withOrganization(organization: String): InclExclRule = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala index 1136de05c..98a005c1c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -22,7 +22,7 @@ final class IvyFileConfiguration private ( override def toString: String = { "IvyFileConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" } - protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): IvyFileConfiguration = { + private[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): IvyFileConfiguration = { new IvyFileConfiguration(validate, scalaModuleInfo, file, autoScalaTools) } def withValidate(validate: Boolean): IvyFileConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala index e696a61d4..d818a88c8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala @@ -21,7 +21,7 @@ final class KeyFileAuthentication private ( override def toString: String = { "KeyFileAuthentication(" + user + ", " + keyfile + ", " + password + ")" } - protected[this] def copy(user: String = user, keyfile: java.io.File = keyfile, password: Option[String] = password): KeyFileAuthentication = { + private[this] def copy(user: String = user, keyfile: java.io.File = keyfile, password: Option[String] = password): KeyFileAuthentication = { new KeyFileAuthentication(user, keyfile, password) } def withUser(user: String): KeyFileAuthentication = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala index 5570f01c6..e7d0ffe2c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -26,7 +26,7 @@ final class MakePomConfiguration private ( override def toString: String = { "MakePomConfiguration(" + file + ", " + moduleInfo + ", " + configurations + ", " + extra + ", " + process + ", " + filterRepositories + ", " + allRepositories + ", " + includeTypes + ")" } - protected[this] def copy(file: Option[java.io.File] = file, moduleInfo: Option[sbt.librarymanagement.ModuleInfo] = moduleInfo, configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]] = configurations, extra: Option[scala.xml.NodeSeq] = extra, process: scala.Function1[scala.xml.Node, scala.xml.Node] = process, filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean] = filterRepositories, allRepositories: Boolean = allRepositories, includeTypes: Set[String] = includeTypes): MakePomConfiguration = { + private[this] def copy(file: Option[java.io.File] = file, moduleInfo: Option[sbt.librarymanagement.ModuleInfo] = moduleInfo, configurations: Option[scala.Vector[sbt.librarymanagement.Configuration]] = configurations, extra: Option[scala.xml.NodeSeq] = extra, process: scala.Function1[scala.xml.Node, scala.xml.Node] = process, filterRepositories: scala.Function1[sbt.librarymanagement.MavenRepository, Boolean] = filterRepositories, allRepositories: Boolean = allRepositories, includeTypes: Set[String] = includeTypes): MakePomConfiguration = { new MakePomConfiguration(file, moduleInfo, configurations, extra, process, filterRepositories, allRepositories, includeTypes) } def withFile(file: Option[java.io.File]): MakePomConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index 3f10f8e04..b1501e3d4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -27,7 +27,7 @@ final class MavenCache private ( override def toString: String = { s"cache:$name: ${rootFile.getAbsolutePath}" } - protected[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile, rootFile: java.io.File = rootFile): MavenCache = { + private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile, rootFile: java.io.File = rootFile): MavenCache = { new MavenCache(name, root, localIfFile, rootFile) } def withName(name: String): MavenCache = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index db4a4d64b..b01c6d8a9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -21,7 +21,7 @@ final class MavenRepo private ( override def toString: String = { s"$name: $root" } - protected[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile): MavenRepo = { + private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile): MavenRepo = { new MavenRepo(name, root, localIfFile) } def withName(name: String): MavenRepo = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala index 38accc410..3bd4b9591 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala @@ -22,7 +22,7 @@ final class ModuleConfiguration private ( override def toString: String = { "ModuleConfiguration(" + organization + ", " + name + ", " + revision + ", " + resolver + ")" } - protected[this] def copy(organization: String = organization, name: String = name, revision: String = revision, resolver: sbt.librarymanagement.Resolver = resolver): ModuleConfiguration = { + private[this] def copy(organization: String = organization, name: String = name, revision: String = revision, resolver: sbt.librarymanagement.Resolver = resolver): ModuleConfiguration = { new ModuleConfiguration(organization, name, revision, resolver) } def withOrganization(organization: String): ModuleConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 215a0c367..8d79275e6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -29,7 +29,7 @@ final class ModuleDescriptorConfiguration private ( override def toString: String = { "ModuleDescriptorConfiguration(" + validate + ", " + scalaModuleInfo + ", " + module + ", " + moduleInfo + ", " + dependencies + ", " + overrides + ", " + excludes + ", " + ivyXML + ", " + configurations + ", " + defaultConfiguration + ", " + conflictManager + ")" } - protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, module: sbt.librarymanagement.ModuleID = module, moduleInfo: sbt.librarymanagement.ModuleInfo = moduleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, overrides: Vector[sbt.librarymanagement.ModuleID] = overrides, excludes: Vector[sbt.librarymanagement.InclExclRule] = excludes, ivyXML: scala.xml.NodeSeq = ivyXML, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, defaultConfiguration: Option[sbt.librarymanagement.Configuration] = defaultConfiguration, conflictManager: sbt.librarymanagement.ConflictManager = conflictManager): ModuleDescriptorConfiguration = { + private[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, module: sbt.librarymanagement.ModuleID = module, moduleInfo: sbt.librarymanagement.ModuleInfo = moduleInfo, dependencies: Vector[sbt.librarymanagement.ModuleID] = dependencies, overrides: Vector[sbt.librarymanagement.ModuleID] = overrides, excludes: Vector[sbt.librarymanagement.InclExclRule] = excludes, ivyXML: scala.xml.NodeSeq = ivyXML, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, defaultConfiguration: Option[sbt.librarymanagement.Configuration] = defaultConfiguration, conflictManager: sbt.librarymanagement.ConflictManager = conflictManager): ModuleDescriptorConfiguration = { new ModuleDescriptorConfiguration(validate, scalaModuleInfo, module, moduleInfo, dependencies, overrides, excludes, ivyXML, configurations, defaultConfiguration, conflictManager) } def withValidate(validate: Boolean): ModuleDescriptorConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index eafa0dd95..485f8c533 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -31,7 +31,7 @@ final class ModuleID private ( override def toString: String = { this.toStringImpl } - protected[this] def copy(organization: String = organization, name: String = name, revision: String = revision, configurations: Option[String] = configurations, isChanging: Boolean = isChanging, isTransitive: Boolean = isTransitive, isForce: Boolean = isForce, explicitArtifacts: Vector[sbt.librarymanagement.Artifact] = explicitArtifacts, inclusions: Vector[sbt.librarymanagement.InclExclRule] = inclusions, exclusions: Vector[sbt.librarymanagement.InclExclRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion, branchName: Option[String] = branchName): ModuleID = { + private[this] def copy(organization: String = organization, name: String = name, revision: String = revision, configurations: Option[String] = configurations, isChanging: Boolean = isChanging, isTransitive: Boolean = isTransitive, isForce: Boolean = isForce, explicitArtifacts: Vector[sbt.librarymanagement.Artifact] = explicitArtifacts, inclusions: Vector[sbt.librarymanagement.InclExclRule] = inclusions, exclusions: Vector[sbt.librarymanagement.InclExclRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion, branchName: Option[String] = branchName): ModuleID = { new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) } def withOrganization(organization: String): ModuleID = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index e41ca76fb..545941120 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -28,7 +28,7 @@ final class ModuleInfo private ( override def toString: String = { "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" } - protected[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { + private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } def withNameFormal(nameFormal: String): ModuleInfo = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 3de609527..22c028d26 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -41,7 +41,7 @@ final class ModuleReport private ( s"\t\t$module: " + (if (arts.size <= 1) "" else "\n\t\t\t") + arts.mkString("\n\t\t\t") + "\n" } - protected[this] def copy(module: sbt.librarymanagement.ModuleID = module, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, missingArtifacts: Vector[sbt.librarymanagement.Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[java.util.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, evictedData: Option[String] = evictedData, evictedReason: Option[String] = evictedReason, problem: Option[String] = problem, homepage: Option[String] = homepage, extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, licenses: Vector[scala.Tuple2[String, Option[String]]] = licenses, callers: Vector[sbt.librarymanagement.Caller] = callers): ModuleReport = { + private[this] def copy(module: sbt.librarymanagement.ModuleID = module, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, missingArtifacts: Vector[sbt.librarymanagement.Artifact] = missingArtifacts, status: Option[String] = status, publicationDate: Option[java.util.Calendar] = publicationDate, resolver: Option[String] = resolver, artifactResolver: Option[String] = artifactResolver, evicted: Boolean = evicted, evictedData: Option[String] = evictedData, evictedReason: Option[String] = evictedReason, problem: Option[String] = problem, homepage: Option[String] = homepage, extraAttributes: Map[String, String] = extraAttributes, isDefault: Option[Boolean] = isDefault, branch: Option[String] = branch, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, licenses: Vector[scala.Tuple2[String, Option[String]]] = licenses, callers: Vector[sbt.librarymanagement.Caller] = callers): ModuleReport = { new ModuleReport(module, artifacts, missingArtifacts, status, publicationDate, resolver, artifactResolver, evicted, evictedData, evictedReason, problem, homepage, extraAttributes, isDefault, branch, configurations, licenses, callers) } def withModule(module: sbt.librarymanagement.ModuleID): ModuleReport = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index 112c4708b..0bef821d4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -33,7 +33,7 @@ final class OrganizationArtifactReport private ( val details = modules map { _.detailReport } s"\t$organization:$name\n${details.mkString}\n" } - protected[this] def copy(organization: String = organization, name: String = name, modules: Vector[sbt.librarymanagement.ModuleReport] = modules): OrganizationArtifactReport = { + private[this] def copy(organization: String = organization, name: String = name, modules: Vector[sbt.librarymanagement.ModuleReport] = modules): OrganizationArtifactReport = { new OrganizationArtifactReport(organization, name, modules) } def withOrganization(organization: String): OrganizationArtifactReport = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala index a67739cc5..93de4085d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala @@ -20,7 +20,7 @@ final class PasswordAuthentication private ( override def toString: String = { "PasswordAuthentication(" + user + ", " + password + ")" } - protected[this] def copy(user: String = user, password: Option[String] = password): PasswordAuthentication = { + private[this] def copy(user: String = user, password: Option[String] = password): PasswordAuthentication = { new PasswordAuthentication(user, password) } def withUser(user: String): PasswordAuthentication = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala index 65ec50436..217f7583e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala @@ -22,7 +22,7 @@ override def hashCode: Int = { override def toString: String = { "Patch()" } -protected[this] def copy(): Patch = { +private[this] def copy(): Patch = { new Patch() } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala index de2a54d98..57c0d03c4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -24,7 +24,7 @@ final class Patterns private ( "Patterns(ivyPatterns=%s, artifactPatterns=%s, isMavenCompatible=%s, descriptorOptional=%s, skipConsistencyCheck=%s)".format( ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } - protected[this] def copy(ivyPatterns: Vector[String] = ivyPatterns, artifactPatterns: Vector[String] = artifactPatterns, isMavenCompatible: Boolean = isMavenCompatible, descriptorOptional: Boolean = descriptorOptional, skipConsistencyCheck: Boolean = skipConsistencyCheck): Patterns = { + private[this] def copy(ivyPatterns: Vector[String] = ivyPatterns, artifactPatterns: Vector[String] = artifactPatterns, isMavenCompatible: Boolean = isMavenCompatible, descriptorOptional: Boolean = descriptorOptional, skipConsistencyCheck: Boolean = skipConsistencyCheck): Patterns = { new Patterns(ivyPatterns, artifactPatterns, isMavenCompatible, descriptorOptional, skipConsistencyCheck) } def withIvyPatterns(ivyPatterns: Vector[String]): Patterns = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala index e9cbf9219..f36a34149 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -22,7 +22,7 @@ final class PomConfiguration private ( override def toString: String = { "PomConfiguration(" + validate + ", " + scalaModuleInfo + ", " + file + ", " + autoScalaTools + ")" } - protected[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): PomConfiguration = { + private[this] def copy(validate: Boolean = validate, scalaModuleInfo: Option[sbt.librarymanagement.ScalaModuleInfo] = scalaModuleInfo, file: java.io.File = file, autoScalaTools: Boolean = autoScalaTools): PomConfiguration = { new PomConfiguration(validate, scalaModuleInfo, file, autoScalaTools) } def withValidate(validate: Boolean): PomConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala index 3adc81fcf..0b0bafa46 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -27,7 +27,7 @@ final class PublishConfiguration private ( override def toString: String = { "PublishConfiguration(" + publishMavenStyle + ", " + deliverIvyPattern + ", " + status + ", " + configurations + ", " + resolverName + ", " + artifacts + ", " + checksums + ", " + logging + ", " + overwrite + ")" } - protected[this] def copy(publishMavenStyle: Boolean = publishMavenStyle, deliverIvyPattern: Option[String] = deliverIvyPattern, status: Option[String] = status, configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurations, resolverName: Option[String] = resolverName, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, checksums: scala.Vector[String] = checksums, logging: Option[sbt.librarymanagement.UpdateLogging] = logging, overwrite: Boolean = overwrite): PublishConfiguration = { + private[this] def copy(publishMavenStyle: Boolean = publishMavenStyle, deliverIvyPattern: Option[String] = deliverIvyPattern, status: Option[String] = status, configurations: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurations, resolverName: Option[String] = resolverName, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]] = artifacts, checksums: scala.Vector[String] = checksums, logging: Option[sbt.librarymanagement.UpdateLogging] = logging, overwrite: Boolean = overwrite): PublishConfiguration = { new PublishConfiguration(publishMavenStyle, deliverIvyPattern, status, configurations, resolverName, artifacts, checksums, logging, overwrite) } def withPublishMavenStyle(publishMavenStyle: Boolean): PublishConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala index 205218b04..814b688dd 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -23,7 +23,7 @@ final class RetrieveConfiguration private ( override def toString: String = { "RetrieveConfiguration(" + retrieveDirectory + ", " + outputPattern + ", " + sync + ", " + configurationsToRetrieve + ")" } - protected[this] def copy(retrieveDirectory: Option[java.io.File] = retrieveDirectory, outputPattern: Option[String] = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurationsToRetrieve): RetrieveConfiguration = { + private[this] def copy(retrieveDirectory: Option[java.io.File] = retrieveDirectory, outputPattern: Option[String] = outputPattern, sync: Boolean = sync, configurationsToRetrieve: Option[scala.Vector[sbt.librarymanagement.ConfigRef]] = configurationsToRetrieve): RetrieveConfiguration = { new RetrieveConfiguration(retrieveDirectory, outputPattern, sync, configurationsToRetrieve) } def withRetrieveDirectory(retrieveDirectory: Option[java.io.File]): RetrieveConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index 36431b387..0f938830b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -26,7 +26,7 @@ final class ScalaModuleInfo private ( override def toString: String = { "ScalaModuleInfo(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" } - protected[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): ScalaModuleInfo = { + private[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): ScalaModuleInfo = { new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) } def withScalaFullVersion(scalaFullVersion: String): ScalaModuleInfo = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 713654f4e..4d40ee514 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -22,7 +22,7 @@ final class ScmInfo private ( override def toString: String = { "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" } - protected[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { + private[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { new ScmInfo(browseUrl, connection, devConnection) } def withBrowseUrl(browseUrl: java.net.URL): ScmInfo = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala index 63734d7ef..6bd5679c7 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala @@ -23,7 +23,7 @@ final class SftpRepository private ( override def toString: String = { "SftpRepository(" + name + ", " + patterns + ", " + connection + ")" } - protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection): SftpRepository = { + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection): SftpRepository = { new SftpRepository(name, patterns, connection) } def withName(name: String): SftpRepository = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala index 5e105ebef..a722ce55a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala @@ -21,7 +21,7 @@ final class SshConnection private ( override def toString: String = { "SshConnection(" + authentication + ", " + hostname + ", " + port + ")" } - protected[this] def copy(authentication: Option[sbt.librarymanagement.SshAuthentication] = authentication, hostname: Option[String] = hostname, port: Option[Int] = port): SshConnection = { + private[this] def copy(authentication: Option[sbt.librarymanagement.SshAuthentication] = authentication, hostname: Option[String] = hostname, port: Option[Int] = port): SshConnection = { new SshConnection(authentication, hostname, port) } def withAuthentication(authentication: Option[sbt.librarymanagement.SshAuthentication]): SshConnection = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala index ca7af27ed..4cb9a18b8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala @@ -24,7 +24,7 @@ final class SshRepository private ( override def toString: String = { "SshRepository(" + name + ", " + patterns + ", " + connection + ", " + publishPermissions + ")" } - protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection, publishPermissions: Option[String] = publishPermissions): SshRepository = { + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, connection: sbt.librarymanagement.SshConnection = connection, publishPermissions: Option[String] = publishPermissions): SshRepository = { new SshRepository(name, patterns, connection, publishPermissions) } def withName(name: String): SshRepository = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 41a52e655..1768cacda 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -20,7 +20,7 @@ final class URLRepository private ( override def toString: String = { "URLRepository(" + name + ", " + patterns + ")" } - protected[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns): URLRepository = { + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns): URLRepository = { new URLRepository(name, patterns) } def withName(name: String): URLRepository = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index 39fce50be..533a24542 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -37,7 +37,7 @@ final class UpdateConfiguration private ( override def toString: String = { "UpdateConfiguration(" + retrieveManaged + ", " + missingOk + ", " + logging + ", " + logicalClock + ", " + metadataDirectory + ", " + artifactFilter + ", " + offline + ", " + frozen + ")" } - protected[this] def copy(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration] = retrieveManaged, missingOk: Boolean = missingOk, logging: sbt.librarymanagement.UpdateLogging = logging, logicalClock: sbt.librarymanagement.LogicalClock = logicalClock, metadataDirectory: Option[java.io.File] = metadataDirectory, artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter] = artifactFilter, offline: Boolean = offline, frozen: Boolean = frozen): UpdateConfiguration = { + private[this] def copy(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration] = retrieveManaged, missingOk: Boolean = missingOk, logging: sbt.librarymanagement.UpdateLogging = logging, logicalClock: sbt.librarymanagement.LogicalClock = logicalClock, metadataDirectory: Option[java.io.File] = metadataDirectory, artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter] = artifactFilter, offline: Boolean = offline, frozen: Boolean = frozen): UpdateConfiguration = { new UpdateConfiguration(retrieveManaged, missingOk, logging, logicalClock, metadataDirectory, artifactFilter, offline, frozen) } def withRetrieveManaged(retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration]): UpdateConfiguration = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 91da13639..5ad396e00 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -30,7 +30,7 @@ final class UpdateReport private ( override def toString: String = { "Update report:\n\t" + stats + "\n" + configurations.mkString } - protected[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { + private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { new UpdateReport(cachedDescriptor, configurations, stats, stamps) } def withCachedDescriptor(cachedDescriptor: java.io.File): UpdateReport = { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala index 408223e24..ef2b53738 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala @@ -22,7 +22,7 @@ final class UpdateStats private ( override def toString: String = { Seq("Resolve time: " + resolveTime + " ms", "Download time: " + downloadTime + " ms", "Download size: " + downloadSize + " bytes").mkString(", ") } - protected[this] def copy(resolveTime: Long = resolveTime, downloadTime: Long = downloadTime, downloadSize: Long = downloadSize, cached: Boolean = cached): UpdateStats = { + private[this] def copy(resolveTime: Long = resolveTime, downloadTime: Long = downloadTime, downloadSize: Long = downloadSize, cached: Boolean = cached): UpdateStats = { new UpdateStats(resolveTime, downloadTime, downloadSize, cached) } def withResolveTime(resolveTime: Long): UpdateStats = { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala index a0293ea63..b1d74e539 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -24,7 +24,7 @@ final class ExternalIvyConfiguration private ( override def toString: String = { "ExternalIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + baseDirectory + ", " + uri + ", " + extraResolvers + ")" } - protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, baseDirectory: Option[java.io.File] = baseDirectory, uri: Option[java.net.URI] = uri, extraResolvers: Vector[sbt.librarymanagement.Resolver] = extraResolvers): ExternalIvyConfiguration = { + private[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, baseDirectory: Option[java.io.File] = baseDirectory, uri: Option[java.net.URI] = uri, extraResolvers: Vector[sbt.librarymanagement.Resolver] = extraResolvers): ExternalIvyConfiguration = { new ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) } def withLock(lock: Option[xsbti.GlobalLock]): ExternalIvyConfiguration = { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index 1baa4aeb3..f6d920fdf 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -28,7 +28,7 @@ final class InlineIvyConfiguration private ( override def toString: String = { "InlineIvyConfiguration(" + lock + ", " + log + ", " + updateOptions + ", " + paths + ", " + resolvers + ", " + otherResolvers + ", " + moduleConfigurations + ", " + checksums + ", " + managedChecksums + ", " + resolutionCacheDir + ")" } - protected[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, paths: Option[sbt.librarymanagement.ivy.IvyPaths] = paths, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration] = moduleConfigurations, checksums: Vector[String] = checksums, managedChecksums: Boolean = managedChecksums, resolutionCacheDir: Option[java.io.File] = resolutionCacheDir): InlineIvyConfiguration = { + private[this] def copy(lock: Option[xsbti.GlobalLock] = lock, log: Option[xsbti.Logger] = log, updateOptions: sbt.librarymanagement.ivy.UpdateOptions = updateOptions, paths: Option[sbt.librarymanagement.ivy.IvyPaths] = paths, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, moduleConfigurations: Vector[sbt.librarymanagement.ModuleConfiguration] = moduleConfigurations, checksums: Vector[String] = checksums, managedChecksums: Boolean = managedChecksums, resolutionCacheDir: Option[java.io.File] = resolutionCacheDir): InlineIvyConfiguration = { new InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) } def withLock(lock: Option[xsbti.GlobalLock]): InlineIvyConfiguration = { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index 562419c40..e1a8e41f0 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -20,7 +20,7 @@ final class IvyPaths private ( override def toString: String = { "IvyPaths(" + baseDirectory + ", " + ivyHome + ")" } - protected[this] def copy(baseDirectory: java.io.File = baseDirectory, ivyHome: Option[java.io.File] = ivyHome): IvyPaths = { + private[this] def copy(baseDirectory: java.io.File = baseDirectory, ivyHome: Option[java.io.File] = ivyHome): IvyPaths = { new IvyPaths(baseDirectory, ivyHome) } def withBaseDirectory(baseDirectory: java.io.File): IvyPaths = { diff --git a/project/plugins.sbt b/project/plugins.sbt index d2c95eb4c..2cec48aed 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.3") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0") scalacOptions += "-language:postfixOps" From e0eb46a99e91faaee742a49aca7d0fe93de73ad8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 26 Mar 2018 22:50:03 -0400 Subject: [PATCH 0752/1030] sbt 1.1.2 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 31334bbd3..05313438a 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.1 +sbt.version=1.1.2 From a14b53da5b7d3468993ff3a6071da6db9b4b3c3e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 26 Mar 2018 22:50:41 -0400 Subject: [PATCH 0753/1030] bump to 1.1.5-SNAPSHOT --- build.sbt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 15b9d73b0..4db20753e 100644 --- a/build.sbt +++ b/build.sbt @@ -30,7 +30,7 @@ def commonSettings: Seq[Setting[_]] = Seq( val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", - "1.1.0", "1.1.1", "1.1.2", "1.1.3", + "1.1.0", "1.1.1", "1.1.2", "1.1.3", "1.1.4", ) map (version => organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) @@ -50,10 +50,10 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile in Sbt := false, - git.baseVersion := "1.1.3", + git.baseVersion := "1.1.5", version := { val v = version.value - if (v contains "SNAPSHOT") git.baseVersion.value + if (v contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" else v } )), From 79e31a3e0f0a4b1c8a19517561f40c6dc0feeb34 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 3 Apr 2018 17:48:26 +0100 Subject: [PATCH 0754/1030] Allow pre-release versions to be compatible with normal versions --- .../sbt/librarymanagement/VersionNumber.scala | 27 +++++-------------- .../librarymanagement/VersionNumberSpec.scala | 12 ++++----- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index fa4f1f35f..aa13161d1 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -129,41 +129,27 @@ object VersionNumber { * Rule 2 we enforce with custom extractors. * Rule 4 we enforce by matching x = 0 & fully equals checking the two versions * Rule 6, 7 & 8 means version compatibility is determined by comparing the two X values - * Rule 9 means pre-release versions are fully equals checked */ def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { - case (NormalVersion(0, _, _), NormalVersion(0, _, _)) => v1 == v2 // R4 - case (NormalVersion(x1, _, _), NormalVersion(x2, _, _)) => x1 == x2 // R6, R7 & R8 - case (PrereleaseVersion(_, _, _), PrereleaseVersion(_, _, _)) => v1 == v2 // R9 - case _ => false + case (NormalVersion(0, _, _), NormalVersion(0, _, _)) => v1 == v2 // R4 + case (NormalVersion(x1, _, _), NormalVersion(x2, _, _)) => x1 == x2 // R6, R7 & R8 + case _ => false } // SemVer Spec Rule 10 (above) private[VersionNumber] def dropBuildMetadata(v: VersionNumber) = if (v.extras.isEmpty) v else VersionNumber(v.numbers, v.tags, Nil) - // SemVer Spec Rule 9 (above) - private[VersionNumber] def isPrerelease(v: VersionNumber): Boolean = v.tags.nonEmpty - // An extractor for SemVer's "normal version number" - SemVer Spec Rule 2 & Rule 9 (above) private[VersionNumber] object NormalVersion { def unapply(v: VersionNumber): Option[(Long, Long, Long)] = PartialFunction.condOpt(v.numbers) { // NOTE! We allow the z to be missing, because of legacy like commons-io 1.3 - case Seq(x, y, _*) if !isPrerelease(v) => (x, y, v._3 getOrElse 0) - } - } - - // An extractor for SemVer's "pre-release versions" - SemVer Spec Rule 2 & Rule 9 (above) - private[VersionNumber] object PrereleaseVersion { - def unapply(v: VersionNumber): Option[(Long, Long, Long)] = - PartialFunction.condOpt(v.numbers) { - // NOTE! We allow the z to be missing, because of legacy like commons-io 1.3 - case Seq(x, y, _*) if isPrerelease(v) => (x, y, v._3 getOrElse 0) + case Seq(x, y, _*) => (x, y, v._3 getOrElse 0) } } } @@ -182,9 +168,8 @@ object VersionNumber { private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = { (v1, v2) match { - case (NormalVersion(x1, y1, _), NormalVersion(x2, y2, _)) => (x1 == x2) && (y1 == y2) - case (PrereleaseVersion(_, _, _), PrereleaseVersion(_, _, _)) => v1 == v2 // R2 & R9 - case _ => false + case (NormalVersion(x1, y1, _), NormalVersion(x2, y2, _)) => (x1 == x2) && (y1 == y2) + case _ => false } } } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index dee74c35b..6401f386d 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -26,12 +26,12 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsCompatibleWith(v, "1.0.1", SemVer) assertIsCompatibleWith(v, "1.1.1", SemVer) assertIsNotCompatibleWith(v, "2.0.0", SemVer) - assertIsNotCompatibleWith(v, "1.0.0-M1", SemVer) + assertIsCompatibleWith(v, "1.0.0-M1", SemVer) assertIsCompatibleWith(v, "1.0.1", SecondSegment) assertIsNotCompatibleWith(v, "1.1.1", SecondSegment) assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) - assertIsNotCompatibleWith(v, "1.0.0-M1", SecondSegment) + assertIsCompatibleWith(v, "1.0.0-M1", SecondSegment) } version("1.0.0.0") { v => @@ -49,9 +49,9 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "0.12.1", SemVer) assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer) - assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment) + assertIsCompatibleWith(v, "0.12.0-RC1", SecondSegment) assertIsCompatibleWith(v, "0.12.1", SecondSegment) - assertIsNotCompatibleWith(v, "0.12.1-M1", SecondSegment) + assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment) } version("0.1.0-SNAPSHOT") { v => @@ -63,7 +63,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer) assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SecondSegment) - assertIsNotCompatibleWith(v, "0.1.0", SecondSegment) + assertIsCompatibleWith(v, "0.1.0", SecondSegment) assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SecondSegment) } @@ -85,7 +85,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { version("2.10.4-20140115-000117-b3a-sources") { v => assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) - assertIsNotCompatibleWith(v, "2.0.0", SemVer) + assertIsCompatibleWith(v, "2.0.0", SemVer) assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) } From f74ec0669965345d1a170a1b9199187200215726 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 5 Apr 2018 14:36:35 +0100 Subject: [PATCH 0755/1030] Change semantics to match previous semantics We're unsure about SemVer's semantics around pre-releases, so for now we just revert this refactoring to preserve the semantics it's always had. --- .../main/scala/sbt/librarymanagement/VersionNumber.scala | 5 +++++ .../scala/sbt/librarymanagement/VersionNumberSpec.scala | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index aa13161d1..bee13b8f9 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -129,6 +129,9 @@ object VersionNumber { * Rule 2 we enforce with custom extractors. * Rule 4 we enforce by matching x = 0 & fully equals checking the two versions * Rule 6, 7 & 8 means version compatibility is determined by comparing the two X values + * Rule 9.. + * Dale thinks means pre-release versions are fully equals checked.. + * Eugene thinks means pre-releases before 1.0.0 are not compatible, if not they are.. */ def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) @@ -136,6 +139,7 @@ object VersionNumber { private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = (v1, v2) match { case (NormalVersion(0, _, _), NormalVersion(0, _, _)) => v1 == v2 // R4 + case (NormalVersion(_, 0, 0), NormalVersion(_, 0, 0)) => v1 == v2 // R9 maybe? case (NormalVersion(x1, _, _), NormalVersion(x2, _, _)) => x1 == x2 // R6, R7 & R8 case _ => false } @@ -168,6 +172,7 @@ object VersionNumber { private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = { (v1, v2) match { + case (NormalVersion(_, _, 0), NormalVersion(_, _, 0)) => v1 == v2 // R9 maybe? case (NormalVersion(x1, y1, _), NormalVersion(x2, y2, _)) => (x1 == x2) && (y1 == y2) case _ => false } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 6401f386d..eab52f6c9 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -26,12 +26,12 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsCompatibleWith(v, "1.0.1", SemVer) assertIsCompatibleWith(v, "1.1.1", SemVer) assertIsNotCompatibleWith(v, "2.0.0", SemVer) - assertIsCompatibleWith(v, "1.0.0-M1", SemVer) + assertIsNotCompatibleWith(v, "1.0.0-M1", SemVer) assertIsCompatibleWith(v, "1.0.1", SecondSegment) assertIsNotCompatibleWith(v, "1.1.1", SecondSegment) assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) - assertIsCompatibleWith(v, "1.0.0-M1", SecondSegment) + assertIsNotCompatibleWith(v, "1.0.0-M1", SecondSegment) } version("1.0.0.0") { v => @@ -49,7 +49,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "0.12.1", SemVer) assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer) - assertIsCompatibleWith(v, "0.12.0-RC1", SecondSegment) + assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment) assertIsCompatibleWith(v, "0.12.1", SecondSegment) assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment) } @@ -63,7 +63,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer) assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SecondSegment) - assertIsCompatibleWith(v, "0.1.0", SecondSegment) + assertIsNotCompatibleWith(v, "0.1.0", SecondSegment) assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SecondSegment) } From 13807179ae15c1bd37e9ca626a0b6671737ed329 Mon Sep 17 00:00:00 2001 From: OlegYch Date: Sat, 7 Apr 2018 21:59:32 +0300 Subject: [PATCH 0756/1030] windows compatibility (due to contraband) --- build.sbt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/build.sbt b/build.sbt index 4db20753e..0bdf600eb 100644 --- a/build.sbt +++ b/build.sbt @@ -2,6 +2,11 @@ import Dependencies._ import Path._ import com.typesafe.tools.mima.core._, ProblemFilters._ +val _ = { + sys.props += ("line.separator" -> "\n") + sys.props += ("file.separaror" -> "/") +} + def commonSettings: Seq[Setting[_]] = Seq( scalaVersion := scala212, // publishArtifact in packageDoc := false, From 58bb203858fc85fd687483bd0c49d31cf38aa2a7 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 8 Apr 2018 14:36:41 +1000 Subject: [PATCH 0757/1030] Upgrade to latest sbt-houserules --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 2cec48aed..7c698418b 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.5") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.6") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0") scalacOptions += "-language:postfixOps" From bbb2ef3977b54dee4eb8fb20fa55f0a1a1bcfa21 Mon Sep 17 00:00:00 2001 From: OlegYch Date: Sat, 7 Apr 2018 23:27:08 +0300 Subject: [PATCH 0758/1030] fix retrieving deps via sftp resolver --- build.sbt | 2 +- .../librarymanagement/ConvertResolver.scala | 18 ++++++-- .../librarymanagement/SftpRepoSpec.scala | 42 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala diff --git a/build.sbt b/build.sbt index 0bdf600eb..4e812dccd 100644 --- a/build.sbt +++ b/build.sbt @@ -3,8 +3,8 @@ import Path._ import com.typesafe.tools.mima.core._, ProblemFilters._ val _ = { + //https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") - sys.props += ("file.separaror" -> "/") } def commonSettings: Seq[Setting[_]] = Seq( diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index cc13ea745..41a571c37 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -7,7 +7,7 @@ import java.net.URL import java.util.Collections import org.apache.ivy.core.module.descriptor.DependencyDescriptor -import org.apache.ivy.core.resolve.ResolveData +import org.apache.ivy.core.resolve.{ DownloadOptions, ResolveData } import org.apache.ivy.core.settings.IvySettings import org.apache.ivy.plugins.repository.{ RepositoryCopyProgressListener, Resource, TransferEvent } import org.apache.ivy.plugins.resolver.{ @@ -30,6 +30,7 @@ import java.io.{ File, IOException } import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } +import org.apache.ivy.core.report.DownloadReport import sbt.io.IO import sbt.util.Logger import sbt.librarymanagement._ @@ -181,7 +182,7 @@ private[sbt] object ConvertResolver { resolver } case repo: SshRepository => { - val resolver = new SshResolver with DescriptorRequired { + val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { override val managedChecksumsEnabled: Boolean = managedChecksums override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } @@ -190,7 +191,7 @@ private[sbt] object ConvertResolver { resolver } case repo: SftpRepository => { - val resolver = new SFTPResolver + val resolver = new SFTPResolver with ThreadSafeSshBasedResolver initializeSSHResolver(resolver, repo, settings) resolver } @@ -406,4 +407,15 @@ private[sbt] object ConvertResolver { } } } + + private sealed trait ThreadSafeSshBasedResolver + extends org.apache.ivy.plugins.resolver.AbstractSshBasedResolver { +//uncomment to test non-threadsafe behavior +// private def lock = new Object + private val lock = org.apache.ivy.plugins.repository.ssh.SshCache.getInstance + override def download(artifacts: Array[IArtifact], options: DownloadOptions): DownloadReport = + lock.synchronized { + super.download(artifacts, options) + } + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala new file mode 100644 index 000000000..8da14644a --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -0,0 +1,42 @@ +package sbt.internal.librarymanagement + +import sbt.io._ +import sbt.io.syntax._ +import sbt.util.Level +import sbt.librarymanagement._ +import sbt.librarymanagement.syntax._ +import java.nio.file.Paths + +//by default this test is ignored +//to run this you need to change "repo" to point to some sftp repository which contains a dependency referring a dependency in same repo +//it will then attempt to authenticate via key file and fetch the dependency specified via "org" and "module" +class SftpRepoSpec extends BaseIvySpecification { + val repo: Option[String] = None +// val repo: Option[String] = Some("some repo") + //a dependency which depends on another in the repo + def org(repo: String) = s"com.${repo}" + def module(org: String) = org % "some-lib" % "version" + + override def resolvers = { + implicit val patterns = Resolver.defaultIvyPatterns + repo.map { repo => + val privateKeyFile = Paths.get(sys.env("HOME"), ".ssh", s"id_${repo}").toFile + Resolver.sftp(repo, s"repo.${repo}.com", 2222).as(repo, privateKeyFile) + }.toVector ++ super.resolvers + } + + "resolving multiple deps from sftp repo" should "not hang or fail" in { + repo match { + case Some(repo) => + IO.delete(currentTarget / "cache" / org(repo)) + // log.setLevel(Level.Debug) + lmEngine().retrieve(module(org(repo)), scalaModuleInfo = None, currentTarget, log) match { + case Right(v) => log.debug(v.toString()) + case Left(e) => + log.log(Level.Error, e.failedPaths.toString()) + throw e.resolveException + } + case None => log.info(s"skipped ${getClass}") + } + } +} From 3b6df7d1059bfbab3f9cd9c417fd767bc1dbfee2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 28 Apr 2018 03:58:44 -0400 Subject: [PATCH 0759/1030] Scala 2.12.6 and other dependencies sbt 1.1.4 Scala 2.12.6 ScalaCheck 1.14.0 ScalaTest 3.0.5 --- project/Dependencies.scala | 6 +++--- project/build.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 61b8756e8..a428e71c0 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala211 = "2.11.12" - val scala212 = "2.12.4" + val scala212 = "2.12.6" private val ioVersion = "1.1.3" private val utilVersion = "1.1.3" @@ -45,8 +45,8 @@ object Dependencies { val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") - val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" % Test - val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" % Test + val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5" % Test + val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" % Test val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value } diff --git a/project/build.properties b/project/build.properties index 05313438a..64cf32f7f 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.2 +sbt.version=1.1.4 From 4d3818f9f70722642bb01572e7a0e584a5f4fe07 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Thu, 3 May 2018 23:03:44 +0900 Subject: [PATCH 0760/1030] use foldLeft instead of /: https://github.com/scala/scala/blob/02776afa797fdf320dfefbaeb4b70431ee085b25/src/library/scala/collection/IterableOnce.scala#L465 --- .../main/scala/sbt/librarymanagement/ConflictWarning.scala | 2 +- ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala | 2 +- .../ivyint/CachedResolutionResolveEngine.scala | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index 02355408f..5fea69f37 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -49,7 +49,7 @@ object ConflictWarning { if (differentFullNames.size > 1) differentFullNames else Set.empty[String] } } - (Map.empty[(String, String), Set[String]] /: mismatches)(merge) + mismatches.foldLeft(Map.empty[(String, String), Set[String]])(merge) } private[this] def merge[A, B](m: Map[A, Set[B]], b: (A, Set[B])): Map[A, Set[B]] = if (b._2.isEmpty) m diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 5a257844e..b50914ea9 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -774,7 +774,7 @@ private[sbt] object IvySbt { elem: scala.xml.Elem, extra: Map[String, String] ): scala.xml.Elem = - (elem /: extra) { + extra.foldLeft(elem) { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index d2d8086ba..cf24d61d3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -957,9 +957,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }: _*) // This emulates test-internal extending test configuration etc. val remappedConfigs: Map[String, Vector[String]] = - (remappedConfigs0 /: rootModuleConfs) { (acc0, c) => + rootModuleConfs.foldLeft(remappedConfigs0) { (acc0, c) => val ps = parentConfigs(c.getName) - (acc0 /: ps) { (acc, parent) => + ps.foldLeft(acc0) { (acc, parent) => val vs0 = acc.getOrElse(c.getName, Vector()) val vs = acc.getOrElse(parent, Vector()) acc.updated(c.getName, (vs0 ++ vs).distinct) From c0c88eda9f150c854c802aff3b35f3fd09379dab Mon Sep 17 00:00:00 2001 From: tanishiking24 Date: Sun, 6 May 2018 17:48:52 +0900 Subject: [PATCH 0761/1030] Add semantic version number selector API. This semantic version number selector API is based on - https://draftin.com/documents/375100?token=rR30GmJJzi4l3BRlD-cHs8lcAcdDAXH4oTzqOWeL0CT0BNv3PZEx0g8pBkI13sQgYXTBqShZ0Ucsqek3Fn3d-aU - https://docs.npmjs.com/misc/semver --- .../librarymanagement/SemanticSelector.scala | 259 ++++++++++++++ .../sbt/librarymanagement/VersionNumber.scala | 4 + .../SemanticSelectorSpec.scala | 315 ++++++++++++++++++ 3 files changed, 578 insertions(+) create mode 100644 core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala create mode 100644 core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala diff --git a/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala new file mode 100644 index 000000000..b728c939a --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala @@ -0,0 +1,259 @@ +package sbt.librarymanagement + +/** + * Semantic version selector API to check if the VersionNumber satisfies + * conditions described by semantic version selector. + */ +sealed abstract case class SemanticSelector( + private val selectors: Seq[SemanticSelector.SemSelAndChunk]) { + + /** + * Check if the version number satisfies the conditions described by semantic version selector. + * + * The empty fields of the version number are assumed to be 0, for example, `1` is treated as `1.0.0`. + * + * @param versionNumber The Version Number to be checked if it satisfies the conditions. + * @return The result of checking the version number satisfies the conditions or not. + */ + def matches(versionNumber: VersionNumber): Boolean = { + selectors.exists(_.matches(versionNumber)) + } + override def toString: String = selectors.map(_.toString).mkString(" || ") +} +object SemanticSelector { + + /** + * Build a SemanticSelector that can match specific semantic versions. + * + * A `comparator` generally consist of an operator and version specifier. + * The set of operators is + * - `<`: Less than + * - `<=`: Less than or equal to + * - `>`: Greater than + * - `>=`: Greater than or equal to + * - `=`: Equal + * If no operator is specified, `=` is assumed. + * + * If minor or patch versions are not specified, some numbers are assumed. + * - `<=1.0` is equivalent to `<1.1.0`. + * - `<1.0` is equivalent to `<1.0.0`. + * - `>=1.0` is equivalent to `>=1.0.0`. + * - `>1.0` is equivalent to `>=1.1.0`. + * - `=1.0` is equivalent to `>=1.0 <=1.0` (so `>=1.0.0 <1.1.0`). + * + * Comparators can be combined by spaces to form the intersection set of the comparators. + * For example, `>1.2.3 <4.5.6` matches versions that are `greater than 1.2.3 AND less than 4.5.6`. + * + * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the + * union set of the intersection sets. So the semantic selector is in disjunctive normal form. + * + * Metadata and pre-release of VersionNumber are ignored. + * So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version + * or any metadata like `1.0.0-alpha`, `1.0.0+metadata`. + * + * Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version. + * Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`) + * + * The hyphen range like `1.2.3 - 4.5.6` matches inclusive set of versions. + * So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`. + * Both sides of comparators around - are required and they can not have any operators. + * For example, `>=1.2.3 - 4.5.6` is invalid. + * + * @param selector A string that represents semantic version selector. + * @return A `SemanticSelector` that can match only onto specific semantic versions. + * @throws java.lang.IllegalAccessException when selector is in invalid format of semantic version selector. + */ + def apply(selector: String): SemanticSelector = { + val orChunkTokens = selector.split("\\s+\\|\\|\\s+").map(_.trim) + val orChunks = orChunkTokens.map { chunk => + SemSelAndChunk(chunk) + } + new SemanticSelector(orChunks) {} + } + + private[this] sealed trait SemSelOperator + private[this] case object Lte extends SemSelOperator { + override def toString: String = "<=" + } + private[this] case object Lt extends SemSelOperator { + override def toString: String = "<" + } + private[this] case object Gte extends SemSelOperator { + override def toString: String = ">=" + } + private[this] case object Gt extends SemSelOperator { + override def toString: String = ">" + } + private[this] case object Eq extends SemSelOperator { + override def toString: String = "=" + } + + private[SemanticSelector] final case class SemSelAndChunk(comparators: Seq[SemComparator]) { + def matches(version: VersionNumber): Boolean = { + comparators.forall(_.matches(version)) + } + override def toString: String = comparators.map(_.toString).mkString(" ") + } + private[SemanticSelector] object SemSelAndChunk { + def apply(andClauseToken: String): SemSelAndChunk = parse(andClauseToken) + private[this] def parse(andClauseToken: String): SemSelAndChunk = { + val comparatorTokens = andClauseToken.split("\\s+") + val hyphenIndex = comparatorTokens.indexWhere(_ == "-") + val comparators = if (hyphenIndex == -1) { + comparatorTokens.map(SemComparator.apply) + } else { + // interpret `A.B.C - D.E.F` to `>=A.B.C <=D.E.F` + val (before, after) = comparatorTokens.splitAt(hyphenIndex) + (before.lastOption, after.drop(1).headOption) match { + case (Some(fromStr), Some(toStr)) => + // from and to can not have an operator. + if (hasOperator(fromStr) || hasOperator(toStr)) { + throw new IllegalArgumentException( + s"Invalid ' - ' range, both side of comparators can not have an operator: $fromStr - $toStr") + } + val from = SemComparator(fromStr) + val to = SemComparator(toStr) + val comparatorsBefore = before.dropRight(1).map(SemComparator.apply) + val comparatorsAfter = after.drop(2) match { + case tokens if !tokens.isEmpty => + parse(tokens.mkString(" ")).comparators + case _ => Seq.empty + } + from.copy(op = Gte) +: + to.copy(op = Lte) +: + (comparatorsBefore ++ comparatorsAfter) + case _ => + throw new IllegalArgumentException( + s"Invalid ' - ' range position, both side of versions must be specified: $andClauseToken") + } + } + SemSelAndChunk(comparators.flatMap(_.expandWildcard)) + } + + private[this] def hasOperator(comparator: String): Boolean = { + comparator.startsWith("<") || + comparator.startsWith(">") || + comparator.startsWith("=") + } + } + + private[SemanticSelector] final case class SemComparator private ( + op: SemSelOperator, + major: Option[Long], + minor: Option[Long], + patch: Option[Long] + ) { + def matches(version: VersionNumber): Boolean = { + // Fill empty fields of version specifier with 0 or max value of Long. + // By filling them, SemComparator realize the properties below + // `<=1.0` is equivalent to `<1.1.0` (`<=1.0.${Long.MaxValue}`) + // `<1.0` is equivalent to `<1.0.0` + // `>=1.0` is equivalent to `>=1.0.0` + // `>1.0` is equivalent to `>=1.1.0` (`>1.0.${Long.MaxValue}`) + // + // However this fills 0 for a comparator that have `=` operator, + // a comparator that have empty part of version and `=` operator won't appear + // because of expanding it to and clause of comparators. + val assumed = op match { + case Lte => Long.MaxValue + case Lt => 0L + case Gte => 0L + case Gt => Long.MaxValue + case Eq => 0L + } + // empty fields of the version number are assumed to be 0. + val versionNumber = + (version._1.getOrElse(0L), version._2.getOrElse(0L), version._3.getOrElse(0L)) + val selector = (major.getOrElse(assumed), minor.getOrElse(assumed), patch.getOrElse(assumed)) + val cmp = implicitly[Ordering[(Long, Long, Long)]].compare(versionNumber, selector) + op match { + case Lte if cmp <= 0 => true + case Lt if cmp < 0 => true + case Gte if cmp >= 0 => true + case Gt if cmp > 0 => true + case Eq if cmp == 0 => true + case _ => false + } + } + + // Expand wildcard with `=` operator to and clause of comparators. + // `=1.0` is equivalent to `>=1.0 <=1.0` + def expandWildcard: Seq[SemComparator] = { + if (op == Eq && !allFieldsSpecified) { + Seq(this.copy(op = Gte), this.copy(op = Lte)) + } else { + Seq(this) + } + } + private[this] def allFieldsSpecified: Boolean = + major.isDefined && minor.isDefined && patch.isDefined + + override def toString: String = { + val versionStr = Seq(major, minor, patch) + .collect { + case Some(v) => v.toString + } + .mkString(".") + s"$op$versionStr" + } + } + private[SemanticSelector] object SemComparator { + def apply(comparator: String): SemComparator = parse(comparator) + private[this] val ComparatorRegex = """(?x)^ + ([<>]=?|=)? + (?:(\d+|[xX*]) + (?:\.(\d+|[xX*]) + (?:\.(\d+|[xX*]))? + )? + )$ + """.r + private[this] def parse(comparator: String): SemComparator = { + comparator match { + case ComparatorRegex(rawOp, rawMajor, rawMinor, rawPatch) => + val opStr = Option(rawOp) + val major = Option(rawMajor) + val minor = Option(rawMinor) + val patch = Option(rawPatch) + + // Trim wildcard(x, X, *) and re-parse it. + // By trimming it, comparator realize the property like + // `=1.2.x` is equivalent to `=1.2`. + val hasXrangeSelector = Seq(major, minor, patch).exists { + case Some(str) => str.matches("[xX*]") + case None => false + } + if (hasXrangeSelector) { + val numbers = Seq(major, minor, patch).takeWhile { + case Some(str) => str.matches("\\d+") + case None => false + } + parse( + numbers + .collect { + case Some(v) => v.toString + } + .mkString(".") + ) + } else { + val operator = opStr match { + case Some("<") => Lt + case Some("<=") => Lte + case Some(">") => Gt + case Some(">=") => Gte + case Some("=") => Eq + case None => Eq + case Some(_) => + throw new IllegalArgumentException(s"Invalid operator: $opStr") + } + SemComparator( + operator, + major.map(_.toLong), + minor.map(_.toLong), + patch.map(_.toLong) + ) + } + case _ => throw new IllegalArgumentException(s"Invalid comparator: $comparator") + } + } + } +} diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index bee13b8f9..102d468c3 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -27,6 +27,10 @@ final class VersionNumber private[sbt] ( case _ => false } + def satisfies(selector: String): Boolean = { + SemanticSelector(selector).matches(this) + } + /** A variant of mkString that returns the empty string if the sequence is empty. */ private[this] def mkString1[A](xs: Seq[A], start: String, sep: String, end: String): String = if (xs.isEmpty) "" else xs.mkString(start, sep, end) diff --git a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala new file mode 100644 index 000000000..4a33d45c5 --- /dev/null +++ b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala @@ -0,0 +1,315 @@ +package sbt.librarymanagement + +import org.scalatest.{ FreeSpec, Matchers } + +class SemanticSelectorSpec extends FreeSpec with Matchers { + semsel("<=1.2.3") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta") + assertMatches(sel, "1.2") + assertMatches(sel, "1") + assertNotMatches(sel, "1.2.4") + assertNotMatches(sel, "1.3") + assertNotMatches(sel, "1.3.0") + assertNotMatches(sel, "2") + } + + semsel("<=1.2") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta") + assertMatches(sel, "1.2") + assertMatches(sel, "1") + assertNotMatches(sel, "1.3.0") + } + + semsel("<=1") { sel => + assertMatches(sel, "1.12.12") + assertMatches(sel, "1.12.12-alpha") + assertMatches(sel, "1.2") + assertNotMatches(sel, "2.0.0") + assertNotMatches(sel, "2.0.0-alpha") + } + + semsel("<1.2.3") { sel => + assertMatches(sel, "1.2.2") + assertMatches(sel, "1.2") + assertNotMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2.3") + } + + semsel("<1.2") { sel => + assertMatches(sel, "1.1.23") + assertMatches(sel, "1.1") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1.2.0-alpha") + } + + semsel("<1") { sel => + assertMatches(sel, "0.9.12") + assertMatches(sel, "0.8") + assertNotMatches(sel, "1") + assertNotMatches(sel, "1.0") + assertNotMatches(sel, "1.0.0") + } + + semsel(">=1.2.3") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta") + assertMatches(sel, "1.3") + assertMatches(sel, "2") + assertNotMatches(sel, "1.2.2") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1") + } + + semsel(">=1.2") { sel => + assertMatches(sel, "1.2.0") + assertMatches(sel, "1.2.0-beta") + assertMatches(sel, "1.2") + assertMatches(sel, "2") + assertNotMatches(sel, "1.1.23") + assertNotMatches(sel, "1.1") + assertNotMatches(sel, "1") + } + + semsel(">=1") { sel => + assertMatches(sel, "1.0.0") + assertMatches(sel, "1.0.0-beta") + assertMatches(sel, "1.0") + assertMatches(sel, "1") + assertNotMatches(sel, "0.9.9") + assertNotMatches(sel, "0.1") + assertNotMatches(sel, "0") + } + + semsel(">1.2.3") { sel => + assertMatches(sel, "1.2.4") + assertMatches(sel, "1.2.4-alpha") + assertMatches(sel, "1.3") + assertMatches(sel, "2") + assertNotMatches(sel, "1.2.3") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1") + } + + semsel(">1.2") { sel => + assertMatches(sel, "1.3.0") + assertMatches(sel, "1.3.0-alpha") + assertMatches(sel, "1.3") + assertMatches(sel, "2") + assertNotMatches(sel, "1.2.9") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1") + } + + semsel(">1") { sel => + assertMatches(sel, "2.0.0") + assertMatches(sel, "2.0") + assertMatches(sel, "2") + assertNotMatches(sel, "1.2.3") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1") + } + + semsel("1.2.3") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1.2.4") + } + + Seq(".x", ".X", ".*", ".x.x", "").foreach { xrange => + semsel(s"1$xrange") { sel => + assertMatches(sel, "1.0.0") + assertMatches(sel, "1.0.1") + assertMatches(sel, "1.1.1") + assertMatches(sel, "1.0.0-alpha") + assertNotMatches(sel, "2.0.0") + assertNotMatches(sel, "0.1.0") + } + } + + Seq(".x", ".X", ".*", "").foreach { xrange => + semsel(s"1.2$xrange") { sel => + assertMatches(sel, "1.2.0") + assertMatches(sel, "1.2.0-beta") + assertMatches(sel, "1.2.3") + assertNotMatches(sel, "1.3.0") + assertNotMatches(sel, "1.1.1") + } + } + + semsel("=1.2.3") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "1.2.4") + } + semsel("=1.2") { sel => + assertMatches(sel, "1.2.0") + assertMatches(sel, "1.2.0-alpha") + assertMatches(sel, "1.2") + assertMatches(sel, "1.2.1") + assertMatches(sel, "1.2.4") + } + semsel("=1") { sel => + assertMatches(sel, "1.0.0") + assertMatches(sel, "1.0.0-alpha") + assertMatches(sel, "1.0") + assertMatches(sel, "1.0.1") + assertMatches(sel, "1.2.3") + } + semsel("1.2.3 || 2.0.0") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "2.0.0") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "2.0.1") + } + semsel("<=1.2.3 || >=2.0.0 || 1.3.x") { sel => + assertMatches(sel, "1.0") + assertMatches(sel, "1.2.3") + assertMatches(sel, "2.0.0") + assertMatches(sel, "2.0") + assertMatches(sel, "1.3.0") + assertMatches(sel, "1.3.3") + assertNotMatches(sel, "1.2.4") + assertNotMatches(sel, "1.4.0") + } + + semsel(">=1.2.3 <2.0.0") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.9.9") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "2.0.0") + } + + semsel(">=1.2.3 <2.0.0 || >3.0.0 <=3.2.0") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.9.9") + assertMatches(sel, "3.0.1") + assertMatches(sel, "3.2.0") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "2.0.0") + assertNotMatches(sel, "3.0.0") + assertNotMatches(sel, "3.2.1") + } + + semsel("1.2.3 - 2.0.0") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.9.9") + assertMatches(sel, "2.0.0") + assertNotMatches(sel, "1.2") + assertNotMatches(sel, "2.0.1") + } + semsel("1.2 - 2") { sel => + assertMatches(sel, "1.2.0") + assertMatches(sel, "1.9.9") + assertMatches(sel, "2.0.0") + assertMatches(sel, "2.0.1") + assertNotMatches(sel, "1.1") + assertNotMatches(sel, "3.0.0") + } + semsel("1.2.3 - 2.0.0 1.5.0 - 2.4.0") { sel => + assertMatches(sel, "1.5.0") + assertMatches(sel, "1.9.9") + assertMatches(sel, "2.0.0") + assertNotMatches(sel, "1.2.3") + assertNotMatches(sel, "1.4") + assertNotMatches(sel, "2.0.1") + assertNotMatches(sel, "2.4.0") + } + semsel("1.2.3 - 2.0 || 2.4.0 - 3") { sel => + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.5.0") + assertMatches(sel, "2.0.0") + assertMatches(sel, "2.4.0") + assertMatches(sel, "2.9") + assertMatches(sel, "3.0.0") + assertMatches(sel, "2.0.1") + assertMatches(sel, "3.0.1") + assertMatches(sel, "3.1.0") + assertNotMatches(sel, "2.1") + assertNotMatches(sel, "2.3.9") + assertNotMatches(sel, "4.0.0") + } + + semsel(">=1.x") { sel => + assertMatches(sel, "1.0.0") + assertMatches(sel, "1.0.0-beta") + assertMatches(sel, "1.0") + assertMatches(sel, "1") + assertNotMatches(sel, "0.9.9") + assertNotMatches(sel, "0.1") + assertNotMatches(sel, "0") + } + + Seq( + // invalid operator + "~1.2.3", + "<~1.2.3", + "+1.2.3", + "!1.0.0", + ">~1.2.3", + // too much version fields + "1.2.3.4", + "1.2.3.4.5", + "1.2.3.x", + // invalid version specifier + "string.!?", + "1.y", + "1.2x", + "1.1.c", + "-1", + "x", + "", + // || without spaces + "1.2.3|| 2.3.4", + "1.2.3 ||2.3.4", + "1.2.3||2.3.4", + // invalid - operator + "- 1.1.1", + "2.0.0 -", + "1.0.0 - 2.0.0 - 3.0.0", + ">=1.0.0 - 2.0.0", + "1.0.0 - =3.0.0", + "=1.0.0 - =3.0.0", + "1.0.0 - 2.0.0 || - 2.0.0", + "1.0.0- 2.0.0", + "1.0.0 -2.0.0", + "1.0.0-2.0.0", + "-", + // cannot specify pre-release or metadata + "1.2.3-alpha", + "1.2-alpha", + "1.2.3+meta" + ).foreach { selectorStr => + semsel(selectorStr) { sel => + assertParsesToError(sel) + } + } + + private[this] final class SemanticSelectorString(val value: String) + private[this] def semsel(s: String)(f: SemanticSelectorString => Unit): Unit = + s"""SemanticSelector "$s"""" - { + f(new SemanticSelectorString(s)) + } + + private[this] def assertMatches( + s: SemanticSelectorString, + v: String + ): Unit = s"""should match "$v"""" in { + SemanticSelector(s.value).matches(VersionNumber(v)) shouldBe true + } + + private[this] def assertNotMatches( + s: SemanticSelectorString, + v: String + ): Unit = s"""should not match "$v"""" in { + SemanticSelector(s.value).matches(VersionNumber(v)) shouldBe false + } + + private[this] def assertParsesToError(s: SemanticSelectorString): Unit = + s"""should parse as an error""" in { + an[IllegalArgumentException] should be thrownBy SemanticSelector(s.value) + } +} From f8efdb1ac2094bc1c8585009b02d5b45427cf880 Mon Sep 17 00:00:00 2001 From: tanishiking24 Date: Fri, 11 May 2018 02:15:43 +0900 Subject: [PATCH 0762/1030] Make semantic selector honor semver ordering around pre-release tags. - When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. Example: 1.0.0-alpha < 1.0.0. - Precedence for two pre-release versions with the same major, minor, and patch version MUST be determined by comparing each dot hyphen separated identifier from left to right until a difference is found as follows - identifiers consisting of only digits are compared numerically and identifiers with letters or hyphens are compared lexically in ASCII sort order. - Numeric identifiers always have lower precedence than non-numeric identifiers. - A larger set of pre-release fields has a higher precedence than a smaller set, if all of the preceding identifiers are equal. - Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. https://semver.org/#spec-item-11 --- .../librarymanagement/SemanticSelector.scala | 70 ++++++++++-- .../SemanticSelectorSpec.scala | 106 ++++++++++++++---- 2 files changed, 148 insertions(+), 28 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala index b728c939a..279f4fdd0 100644 --- a/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala +++ b/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala @@ -1,5 +1,7 @@ package sbt.librarymanagement +import scala.annotation.tailrec + /** * Semantic version selector API to check if the VersionNumber satisfies * conditions described by semantic version selector. @@ -43,9 +45,9 @@ object SemanticSelector { * * Comparators can be combined by spaces to form the intersection set of the comparators. * For example, `>1.2.3 <4.5.6` matches versions that are `greater than 1.2.3 AND less than 4.5.6`. - * - * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the - * union set of the intersection sets. So the semantic selector is in disjunctive normal form. + * + * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the + * union set of the intersection sets. So the semantic selector is in disjunctive normal form. * * Metadata and pre-release of VersionNumber are ignored. * So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version @@ -141,7 +143,8 @@ object SemanticSelector { op: SemSelOperator, major: Option[Long], minor: Option[Long], - patch: Option[Long] + patch: Option[Long], + tags: Seq[String] ) { def matches(version: VersionNumber): Boolean = { // Fill empty fields of version specifier with 0 or max value of Long. @@ -165,7 +168,11 @@ object SemanticSelector { val versionNumber = (version._1.getOrElse(0L), version._2.getOrElse(0L), version._3.getOrElse(0L)) val selector = (major.getOrElse(assumed), minor.getOrElse(assumed), patch.getOrElse(assumed)) - val cmp = implicitly[Ordering[(Long, Long, Long)]].compare(versionNumber, selector) + val normalVersionCmp = + implicitly[Ordering[(Long, Long, Long)]].compare(versionNumber, selector) + val cmp = + if (normalVersionCmp == 0) SemComparator.comparePreReleaseTags(version.tags, tags) + else normalVersionCmp op match { case Lte if cmp <= 0 => true case Lt if cmp < 0 => true @@ -194,7 +201,8 @@ object SemanticSelector { case Some(v) => v.toString } .mkString(".") - s"$op$versionStr" + val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" + s"$op$versionStr$tagsStr" } } private[SemanticSelector] object SemComparator { @@ -205,15 +213,16 @@ object SemanticSelector { (?:\.(\d+|[xX*]) (?:\.(\d+|[xX*]))? )? - )$ + )((?:-\w+)*)$ """.r private[this] def parse(comparator: String): SemComparator = { comparator match { - case ComparatorRegex(rawOp, rawMajor, rawMinor, rawPatch) => + case ComparatorRegex(rawOp, rawMajor, rawMinor, rawPatch, ts) => val opStr = Option(rawOp) val major = Option(rawMajor) val minor = Option(rawMinor) val patch = Option(rawPatch) + val tags = splitDash(ts) // Trim wildcard(x, X, *) and re-parse it. // By trimming it, comparator realize the property like @@ -223,6 +232,9 @@ object SemanticSelector { case None => false } if (hasXrangeSelector) { + if (tags.nonEmpty) + throw new IllegalArgumentException( + s"Pre-release version requires major, minor, patch versions to be specified: $comparator") val numbers = Seq(major, minor, patch).takeWhile { case Some(str) => str.matches("\\d+") case None => false @@ -235,6 +247,9 @@ object SemanticSelector { .mkString(".") ) } else { + if (tags.nonEmpty && (major.isEmpty || minor.isEmpty || patch.isEmpty)) + throw new IllegalArgumentException( + s"Pre-release version requires major, minor, patch versions to be specified: $comparator") val operator = opStr match { case Some("<") => Lt case Some("<=") => Lte @@ -249,11 +264,48 @@ object SemanticSelector { operator, major.map(_.toLong), minor.map(_.toLong), - patch.map(_.toLong) + patch.map(_.toLong), + tags ) } case _ => throw new IllegalArgumentException(s"Invalid comparator: $comparator") } } + private[this] def splitOn[A](s: String, sep: Char): Vector[String] = + if (s eq null) Vector() + else s.split(sep).filterNot(_ == "").toVector + private[this] def splitDash(s: String) = splitOn(s, '-') + + private[SemComparator] def comparePreReleaseTags(ts1: Seq[String], ts2: Seq[String]): Int = { + // > When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. + if (ts1.isEmpty && ts2.isEmpty) 0 + else if (ts1.nonEmpty && ts2.isEmpty) -1 // ts1 is pre-release version + else if (ts1.isEmpty && ts2.nonEmpty) 1 // ts2 is pre-release version + else compareTags(ts1, ts2) + } + + @tailrec + private[this] def compareTags(ts1: Seq[String], ts2: Seq[String]): Int = { + // > A larger set of pre-release fields has a higher precedence than a smaller set, + // > if all of the preceding identifiers are equal. + if (ts1.isEmpty && ts2.isEmpty) 0 + else if (ts1.nonEmpty && ts2.isEmpty) 1 + else if (ts1.isEmpty && ts2.nonEmpty) -1 + else { + val ts1head = ts1.head + val ts2head = ts2.head + val cmp = (ts1head.matches("\\d+"), ts2head.matches("\\d+")) match { + // Identifiers consisting of only digits are compared numerically. + // Numeric identifiers always have lower precedence than non-numeric identifiers. + // Identifiers with letters are compared case insensitive lexical order. + case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) + case (false, true) => 1 + case (true, false) => -1 + case (false, false) => ts1head.toLowerCase.compareTo(ts2head.toLowerCase) + } + if (cmp == 0) compareTags(ts1.tail, ts2.tail) + else cmp + } + } } } diff --git a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala index 4a33d45c5..f7bf4f5bf 100644 --- a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala @@ -5,9 +5,11 @@ import org.scalatest.{ FreeSpec, Matchers } class SemanticSelectorSpec extends FreeSpec with Matchers { semsel("<=1.2.3") { sel => assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2-beta") assertMatches(sel, "1.2.3-beta") assertMatches(sel, "1.2") assertMatches(sel, "1") + assertNotMatches(sel, "1.2.4-alpha") assertNotMatches(sel, "1.2.4") assertNotMatches(sel, "1.3") assertNotMatches(sel, "1.3.0") @@ -15,68 +17,89 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { } semsel("<=1.2") { sel => - assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.345-beta") assertMatches(sel, "1.2.3-beta") + assertMatches(sel, "1.2.3") assertMatches(sel, "1.2") assertMatches(sel, "1") assertNotMatches(sel, "1.3.0") + assertNotMatches(sel, "1.3.0-alpha") } semsel("<=1") { sel => - assertMatches(sel, "1.12.12") - assertMatches(sel, "1.12.12-alpha") - assertMatches(sel, "1.2") + assertMatches(sel, "1.234.567-alpha") + assertMatches(sel, "1.234.567") + assertMatches(sel, "1.234") + assertMatches(sel, "1.0.0-alpha") + assertMatches(sel, "1.0.0") + assertMatches(sel, "1.0") + assertMatches(sel, "1") assertNotMatches(sel, "2.0.0") assertNotMatches(sel, "2.0.0-alpha") } semsel("<1.2.3") { sel => + assertMatches(sel, "1.2.3-alpha") assertMatches(sel, "1.2.2") assertMatches(sel, "1.2") - assertNotMatches(sel, "1.2.3-alpha") + assertMatches(sel, "1") + assertNotMatches(sel, "1.2.4-beta") assertNotMatches(sel, "1.2.3") + assertNotMatches(sel, "1.3") + assertNotMatches(sel, "2") } semsel("<1.2") { sel => + assertMatches(sel, "1.2.0-alpha") assertMatches(sel, "1.1.23") assertMatches(sel, "1.1") + assertMatches(sel, "1") + assertNotMatches(sel, "1.3-beta") + assertNotMatches(sel, "1.2.0") assertNotMatches(sel, "1.2") - assertNotMatches(sel, "1.2.0-alpha") + assertNotMatches(sel, "2") } semsel("<1") { sel => + assertMatches(sel, "1.0.0-beta") + assertMatches(sel, "0.9.9-beta") assertMatches(sel, "0.9.12") assertMatches(sel, "0.8") + assertMatches(sel, "0") + assertNotMatches(sel, "1.0.1-beta") assertNotMatches(sel, "1") assertNotMatches(sel, "1.0") assertNotMatches(sel, "1.0.0") } semsel(">=1.2.3") { sel => + assertMatches(sel, "1.2.4-beta") assertMatches(sel, "1.2.3") - assertMatches(sel, "1.2.3-beta") assertMatches(sel, "1.3") assertMatches(sel, "2") + assertNotMatches(sel, "1.2.3-beta") assertNotMatches(sel, "1.2.2") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1") } semsel(">=1.2") { sel => + assertMatches(sel, "1.2.1-beta") assertMatches(sel, "1.2.0") - assertMatches(sel, "1.2.0-beta") assertMatches(sel, "1.2") assertMatches(sel, "2") + assertNotMatches(sel, "1.2.0-beta") assertNotMatches(sel, "1.1.23") assertNotMatches(sel, "1.1") assertNotMatches(sel, "1") } semsel(">=1") { sel => + assertMatches(sel, "1.0.1-beta") assertMatches(sel, "1.0.0") - assertMatches(sel, "1.0.0-beta") assertMatches(sel, "1.0") assertMatches(sel, "1") + assertNotMatches(sel, "1.0.0-beta") assertNotMatches(sel, "0.9.9") assertNotMatches(sel, "0.1") assertNotMatches(sel, "0") @@ -87,6 +110,7 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { assertMatches(sel, "1.2.4-alpha") assertMatches(sel, "1.3") assertMatches(sel, "2") + assertNotMatches(sel, "1.2.3-alpha") assertNotMatches(sel, "1.2.3") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1") @@ -97,15 +121,18 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { assertMatches(sel, "1.3.0-alpha") assertMatches(sel, "1.3") assertMatches(sel, "2") + assertNotMatches(sel, "1.2.0-alpha") assertNotMatches(sel, "1.2.9") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1") } semsel(">1") { sel => + assertMatches(sel, "2.0.0-alpha") assertMatches(sel, "2.0.0") assertMatches(sel, "2.0") assertMatches(sel, "2") + assertNotMatches(sel, "1.2.3-alpha") assertNotMatches(sel, "1.2.3") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1") @@ -113,17 +140,19 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { semsel("1.2.3") { sel => assertMatches(sel, "1.2.3") - assertMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2.3-alpha") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1.2.4") } Seq(".x", ".X", ".*", ".x.x", "").foreach { xrange => semsel(s"1$xrange") { sel => + assertMatches(sel, "1.2.3-alpha") assertMatches(sel, "1.0.0") assertMatches(sel, "1.0.1") assertMatches(sel, "1.1.1") - assertMatches(sel, "1.0.0-alpha") + assertNotMatches(sel, "1.0.0-alpha") + assertNotMatches(sel, "2.0.0-alpha") assertNotMatches(sel, "2.0.0") assertNotMatches(sel, "0.1.0") } @@ -132,8 +161,10 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { Seq(".x", ".X", ".*", "").foreach { xrange => semsel(s"1.2$xrange") { sel => assertMatches(sel, "1.2.0") - assertMatches(sel, "1.2.0-beta") assertMatches(sel, "1.2.3") + assertNotMatches(sel, "1.2.0-alpha") + assertNotMatches(sel, "1.2.0-beta") + assertNotMatches(sel, "1.3.0-beta") assertNotMatches(sel, "1.3.0") assertNotMatches(sel, "1.1.1") } @@ -141,23 +172,27 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { semsel("=1.2.3") { sel => assertMatches(sel, "1.2.3") - assertMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2.3-alpha") assertNotMatches(sel, "1.2") assertNotMatches(sel, "1.2.4") } semsel("=1.2") { sel => assertMatches(sel, "1.2.0") - assertMatches(sel, "1.2.0-alpha") assertMatches(sel, "1.2") assertMatches(sel, "1.2.1") assertMatches(sel, "1.2.4") + assertNotMatches(sel, "1.1.0") + assertNotMatches(sel, "1.3.0") + assertNotMatches(sel, "1.2.0-alpha") + assertNotMatches(sel, "1.3.0-alpha") } semsel("=1") { sel => assertMatches(sel, "1.0.0") - assertMatches(sel, "1.0.0-alpha") assertMatches(sel, "1.0") assertMatches(sel, "1.0.1") assertMatches(sel, "1.2.3") + assertNotMatches(sel, "1.0.0-alpha") + assertNotMatches(sel, "2.0.0") } semsel("1.2.3 || 2.0.0") { sel => assertMatches(sel, "1.2.3") @@ -235,14 +270,41 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { semsel(">=1.x") { sel => assertMatches(sel, "1.0.0") - assertMatches(sel, "1.0.0-beta") assertMatches(sel, "1.0") assertMatches(sel, "1") + assertNotMatches(sel, "1.0.0-beta") assertNotMatches(sel, "0.9.9") assertNotMatches(sel, "0.1") assertNotMatches(sel, "0") } + semsel(">=1.2.3-beta") { sel => + assertMatches(sel, "1.3-alpha") + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta") + assertMatches(sel, "1.2.3-beta-2") + assertMatches(sel, "1.2.3-beta-gamma") + assertMatches(sel, "1.2.4") + assertMatches(sel, "1.3") + assertNotMatches(sel, "1.2.3-alpha") + assertNotMatches(sel, "1.2.2") + } + + semsel(">=1.2.3-beta-2") { sel => + assertMatches(sel, "1.3-alpha") + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta-2") + assertMatches(sel, "1.2.3-beta-2-3") + assertMatches(sel, "1.2.3-beta-3") + assertMatches(sel, "1.2.3-beta-gamma") + assertMatches(sel, "1.2.4") + assertMatches(sel, "1.3") + assertNotMatches(sel, "1.2.3-alpha-3") + assertNotMatches(sel, "1.2.3-beta-1") + assertNotMatches(sel, "1.2.3-beta") + assertNotMatches(sel, "1.2.2") + } + Seq( // invalid operator "~1.2.3", @@ -278,9 +340,15 @@ class SemanticSelectorSpec extends FreeSpec with Matchers { "1.0.0 -2.0.0", "1.0.0-2.0.0", "-", - // cannot specify pre-release or metadata - "1.2.3-alpha", - "1.2-alpha", + // minor and patch versions are required for pre-release version + "1.2-alpha-beta", + "1-beta", + "<=1.2-beta", + "<=1-beta", + "1.2-beta - 1.3-alpha", + "1.2.x-beta", + "1.x.*-beta", + // cannot specify metadata "1.2.3+meta" ).foreach { selectorStr => semsel(selectorStr) { sel => From 4e8b6dc7aa42f022edea9ae798de1d7aac86404d Mon Sep 17 00:00:00 2001 From: tanishiking24 Date: Sat, 12 May 2018 11:05:22 +0900 Subject: [PATCH 0763/1030] Use contraband for generating SemanticSelector instead of using case class. --- .../librarymanagement/SemComparator.scala | 56 ++++ .../librarymanagement/SemSelAndChunk.scala | 32 ++ .../librarymanagement/SemanticSelector.scala | 74 +++++ .../main/contraband/librarymanagement2.json | 104 ++++++ .../librarymanagement/SemSelOperator.scala | 17 + .../SemanticSelectorExtra.scala | 209 ++++++++++++ .../librarymanagement/SemanticSelector.scala | 311 ------------------ 7 files changed, 492 insertions(+), 311 deletions(-) create mode 100644 core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala create mode 100644 core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala create mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/SemSelOperator.scala create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala delete mode 100644 core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala new file mode 100644 index 000000000..fd3ff81db --- /dev/null +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala @@ -0,0 +1,56 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class SemComparator private ( + val op: sbt.internal.librarymanagement.SemSelOperator, + val major: Option[Long], + val minor: Option[Long], + val patch: Option[Long], + val tags: Seq[String]) extends sbt.internal.librarymanagement.SemComparatorExtra with Serializable { + def matches(version: sbt.librarymanagement.VersionNumber): Boolean = this.matchesImpl(version) + def expandWildcard: Seq[SemComparator] = { + if (op == sbt.internal.librarymanagement.SemSelOperator.Eq && !allFieldsSpecified) { + Seq( + this.withOp(sbt.internal.librarymanagement.SemSelOperator.Gte), + this.withOp(sbt.internal.librarymanagement.SemSelOperator.Lte) + ) + } else { Seq(this) } +} + + +override def equals(o: Any): Boolean = o match { + case x: SemComparator => (this.op == x.op) && (this.major == x.major) && (this.minor == x.minor) && (this.patch == x.patch) && (this.tags == x.tags) + case _ => false +} +override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.SemComparator".##) + op.##) + major.##) + minor.##) + patch.##) + tags.##) +} +override def toString: String = { + this.toStringImpl +} +private[this] def copy(op: sbt.internal.librarymanagement.SemSelOperator = op, major: Option[Long] = major, minor: Option[Long] = minor, patch: Option[Long] = patch, tags: Seq[String] = tags): SemComparator = { + new SemComparator(op, major, minor, patch, tags) +} +def withOp(op: sbt.internal.librarymanagement.SemSelOperator): SemComparator = { + copy(op = op) +} +def withMajor(major: Option[Long]): SemComparator = { + copy(major = major) +} +def withMinor(minor: Option[Long]): SemComparator = { + copy(minor = minor) +} +def withPatch(patch: Option[Long]): SemComparator = { + copy(patch = patch) +} +def withTags(tags: Seq[String]): SemComparator = { + copy(tags = tags) +} +} +object SemComparator extends sbt.internal.librarymanagement.SemComparatorFunctions { + def apply(comparator: String): SemComparator = parse(comparator) + def apply(op: sbt.internal.librarymanagement.SemSelOperator, major: Option[Long], minor: Option[Long], patch: Option[Long], tags: Seq[String]): SemComparator = new SemComparator(op, major, minor, patch, tags) +} diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala new file mode 100644 index 000000000..9e25e9789 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala @@ -0,0 +1,32 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.librarymanagement +final class SemSelAndChunk private ( + val comparators: Seq[sbt.internal.librarymanagement.SemComparator]) extends Serializable { + def matches(version: sbt.librarymanagement.VersionNumber): Boolean = comparators.forall(_.matches(version)) + + + override def equals(o: Any): Boolean = o match { + case x: SemSelAndChunk => (this.comparators == x.comparators) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.internal.librarymanagement.SemSelAndChunk".##) + comparators.##) + } + override def toString: String = { + comparators.map(_.toString).mkString(" ") + } + private[this] def copy(comparators: Seq[sbt.internal.librarymanagement.SemComparator] = comparators): SemSelAndChunk = { + new SemSelAndChunk(comparators) + } + def withComparators(comparators: Seq[sbt.internal.librarymanagement.SemComparator]): SemSelAndChunk = { + copy(comparators = comparators) + } +} +object SemSelAndChunk extends sbt.internal.librarymanagement.SemSelAndChunkFunctions { + def apply(andClauseToken: String): SemSelAndChunk = parse(andClauseToken) + def apply(comparators: Seq[sbt.internal.librarymanagement.SemComparator]): SemSelAndChunk = new SemSelAndChunk(comparators) +} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala new file mode 100644 index 000000000..65f6e5b19 --- /dev/null +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala @@ -0,0 +1,74 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement +/** + * Semantic version selector API to check if the VersionNumber satisfies + * conditions described by semantic version selector. + * + * A `comparator` generally consist of an operator and version specifier. + * The set of operators is + * - `<`: Less than + * - `<=`: Less than or equal to + * - `>`: Greater than + * - `>=`: Greater than or equal to + * - `=`: Equal + * If no operator is specified, `=` is assumed. + * + * If minor or patch versions are not specified, some numbers are assumed. + * - `<=1.0` is equivalent to `<1.1.0`. + * - `<1.0` is equivalent to `<1.0.0`. + * - `>=1.0` is equivalent to `>=1.0.0`. + * - `>1.0` is equivalent to `>=1.1.0`. + * - `=1.0` is equivalent to `>=1.0 <=1.0` (so `>=1.0.0 <1.1.0`). + * + * Comparators can be combined by spaces to form the intersection set of the comparators. + * For example, `>1.2.3 <4.5.6` matches versions that are `greater than 1.2.3 AND less than 4.5.6`. + * + * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the + * union set of the intersection sets. So the semantic selector is in disjunctive normal form. + * + * Metadata and pre-release of VersionNumber are ignored. + * So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version + * or any metadata like `1.0.0-alpha`, `1.0.0+metadata`. + * + * Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version. + * Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`) + * + * The hyphen range like `1.2.3 - 4.5.6` matches inclusive set of versions. + * So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`. + * Both sides of comparators around - are required and they can not have any operators. + * For example, `>=1.2.3 - 4.5.6` is invalid. + */ +final class SemanticSelector private ( + val selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk]) extends Serializable { + def matches(versionNumber: VersionNumber): Boolean = selectors.exists(_.matches(versionNumber)) + + + override def equals(o: Any): Boolean = o match { + case x: SemanticSelector => (this.selectors == x.selectors) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.librarymanagement.SemanticSelector".##) + selectors.##) + } + override def toString: String = { + selectors.map(_.toString).mkString(" || ") + } + private[this] def copy(selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk] = selectors): SemanticSelector = { + new SemanticSelector(selectors) + } + def withSelectors(selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk]): SemanticSelector = { + copy(selectors = selectors) + } +} +object SemanticSelector { + def apply(selector: String): SemanticSelector = { + val orChunkTokens = selector.split("\\s+\\|\\|\\s+").map(_.trim) + val orChunks = orChunkTokens.map { chunk => sbt.internal.librarymanagement.SemSelAndChunk(chunk) } + SemanticSelector(orChunks) + } + def apply(selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk]): SemanticSelector = new SemanticSelector(selectors) +} diff --git a/core/src/main/contraband/librarymanagement2.json b/core/src/main/contraband/librarymanagement2.json index 2c9d3d6cf..f94cbef02 100644 --- a/core/src/main/contraband/librarymanagement2.json +++ b/core/src/main/contraband/librarymanagement2.json @@ -17,6 +17,110 @@ { "name": "includeTypes", "type": "Set[String]" } ], "parentsCompanion": "sbt.librarymanagement.MakePomConfigurationFunctions" + }, + { + "name": "SemanticSelector", + "namespace": "sbt.librarymanagement", + "target": "Scala", + "type": "record", + "doc": [ + "Semantic version selector API to check if the VersionNumber satisfies", + "conditions described by semantic version selector.", + "", + "A `comparator` generally consist of an operator and version specifier.", + "The set of operators is", + "- `<`: Less than", + "- `<=`: Less than or equal to", + "- `>`: Greater than", + "- `>=`: Greater than or equal to", + "- `=`: Equal", + "If no operator is specified, `=` is assumed.", + "", + "If minor or patch versions are not specified, some numbers are assumed.", + "- `<=1.0` is equivalent to `<1.1.0`.", + "- `<1.0` is equivalent to `<1.0.0`.", + "- `>=1.0` is equivalent to `>=1.0.0`.", + "- `>1.0` is equivalent to `>=1.1.0`.", + "- `=1.0` is equivalent to `>=1.0 <=1.0` (so `>=1.0.0 <1.1.0`).", + "", + "Comparators can be combined by spaces to form the intersection set of the comparators.", + "For example, `>1.2.3 <4.5.6` matches versions that are `greater than 1.2.3 AND less than 4.5.6`.", + "", + "The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the", + "union set of the intersection sets. So the semantic selector is in disjunctive normal form.", + "", + "Metadata and pre-release of VersionNumber are ignored.", + "So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version", + "or any metadata like `1.0.0-alpha`, `1.0.0+metadata`.", + "", + "Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version.", + "Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`)", + "", + "The hyphen range like `1.2.3 - 4.5.6` matches inclusive set of versions.", + "So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`.", + "Both sides of comparators around - are required and they can not have any operators.", + "For example, `>=1.2.3 - 4.5.6` is invalid." + ], + "generateCodec": false, + "fields": [ + { "name": "selectors", "type": "Seq[sbt.internal.librarymanagement.SemSelAndChunk]" } + ], + "toString": "selectors.map(_.toString).mkString(\" || \")", + "extra": "def matches(versionNumber: VersionNumber): Boolean = selectors.exists(_.matches(versionNumber))", + "extraCompanion": [ + "def apply(selector: String): SemanticSelector = {", + " val orChunkTokens = selector.split(\"\\\\s+\\\\|\\\\|\\\\s+\").map(_.trim)", + " val orChunks = orChunkTokens.map { chunk => sbt.internal.librarymanagement.SemSelAndChunk(chunk) }", + " SemanticSelector(orChunks)", + "}" + ] + }, + { + "name": "SemSelAndChunk", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "generateCodec": false, + "parentsCompanion": "sbt.internal.librarymanagement.SemSelAndChunkFunctions", + "fields": [ + { "name": "comparators", "type": "Seq[sbt.internal.librarymanagement.SemComparator]" } + ], + "toString": "comparators.map(_.toString).mkString(\" \")", + "extra": "def matches(version: sbt.librarymanagement.VersionNumber): Boolean = comparators.forall(_.matches(version))", + "extraCompanion": [ + "def apply(andClauseToken: String): SemSelAndChunk = parse(andClauseToken)" + ] + }, + { + "name": "SemComparator", + "namespace": "sbt.internal.librarymanagement", + "target": "Scala", + "type": "record", + "generateCodec": false, + "toString": "this.toStringImpl", + "parents": "sbt.internal.librarymanagement.SemComparatorExtra", + "parentsCompanion": "sbt.internal.librarymanagement.SemComparatorFunctions", + "fields": [ + { "name": "op", "type": "sbt.internal.librarymanagement.SemSelOperator" }, + { "name": "major", "type": "Option[Long]" }, + { "name": "minor", "type": "Option[Long]" }, + { "name": "patch", "type": "Option[Long]" }, + { "name": "tags", "type": "Seq[String]" } + ], + "extra": [ + "def matches(version: sbt.librarymanagement.VersionNumber): Boolean = this.matchesImpl(version)", + "def expandWildcard: Seq[SemComparator] = {", + " if (op == sbt.internal.librarymanagement.SemSelOperator.Eq && !allFieldsSpecified) {", + " Seq(", + " this.withOp(sbt.internal.librarymanagement.SemSelOperator.Gte),", + " this.withOp(sbt.internal.librarymanagement.SemSelOperator.Lte)", + " )", + " } else { Seq(this) }", + "}" + ], + "extraCompanion": [ + "def apply(comparator: String): SemComparator = parse(comparator)" + ] } ] } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemSelOperator.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemSelOperator.scala new file mode 100644 index 000000000..d881fe9e2 --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemSelOperator.scala @@ -0,0 +1,17 @@ +package sbt.internal.librarymanagement +sealed abstract class SemSelOperator { + override def toString: String = this match { + case SemSelOperator.Lte => "<=" + case SemSelOperator.Lt => "<" + case SemSelOperator.Gte => ">=" + case SemSelOperator.Gt => ">" + case SemSelOperator.Eq => "=" + } +} +object SemSelOperator { + case object Lte extends SemSelOperator + case object Lt extends SemSelOperator + case object Gte extends SemSelOperator + case object Gt extends SemSelOperator + case object Eq extends SemSelOperator +} diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala new file mode 100644 index 000000000..49990d1df --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -0,0 +1,209 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement.VersionNumber +import sbt.internal.librarymanagement.SemSelOperator.{ Lt, Lte, Gt, Gte, Eq } + +import scala.annotation.tailrec + +private[librarymanagement] abstract class SemSelAndChunkFunctions { + protected def parse(andClauseToken: String): SemSelAndChunk = { + val comparatorTokens = andClauseToken.split("\\s+") + val hyphenIndex = comparatorTokens.indexWhere(_ == "-") + val comparators = if (hyphenIndex == -1) { + comparatorTokens.map(SemComparator.apply) + } else { + // interpret `A.B.C - D.E.F` to `>=A.B.C <=D.E.F` + val (before, after) = comparatorTokens.splitAt(hyphenIndex) + (before.lastOption, after.drop(1).headOption) match { + case (Some(fromStr), Some(toStr)) => + // from and to can not have an operator. + if (hasOperator(fromStr) || hasOperator(toStr)) { + throw new IllegalArgumentException( + s"Invalid ' - ' range, both side of comparators can not have an operator: $fromStr - $toStr") + } + val from = SemComparator(fromStr) + val to = SemComparator(toStr) + val comparatorsBefore = before.dropRight(1).map(SemComparator.apply) + val comparatorsAfter = after.drop(2) match { + case tokens if !tokens.isEmpty => + parse(tokens.mkString(" ")).comparators + case _ => Seq.empty + } + from.withOp(Gte) +: to.withOp(Lte) +: + (comparatorsBefore ++ comparatorsAfter) + case _ => + throw new IllegalArgumentException( + s"Invalid ' - ' range position, both side of versions must be specified: $andClauseToken") + } + } + SemSelAndChunk(comparators.flatMap(_.expandWildcard)) + } + + private[this] def hasOperator(comparator: String): Boolean = { + comparator.startsWith("<") || + comparator.startsWith(">") || + comparator.startsWith("=") + } +} + +private[librarymanagement] abstract class SemComparatorExtra { + val op: SemSelOperator + val major: Option[Long] + val minor: Option[Long] + val patch: Option[Long] + val tags: Seq[String] + + protected def toStringImpl: String = { + val versionStr = Seq(major, minor, patch) + .collect { + case Some(v) => v.toString + } + .mkString(".") + val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" + s"$op$versionStr$tagsStr" + } + + protected def matchesImpl(version: VersionNumber): Boolean = { + // Fill empty fields of version specifier with 0 or max value of Long. + // By filling them, SemComparator realize the properties below + // `<=1.0` is equivalent to `<1.1.0` (`<=1.0.${Long.MaxValue}`) + // `<1.0` is equivalent to `<1.0.0` + // `>=1.0` is equivalent to `>=1.0.0` + // `>1.0` is equivalent to `>=1.1.0` (`>1.0.${Long.MaxValue}`) + // + // However this fills 0 for a comparator that have `=` operator, + // a comparator that have empty part of version and `=` operator won't appear + // because of expanding it to and clause of comparators. + val assumed = op match { + case Lte => Long.MaxValue + case Lt => 0L + case Gte => 0L + case Gt => Long.MaxValue + case Eq => 0L + } + // empty fields of the version number are assumed to be 0. + val versionNumber = + (version._1.getOrElse(0L), version._2.getOrElse(0L), version._3.getOrElse(0L)) + val selector = (major.getOrElse(assumed), minor.getOrElse(assumed), patch.getOrElse(assumed)) + val normalVersionCmp = + implicitly[Ordering[(Long, Long, Long)]].compare(versionNumber, selector) + val cmp = + if (normalVersionCmp == 0) comparePreReleaseTags(version.tags, tags) + else normalVersionCmp + op match { + case Lte if cmp <= 0 => true + case Lt if cmp < 0 => true + case Gte if cmp >= 0 => true + case Gt if cmp > 0 => true + case Eq if cmp == 0 => true + case _ => false + } + } + private[this] def comparePreReleaseTags(ts1: Seq[String], ts2: Seq[String]): Int = { + // > When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. + if (ts1.isEmpty && ts2.isEmpty) 0 + else if (ts1.nonEmpty && ts2.isEmpty) -1 // ts1 is pre-release version + else if (ts1.isEmpty && ts2.nonEmpty) 1 // ts2 is pre-release version + else compareTags(ts1, ts2) + } + + @tailrec + private[this] def compareTags(ts1: Seq[String], ts2: Seq[String]): Int = { + // > A larger set of pre-release fields has a higher precedence than a smaller set, + // > if all of the preceding identifiers are equal. + if (ts1.isEmpty && ts2.isEmpty) 0 + else if (ts1.nonEmpty && ts2.isEmpty) 1 + else if (ts1.isEmpty && ts2.nonEmpty) -1 + else { + val ts1head = ts1.head + val ts2head = ts2.head + val cmp = (ts1head.matches("\\d+"), ts2head.matches("\\d+")) match { + // Identifiers consisting of only digits are compared numerically. + // Numeric identifiers always have lower precedence than non-numeric identifiers. + // Identifiers with letters are compared case insensitive lexical order. + case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) + case (false, true) => 1 + case (true, false) => -1 + case (false, false) => ts1head.toLowerCase.compareTo(ts2head.toLowerCase) + } + if (cmp == 0) compareTags(ts1.tail, ts2.tail) + else cmp + } + } + + // Expand wildcard with `=` operator to and clause of comparators. + // `=1.0` is equivalent to `>=1.0 <=1.0` + protected def allFieldsSpecified: Boolean = + major.isDefined && minor.isDefined && patch.isDefined +} + +private[librarymanagement] abstract class SemComparatorFunctions { + private[this] val ComparatorRegex = """(?x)^ + ([<>]=?|=)? + (?:(\d+|[xX*]) + (?:\.(\d+|[xX*]) + (?:\.(\d+|[xX*]))? + )? + )((?:-\w+)*)$ + """.r + protected def parse(comparator: String): SemComparator = { + comparator match { + case ComparatorRegex(rawOp, rawMajor, rawMinor, rawPatch, ts) => + val opStr = Option(rawOp) + val major = Option(rawMajor) + val minor = Option(rawMinor) + val patch = Option(rawPatch) + val tags = splitDash(ts) + + // Trim wildcard(x, X, *) and re-parse it. + // By trimming it, comparator realize the property like + // `=1.2.x` is equivalent to `=1.2`. + val hasXrangeSelector = Seq(major, minor, patch).exists { + case Some(str) => str.matches("[xX*]") + case None => false + } + if (hasXrangeSelector) { + if (tags.nonEmpty) + throw new IllegalArgumentException( + s"Pre-release version requires major, minor, patch versions to be specified: $comparator") + val numbers = Seq(major, minor, patch).takeWhile { + case Some(str) => str.matches("\\d+") + case None => false + } + parse( + numbers + .collect { + case Some(v) => v.toString + } + .mkString(".") + ) + } else { + if (tags.nonEmpty && (major.isEmpty || minor.isEmpty || patch.isEmpty)) + throw new IllegalArgumentException( + s"Pre-release version requires major, minor, patch versions to be specified: $comparator") + val operator = opStr match { + case Some("<") => Lt + case Some("<=") => Lte + case Some(">") => Gt + case Some(">=") => Gte + case Some("=") => Eq + case None => Eq + case Some(_) => + throw new IllegalArgumentException(s"Invalid operator: $opStr") + } + SemComparator( + operator, + major.map(_.toLong), + minor.map(_.toLong), + patch.map(_.toLong), + tags + ) + } + case _ => throw new IllegalArgumentException(s"Invalid comparator: $comparator") + } + } + private[this] def splitOn[A](s: String, sep: Char): Vector[String] = + if (s eq null) Vector() + else s.split(sep).filterNot(_ == "").toVector + private[this] def splitDash(s: String) = splitOn(s, '-') +} diff --git a/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala deleted file mode 100644 index 279f4fdd0..000000000 --- a/core/src/main/scala/sbt/librarymanagement/SemanticSelector.scala +++ /dev/null @@ -1,311 +0,0 @@ -package sbt.librarymanagement - -import scala.annotation.tailrec - -/** - * Semantic version selector API to check if the VersionNumber satisfies - * conditions described by semantic version selector. - */ -sealed abstract case class SemanticSelector( - private val selectors: Seq[SemanticSelector.SemSelAndChunk]) { - - /** - * Check if the version number satisfies the conditions described by semantic version selector. - * - * The empty fields of the version number are assumed to be 0, for example, `1` is treated as `1.0.0`. - * - * @param versionNumber The Version Number to be checked if it satisfies the conditions. - * @return The result of checking the version number satisfies the conditions or not. - */ - def matches(versionNumber: VersionNumber): Boolean = { - selectors.exists(_.matches(versionNumber)) - } - override def toString: String = selectors.map(_.toString).mkString(" || ") -} -object SemanticSelector { - - /** - * Build a SemanticSelector that can match specific semantic versions. - * - * A `comparator` generally consist of an operator and version specifier. - * The set of operators is - * - `<`: Less than - * - `<=`: Less than or equal to - * - `>`: Greater than - * - `>=`: Greater than or equal to - * - `=`: Equal - * If no operator is specified, `=` is assumed. - * - * If minor or patch versions are not specified, some numbers are assumed. - * - `<=1.0` is equivalent to `<1.1.0`. - * - `<1.0` is equivalent to `<1.0.0`. - * - `>=1.0` is equivalent to `>=1.0.0`. - * - `>1.0` is equivalent to `>=1.1.0`. - * - `=1.0` is equivalent to `>=1.0 <=1.0` (so `>=1.0.0 <1.1.0`). - * - * Comparators can be combined by spaces to form the intersection set of the comparators. - * For example, `>1.2.3 <4.5.6` matches versions that are `greater than 1.2.3 AND less than 4.5.6`. - * - * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the - * union set of the intersection sets. So the semantic selector is in disjunctive normal form. - * - * Metadata and pre-release of VersionNumber are ignored. - * So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version - * or any metadata like `1.0.0-alpha`, `1.0.0+metadata`. - * - * Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version. - * Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`) - * - * The hyphen range like `1.2.3 - 4.5.6` matches inclusive set of versions. - * So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`. - * Both sides of comparators around - are required and they can not have any operators. - * For example, `>=1.2.3 - 4.5.6` is invalid. - * - * @param selector A string that represents semantic version selector. - * @return A `SemanticSelector` that can match only onto specific semantic versions. - * @throws java.lang.IllegalAccessException when selector is in invalid format of semantic version selector. - */ - def apply(selector: String): SemanticSelector = { - val orChunkTokens = selector.split("\\s+\\|\\|\\s+").map(_.trim) - val orChunks = orChunkTokens.map { chunk => - SemSelAndChunk(chunk) - } - new SemanticSelector(orChunks) {} - } - - private[this] sealed trait SemSelOperator - private[this] case object Lte extends SemSelOperator { - override def toString: String = "<=" - } - private[this] case object Lt extends SemSelOperator { - override def toString: String = "<" - } - private[this] case object Gte extends SemSelOperator { - override def toString: String = ">=" - } - private[this] case object Gt extends SemSelOperator { - override def toString: String = ">" - } - private[this] case object Eq extends SemSelOperator { - override def toString: String = "=" - } - - private[SemanticSelector] final case class SemSelAndChunk(comparators: Seq[SemComparator]) { - def matches(version: VersionNumber): Boolean = { - comparators.forall(_.matches(version)) - } - override def toString: String = comparators.map(_.toString).mkString(" ") - } - private[SemanticSelector] object SemSelAndChunk { - def apply(andClauseToken: String): SemSelAndChunk = parse(andClauseToken) - private[this] def parse(andClauseToken: String): SemSelAndChunk = { - val comparatorTokens = andClauseToken.split("\\s+") - val hyphenIndex = comparatorTokens.indexWhere(_ == "-") - val comparators = if (hyphenIndex == -1) { - comparatorTokens.map(SemComparator.apply) - } else { - // interpret `A.B.C - D.E.F` to `>=A.B.C <=D.E.F` - val (before, after) = comparatorTokens.splitAt(hyphenIndex) - (before.lastOption, after.drop(1).headOption) match { - case (Some(fromStr), Some(toStr)) => - // from and to can not have an operator. - if (hasOperator(fromStr) || hasOperator(toStr)) { - throw new IllegalArgumentException( - s"Invalid ' - ' range, both side of comparators can not have an operator: $fromStr - $toStr") - } - val from = SemComparator(fromStr) - val to = SemComparator(toStr) - val comparatorsBefore = before.dropRight(1).map(SemComparator.apply) - val comparatorsAfter = after.drop(2) match { - case tokens if !tokens.isEmpty => - parse(tokens.mkString(" ")).comparators - case _ => Seq.empty - } - from.copy(op = Gte) +: - to.copy(op = Lte) +: - (comparatorsBefore ++ comparatorsAfter) - case _ => - throw new IllegalArgumentException( - s"Invalid ' - ' range position, both side of versions must be specified: $andClauseToken") - } - } - SemSelAndChunk(comparators.flatMap(_.expandWildcard)) - } - - private[this] def hasOperator(comparator: String): Boolean = { - comparator.startsWith("<") || - comparator.startsWith(">") || - comparator.startsWith("=") - } - } - - private[SemanticSelector] final case class SemComparator private ( - op: SemSelOperator, - major: Option[Long], - minor: Option[Long], - patch: Option[Long], - tags: Seq[String] - ) { - def matches(version: VersionNumber): Boolean = { - // Fill empty fields of version specifier with 0 or max value of Long. - // By filling them, SemComparator realize the properties below - // `<=1.0` is equivalent to `<1.1.0` (`<=1.0.${Long.MaxValue}`) - // `<1.0` is equivalent to `<1.0.0` - // `>=1.0` is equivalent to `>=1.0.0` - // `>1.0` is equivalent to `>=1.1.0` (`>1.0.${Long.MaxValue}`) - // - // However this fills 0 for a comparator that have `=` operator, - // a comparator that have empty part of version and `=` operator won't appear - // because of expanding it to and clause of comparators. - val assumed = op match { - case Lte => Long.MaxValue - case Lt => 0L - case Gte => 0L - case Gt => Long.MaxValue - case Eq => 0L - } - // empty fields of the version number are assumed to be 0. - val versionNumber = - (version._1.getOrElse(0L), version._2.getOrElse(0L), version._3.getOrElse(0L)) - val selector = (major.getOrElse(assumed), minor.getOrElse(assumed), patch.getOrElse(assumed)) - val normalVersionCmp = - implicitly[Ordering[(Long, Long, Long)]].compare(versionNumber, selector) - val cmp = - if (normalVersionCmp == 0) SemComparator.comparePreReleaseTags(version.tags, tags) - else normalVersionCmp - op match { - case Lte if cmp <= 0 => true - case Lt if cmp < 0 => true - case Gte if cmp >= 0 => true - case Gt if cmp > 0 => true - case Eq if cmp == 0 => true - case _ => false - } - } - - // Expand wildcard with `=` operator to and clause of comparators. - // `=1.0` is equivalent to `>=1.0 <=1.0` - def expandWildcard: Seq[SemComparator] = { - if (op == Eq && !allFieldsSpecified) { - Seq(this.copy(op = Gte), this.copy(op = Lte)) - } else { - Seq(this) - } - } - private[this] def allFieldsSpecified: Boolean = - major.isDefined && minor.isDefined && patch.isDefined - - override def toString: String = { - val versionStr = Seq(major, minor, patch) - .collect { - case Some(v) => v.toString - } - .mkString(".") - val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" - s"$op$versionStr$tagsStr" - } - } - private[SemanticSelector] object SemComparator { - def apply(comparator: String): SemComparator = parse(comparator) - private[this] val ComparatorRegex = """(?x)^ - ([<>]=?|=)? - (?:(\d+|[xX*]) - (?:\.(\d+|[xX*]) - (?:\.(\d+|[xX*]))? - )? - )((?:-\w+)*)$ - """.r - private[this] def parse(comparator: String): SemComparator = { - comparator match { - case ComparatorRegex(rawOp, rawMajor, rawMinor, rawPatch, ts) => - val opStr = Option(rawOp) - val major = Option(rawMajor) - val minor = Option(rawMinor) - val patch = Option(rawPatch) - val tags = splitDash(ts) - - // Trim wildcard(x, X, *) and re-parse it. - // By trimming it, comparator realize the property like - // `=1.2.x` is equivalent to `=1.2`. - val hasXrangeSelector = Seq(major, minor, patch).exists { - case Some(str) => str.matches("[xX*]") - case None => false - } - if (hasXrangeSelector) { - if (tags.nonEmpty) - throw new IllegalArgumentException( - s"Pre-release version requires major, minor, patch versions to be specified: $comparator") - val numbers = Seq(major, minor, patch).takeWhile { - case Some(str) => str.matches("\\d+") - case None => false - } - parse( - numbers - .collect { - case Some(v) => v.toString - } - .mkString(".") - ) - } else { - if (tags.nonEmpty && (major.isEmpty || minor.isEmpty || patch.isEmpty)) - throw new IllegalArgumentException( - s"Pre-release version requires major, minor, patch versions to be specified: $comparator") - val operator = opStr match { - case Some("<") => Lt - case Some("<=") => Lte - case Some(">") => Gt - case Some(">=") => Gte - case Some("=") => Eq - case None => Eq - case Some(_) => - throw new IllegalArgumentException(s"Invalid operator: $opStr") - } - SemComparator( - operator, - major.map(_.toLong), - minor.map(_.toLong), - patch.map(_.toLong), - tags - ) - } - case _ => throw new IllegalArgumentException(s"Invalid comparator: $comparator") - } - } - private[this] def splitOn[A](s: String, sep: Char): Vector[String] = - if (s eq null) Vector() - else s.split(sep).filterNot(_ == "").toVector - private[this] def splitDash(s: String) = splitOn(s, '-') - - private[SemComparator] def comparePreReleaseTags(ts1: Seq[String], ts2: Seq[String]): Int = { - // > When major, minor, and patch are equal, a pre-release version has lower precedence than a normal version. - if (ts1.isEmpty && ts2.isEmpty) 0 - else if (ts1.nonEmpty && ts2.isEmpty) -1 // ts1 is pre-release version - else if (ts1.isEmpty && ts2.nonEmpty) 1 // ts2 is pre-release version - else compareTags(ts1, ts2) - } - - @tailrec - private[this] def compareTags(ts1: Seq[String], ts2: Seq[String]): Int = { - // > A larger set of pre-release fields has a higher precedence than a smaller set, - // > if all of the preceding identifiers are equal. - if (ts1.isEmpty && ts2.isEmpty) 0 - else if (ts1.nonEmpty && ts2.isEmpty) 1 - else if (ts1.isEmpty && ts2.nonEmpty) -1 - else { - val ts1head = ts1.head - val ts2head = ts2.head - val cmp = (ts1head.matches("\\d+"), ts2head.matches("\\d+")) match { - // Identifiers consisting of only digits are compared numerically. - // Numeric identifiers always have lower precedence than non-numeric identifiers. - // Identifiers with letters are compared case insensitive lexical order. - case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) - case (false, true) => 1 - case (true, false) => -1 - case (false, false) => ts1head.toLowerCase.compareTo(ts2head.toLowerCase) - } - if (cmp == 0) compareTags(ts1.tail, ts2.tail) - else cmp - } - } - } -} From d5f5cbb0610ef4621fad675574471c7176ca22e7 Mon Sep 17 00:00:00 2001 From: tanishiking24 Date: Sat, 12 May 2018 12:26:44 +0900 Subject: [PATCH 0764/1030] Rename VersionNumber#satisfies to VersionNumber#matchesSemVer VersionNumber#matchesSemVer receive SemanticSelector instead of String --- core/src/main/scala/sbt/librarymanagement/VersionNumber.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 102d468c3..2437466cc 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -27,8 +27,8 @@ final class VersionNumber private[sbt] ( case _ => false } - def satisfies(selector: String): Boolean = { - SemanticSelector(selector).matches(this) + def matchesSemVer(selsem: SemanticSelector): Boolean = { + selsem.matches(this) } /** A variant of mkString that returns the empty string if the sequence is empty. */ From 9a002fb5494889d645f45f7834c970dc0e4702d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20Wold?= Date: Tue, 15 May 2018 13:22:38 +0200 Subject: [PATCH 0765/1030] Fixes 4156 --- .../internal/librarymanagement/ivyint/SbtChainResolver.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index fb2e9b1d3..b22aa5bef 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -85,8 +85,8 @@ private[sbt] case class SbtChainResolver( dd: DependencyDescriptor, data: ResolveData ): ResolvedModuleRevision = { - if (data.getOptions.getLog != LogOptions.LOG_QUIET) - Message.debug("Resolving " + dd.getDependencyRevisionId + " ...") + if (data.getOptions.getLog == LogOptions.LOG_DEFAULT) + Message.info("Resolving " + dd.getDependencyRevisionId + " ...") val gd = CustomSbtResolution.getDependency(dd, data) val mod = IvySbt.resetArtifactResolver(gd) mod From c24ab5c4eeac5032677ce2672c508808e695f175 Mon Sep 17 00:00:00 2001 From: tanishiking24 Date: Thu, 17 May 2018 10:46:21 +0900 Subject: [PATCH 0766/1030] Enable sbt to specify config.resource without disabling gigahorse Fix https://github.com/sbt/sbt/issues/3585. Gigahorse.config tries to load specified config file in sbt's classpath and of course fail to find the specified config file, and throw java.io.IOException if we specify config.resource, because We can avoid trying to load specified config file inside sbt by avoid using Gigahorse.config that call `ConfigFactory.load()` inside. This commit fixes librarymanagement not to use Gigahorse.config and make it use gigahorse.Config() which returns gigahorse's default config without calling `ConfigFactory.load()` instead. --- core/src/main/scala/sbt/librarymanagement/Http.scala | 2 +- .../internal/librarymanagement/ivyint/GigahorseUrlHandler.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 9870d9b0f..833a9edc0 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -3,5 +3,5 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse object Http { - lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + lazy val http: HttpClient = Gigahorse.http(gigahorse.Config()) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index b7e754dda..49b0f2bbc 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -214,7 +214,7 @@ object GigahorseUrlHandler { private val EmptyBuffer: Array[Byte] = new Array[Byte](0) - lazy val http: HttpClient = Gigahorse.http(Gigahorse.config) + lazy val http: HttpClient = Gigahorse.http(gigahorse.Config()) private lazy val okHttpClient: OkHttpClient = { http From 6b86d05ce61c7e037895541125dbeeee9d0f6a3b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 14 Jun 2018 02:07:39 -0400 Subject: [PATCH 0767/1030] sbt-houserules 0.3.7 --- project/build.properties | 2 +- project/plugins.sbt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/build.properties b/project/build.properties index 64cf32f7f..d6e35076c 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.4 +sbt.version=1.1.6 diff --git a/project/plugins.sbt b/project/plugins.sbt index f38b000fe..a0ff36b64 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,4 +1,4 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.6") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.7") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") From 2b4aa3973daa42684a793a512fe29a02f98e0d37 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 14 Jun 2018 03:16:49 -0400 Subject: [PATCH 0768/1030] Fix flaky OfflineModeSpec Fixes https://github.com/sbt/librarymanagement/issues/229 OfflineModeSpec is failing often because it asserts that the offline resolution needs to happen within 30% of the original resolution, and I guess it really depends on the weather how much portion of it spends on resolution. --- .../librarymanagement/OfflineModeSpec.scala | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala index 5b0b7ed34..028c2b0b3 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala @@ -2,10 +2,10 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions -import org.scalatest.Assertion +import org.scalatest.{ Assertion, DiagrammedAssertions } import sbt.io.IO -class OfflineModeSpec extends BaseIvySpecification { +class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { private final def targetDir = Some(currentDependency) private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def offlineConf = makeUpdateConfiguration(true, targetDir) @@ -37,18 +37,13 @@ class OfflineModeSpec extends BaseIvySpecification { assert(onlineResolution.isRight) assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0)) - // Compute an estimate to ensure that the second resolution does indeed use the cache val originalResolveTime = onlineResolution.right.get.stats.resolveTime - val estimatedCachedTime = originalResolveTime * 0.3 - val offlineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, log) - assert(offlineResolution.isRight, s"Offline resolution has failed with $offlineResolution.") + assert(offlineResolution.isRight) val resolveTime = offlineResolution.right.get.stats.resolveTime - // Only check the estimate for the non cached resolution, otherwise resolution is cached - assert(resolveTime <= estimatedCachedTime, - "Offline resolution took more than 15% of normal resolution's running time.") + assert(originalResolveTime > resolveTime) } "Offline update configuration" should "reuse the caches when offline is enabled" in { From 3b9385dfc52ad3d115b19af11af1b933205be904 Mon Sep 17 00:00:00 2001 From: Peter Neyens Date: Sat, 16 Jun 2018 10:11:36 +0100 Subject: [PATCH 0769/1030] Set Gigahorse readTimeout to 1 hour --- core/src/main/scala/sbt/librarymanagement/Http.scala | 3 ++- .../librarymanagement/ivyint/GigahorseUrlHandler.scala | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 833a9edc0..2b54f8140 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,7 +1,8 @@ package sbt.librarymanagement import gigahorse._, support.okhttp.Gigahorse +import scala.concurrent.duration.DurationInt object Http { - lazy val http: HttpClient = Gigahorse.http(gigahorse.Config()) + lazy val http: HttpClient = Gigahorse.http(gigahorse.Config().withReadTimeout(60.minutes)) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 4c80cd152..38f520867 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -198,8 +198,8 @@ class GigahorseUrlHandler extends AbstractURLHandler { object GigahorseUrlHandler { import gigahorse.HttpClient - import gigahorse.support.okhttp.Gigahorse import okhttp3.{ OkHttpClient, JavaNetAuthenticator } + import sbt.librarymanagement.Http // This is requires to access the constructor of URLInfo. private[sbt] class SbtUrlInfo(available: Boolean, @@ -214,7 +214,7 @@ object GigahorseUrlHandler { private val EmptyBuffer: Array[Byte] = new Array[Byte](0) - lazy val http: HttpClient = Gigahorse.http(gigahorse.Config()) + lazy val http: HttpClient = Http.http private lazy val okHttpClient: OkHttpClient = { http From 8e1e1e8121de925cef87858e5586c5fb7fe60ba6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 18 Jun 2018 04:46:51 -0400 Subject: [PATCH 0770/1030] IO, Util 1.2.0-M1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9ef21a22b..f49220688 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.6" - private val ioVersion = "1.1.3" - private val utilVersion = "1.1.3" + private val ioVersion = "1.2.0-M1" + private val utilVersion = "1.2.0-M1" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 660e6fb7109b64662fb40de187227e6ec504e36b Mon Sep 17 00:00:00 2001 From: Alex Khvatov Date: Tue, 19 Jun 2018 14:47:48 -0400 Subject: [PATCH 0771/1030] Fix for #4157 see discussion https://github.com/sbt/sbt/issues/4157 --- .../ivyint/SbtChainResolver.scala | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 3e70ecafc..c7c8904bf 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -216,7 +216,22 @@ private[sbt] case class SbtChainResolver( val firstHit = sortedRevisions.reverse.headOption firstHit.map { hit => val (resolvedModule, resolver) = hit - Message.warn(s"Choosing $resolver for ${resolvedModule.getId}") + + if (resolvedModule.getId.getRevision.contains("SNAPSHOT")) { + + Message.warn( + "Resolving a snapshot version. It's going to be slow unless you use `updateOptions := updateOptions.value.withLatestSnapshots(false)` options.") + val resolvers = sortedRevisions.map(_._2.getName) + sortedRevisions.foreach(h => { + val (module, resolver) = h + Message.info( + s"Out of ${sortedRevisions.size} candidates we found for ${module.getId} in ${resolvers + .mkString(" and ")}, we are choosing ${resolver}.") + }) + } else { + Message.warn(s"Choosing $resolver for ${resolvedModule.getId}") + } + // Now that we know the real latest revision, let's force Ivy to use it val resolvedDescriptor = resolvedModule.getDescriptor val artifactOpt = findFirstArtifactRef(resolvedDescriptor, data, resolver) From a8d5db4fb6346d784112c518e26a149a38ac6ea4 Mon Sep 17 00:00:00 2001 From: OlegYch Date: Tue, 26 Jun 2018 00:28:34 +0300 Subject: [PATCH 0772/1030] fixes https://github.com/sbt/sbt/issues/4224 blocking+global ec+par collections leads to a significant performance regression, offload downloading to a separate threadpool --- .../ivyint/ParallelResolveEngine.scala | 52 +++++++++++-------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index f461d0cdf..235f280d5 100755 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -1,5 +1,7 @@ package sbt.internal.librarymanagement.ivyint +import java.util.concurrent.Executors + import org.apache.ivy.core.event.EventManager import org.apache.ivy.core.event.download.PrepareDownloadEvent import org.apache.ivy.core.module.descriptor.Artifact @@ -9,12 +11,18 @@ import org.apache.ivy.core.sort.SortEngine import org.apache.ivy.util.Message import org.apache.ivy.util.filter.Filter -import scala.collection.parallel.mutable.ParArray +import scala.concurrent.duration.Duration +import scala.concurrent.{ Await, ExecutionContext, Future } private[ivyint] case class DownloadResult(dep: IvyNode, report: DownloadReport, totalSizeDownloaded: Long) +object ParallelResolveEngine { + private val resolveExecutionContext = + ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) +} + /** Define an ivy [[ResolveEngine]] that resolves dependencies in parallel. */ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, eventManager: EventManager, @@ -24,30 +32,27 @@ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, override def downloadArtifacts(report: ResolveReport, artifactFilter: Filter, options: DownloadOptions): Unit = { - + import scala.collection.JavaConverters._ val start = System.currentTimeMillis - val dependencies0 = report.getDependencies - val dependencies = dependencies0 - .toArray(new Array[IvyNode](dependencies0.size)) - val artifacts = report.getArtifacts - .toArray(new Array[Artifact](report.getArtifacts.size)) - - getEventManager.fireIvyEvent(new PrepareDownloadEvent(artifacts)) - - // Farm out the dependencies for parallel download - val allDownloads = dependencies.par.flatMap { dep => - if (!(dep.isCompletelyEvicted || dep.hasProblem) && - dep.getModuleRevision != null) { - //don't block in global ec to avoid deadlocks - scala.concurrent.blocking { - ParArray(downloadNodeArtifacts(dep, artifactFilter, options)) - } - } else ParArray.empty[DownloadResult] + report.getArtifacts match { + case typed: java.util.List[Artifact @unchecked] => + new PrepareDownloadEvent(typed.asScala.toArray) } - - // Force parallel downloads and compute total downloaded size - val totalSize = allDownloads.toArray.foldLeft(0L) { - case (size, download) => + // Farm out the dependencies for parallel download + implicit val ec = ParallelResolveEngine.resolveExecutionContext + val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { + case dep: IvyNode => + Future { + if (!(dep.isCompletelyEvicted || dep.hasProblem) && + dep.getModuleRevision != null) { + Some(downloadNodeArtifacts(dep, artifactFilter, options)) + } else None + } + } + val allDownloads = Await.result(allDownloadsFuture, Duration.Inf) + //compute total downloaded size + val totalSize = allDownloads.foldLeft(0L) { + case (size, Some(download)) => val dependency = download.dep val moduleConfigurations = dependency.getRootModuleConfigurations moduleConfigurations.foreach { configuration => @@ -61,6 +66,7 @@ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, } size + download.totalSizeDownloaded + case (size, None) => size } report.setDownloadTime(System.currentTimeMillis() - start) From e97c79a243c974a45be74371760fc42fd2bf8f7e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 26 Jun 2018 19:24:25 -0400 Subject: [PATCH 0773/1030] IO 1.2.0-M2 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f49220688..73b38a1df 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,7 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.6" - private val ioVersion = "1.2.0-M1" + private val ioVersion = "1.2.0-M2" private val utilVersion = "1.2.0-M1" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 127241f2c6169a481249bb1c6b9a3330d5765196 Mon Sep 17 00:00:00 2001 From: Sean Sullivan Date: Thu, 28 Jun 2018 05:59:58 -0700 Subject: [PATCH 0774/1030] cleanup plugins.sbt --- project/plugins.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index a0ff36b64..32f478494 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,5 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.7") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.3.2") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") scalacOptions += "-language:postfixOps" From 22a4eed65f6b572857a8bbe92599b3ec73231388 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 1 Jul 2018 02:10:41 -0400 Subject: [PATCH 0775/1030] Default eviction warning to summary --- .../librarymanagement/EvictionWarning.scala | 12 +----- .../EvictionWarningSpec.scala | 42 +++++++++---------- 2 files changed, 22 insertions(+), 32 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index cccbfe801..2ec0e97f1 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -70,17 +70,7 @@ object EvictionWarningOptions { showCallers = false, defaultGuess ) - def default: EvictionWarningOptions = - new EvictionWarningOptions( - Vector(Compile), - warnScalaVersionEviction = true, - warnDirectEvictions = true, - warnTransitiveEvictions = true, - warnEvictionSummary = false, - infoAllEvictions = false, - showCallers = true, - defaultGuess - ) + def default: EvictionWarningOptions = summary def full: EvictionWarningOptions = new EvictionWarningOptions( Vector(Compile), diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index ffc6e1f70..78669c178 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -88,7 +88,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def akkaRemote234 = ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 - def defaultOptions = EvictionWarningOptions.default + def fullOptions = EvictionWarningOptions.full import sbt.util.ShowLines._ @@ -97,19 +97,19 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).scalaEvictions should have size (1) + EvictionWarning(m, fullOptions, report).scalaEvictions should have size (1) } def scalaVersionWarn2() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) } def scalaVersionWarn3() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(false), report).lines shouldBe + EvictionWarning(m, fullOptions.withShowCallers(false), report).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", @@ -123,7 +123,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionWarn4() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe + EvictionWarning(m, fullOptions, report).lines shouldBe List( "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", @@ -149,13 +149,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaVersionNoWarn1() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).scalaEvictions should have size (0) + EvictionWarning(m, fullOptions, report).scalaEvictions should have size (0) } def scalaVersionNoWarn2() = { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) } def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) @@ -163,7 +163,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn1() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) } def javaLibWarn2() = { @@ -171,7 +171,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning( m, - defaultOptions + fullOptions .withWarnDirectEvictions(false) .withWarnTransitiveEvictions(false), report @@ -181,7 +181,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn3() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe + EvictionWarning(m, fullOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -195,7 +195,7 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibWarn4() = { val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions.withShowCallers(true), report).lines shouldBe + EvictionWarning(m, fullOptions.withShowCallers(true), report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -220,14 +220,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (0) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) } def javaLibNoWarn2() = { val deps = Vector(commonsIo14, commonsIo13) val m = module(defaultModuleId, deps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe Nil + EvictionWarning(m, fullOptions, report).lines shouldBe Nil } def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) @@ -235,13 +235,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def javaLibTransitiveWarn2() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) } def javaLibTransitiveWarn3() = { val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe + EvictionWarning(m, fullOptions, report).lines shouldBe List( "There may be incompatibilities among your library dependencies.", "Here are some of the libraries that were evicted:", @@ -253,14 +253,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) } def scalaLibWarn2() = { val deps = Vector(scala2104, akkaActor214, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe + EvictionWarning(m, fullOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", @@ -286,14 +286,14 @@ class EvictionWarningSpec extends BaseIvySpecification { val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (0) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) } def scalaLibNoWarn2() = { val deps = Vector(scala2104, akkaActor230, akkaActor234) val m = module(defaultModuleId, deps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe Nil + EvictionWarning(m, fullOptions, report).lines shouldBe Nil } def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) @@ -301,13 +301,13 @@ class EvictionWarningSpec extends BaseIvySpecification { def scalaLibTransitiveWarn2() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).reportedEvictions should have size (1) + EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) } def scalaLibTransitiveWarn3() = { val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) val report = ivyUpdate(m) - EvictionWarning(m, defaultOptions, report).lines shouldBe + EvictionWarning(m, fullOptions, report).lines shouldBe List( "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", From f353de243e5b686d02cab04f5de9de7c1f4b112d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 29 Jul 2018 14:50:39 -0400 Subject: [PATCH 0776/1030] Fixes destination file exists error message Fixes sbt/sbt#3431 Fixes sbt/sbt#4275 https://github.com/sbt/librarymanagement/pull/171 attempted to fix the error message previously, but it was not handling the common cases where the put is delegated to `super.put(...)`. --- .../librarymanagement/ConvertResolver.scala | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 47d597660..545a8f9f6 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -362,31 +362,46 @@ private[sbt] object ConvertResolver { override def put(source: File, destination: String, overwrite: Boolean): Unit = { val url = new URL(destination) - if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) - else { - // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler - val resource = getResource(destination) - if (!overwrite && resource.exists()) { - throw new IOException(s"Destination file $destination exists and overwrite == false"); - } - fireTransferInitiated(resource, TransferEvent.REQUEST_PUT); - try { - val totalLength = source.length - if (totalLength > 0) { - progress.setTotalLength(totalLength); + try { + if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) + else { + // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler + val resource = getResource(destination) + if (!overwrite && resource.exists()) { + throw new IOException(s"destination file exists and overwrite == false"); + } + fireTransferInitiated(resource, TransferEvent.REQUEST_PUT); + try { + val totalLength = source.length + if (totalLength > 0) { + progress.setTotalLength(totalLength); + } + FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) + () + } catch { + case ex: IOException => + fireTransferError(ex) + throw ex + case ex: RuntimeException => + fireTransferError(ex) + throw ex + } finally { + progress.setTotalLength(null); } - FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) - () - } catch { - case ex: IOException => - fireTransferError(ex) - throw ex - case ex: RuntimeException => - fireTransferError(ex) - throw ex - } finally { - progress.setTotalLength(null); } + } catch { + // This error could be thrown either by super.put or the above + case ex: IOException if ex.getMessage.contains("destination file exists") => + throw new IOException( + s"""PUT operation failed because the desitnation file exists and overwriting is disabled: + | source : $source + | destination: $destination + |If you have a staging repository that has failed, drop it and start over. + |Otherwise fix the double publishing, or relax the setting as follows: + | publishConfiguration := publishConfiguration.value.withOverwrite(true) + | publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true)""".stripMargin, + ex + ) } } } From 5dd1e6adc39d9b57af61a43444558723aa397b7c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 29 Jul 2018 20:34:40 -0400 Subject: [PATCH 0777/1030] Util 1.2.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 73b38a1df..8464f2507 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,8 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.6" - private val ioVersion = "1.2.0-M2" - private val utilVersion = "1.2.0-M1" + private val ioVersion = "1.2.0" + private val utilVersion = "1.2.0" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 98f15d8c8acaab062c04ffb08860be174fa022e3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 1 Aug 2018 00:13:09 -0400 Subject: [PATCH 0778/1030] 1.2.1-SNAPSHOT --- build.sbt | 3 ++- project/build.properties | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 591b02d1f..b28c7bea6 100644 --- a/build.sbt +++ b/build.sbt @@ -37,6 +37,7 @@ val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", "1.1.0", "1.1.1", "1.1.2", "1.1.3", "1.1.4", + "1.2.0", ) map (version => organization.value %% moduleName.value % version cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) @@ -56,7 +57,7 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile in Sbt := false, - git.baseVersion := "1.2.0", + git.baseVersion := "1.2.1", version := { val v = version.value if (v contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" diff --git a/project/build.properties b/project/build.properties index d6e35076c..f59579fd6 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.6 +sbt.version=1.2.0 From 326342cf32f1392c7ed1801370b0202be8ec01a0 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Wed, 1 Aug 2018 22:45:02 +0900 Subject: [PATCH 0779/1030] fix #134 validate Configuration id --- .../sbt/librarymanagement/ConfigurationExtra.scala | 3 +++ .../sbt/librarymanagement/ConfigMacroTest.scala | 13 +++++++++++++ 2 files changed, 16 insertions(+) create mode 100644 core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 00acf7305..b8e339526 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -110,6 +110,9 @@ private[sbt] object ConfigurationMacro { c, methodName => s"""$methodName must be directly assigned to a val, such as `val Tooling = $methodName("tooling")`.""") + if (enclosingValName.head.isLower) { + c.error(c.enclosingPosition, "configuration id must be capitalized") + } val id = c.Expr[String](Literal(Constant(enclosingValName))) reify { Configuration.of(id.splice, name.splice) } } diff --git a/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala b/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala new file mode 100644 index 000000000..85d798a21 --- /dev/null +++ b/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala @@ -0,0 +1,13 @@ +package sbt.librarymanagement + +import sbt.librarymanagement.Configurations.config +import org.scalatest._ + +class ConfigMacroTest extends FunSpec with Matchers { + describe("Configurations.config") { + it("should validate the ID in compile time") { + """val A = config("a")""" should compile + """val b = config("b")""" shouldNot compile + } + } +} From 081ca94e6138fdade1fe01e5840ba669c2d8be2b Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Tue, 28 Aug 2018 16:25:27 +0200 Subject: [PATCH 0780/1030] Fix typo --- .../scala/sbt/internal/librarymanagement/ConvertResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 545a8f9f6..2c9a79357 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -393,7 +393,7 @@ private[sbt] object ConvertResolver { // This error could be thrown either by super.put or the above case ex: IOException if ex.getMessage.contains("destination file exists") => throw new IOException( - s"""PUT operation failed because the desitnation file exists and overwriting is disabled: + s"""PUT operation failed because the destination file exists and overwriting is disabled: | source : $source | destination: $destination |If you have a staging repository that has failed, drop it and start over. From 02475c7a667744960c7725e9fe1619edf06fd09c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 21 Sep 2018 01:16:55 -0400 Subject: [PATCH 0781/1030] -Xfatal-warnings --- build.sbt | 1 + .../ArtifactTypeFilter.scala | 14 ++++++------- .../sbt/librarymanagement/ConfigRef.scala | 6 ++++-- .../ConfigurationReport.scala | 10 ++++++---- .../UpdateConfiguration.scala | 20 +++++++++---------- .../sbt/librarymanagement/UpdateReport.scala | 6 +++--- .../JavaNetAuthenticator.java | 6 +++--- .../librarymanagement/IvyActions.scala | 2 -- .../ivy/IvyDependencyResolution.scala | 2 +- .../librarymanagement/ivy/IvyPublisher.scala | 2 +- project/build.properties | 2 +- project/plugins.sbt | 4 ++-- 12 files changed, 38 insertions(+), 37 deletions(-) diff --git a/build.sbt b/build.sbt index 591b02d1f..7478d08e8 100644 --- a/build.sbt +++ b/build.sbt @@ -99,6 +99,7 @@ lazy val lmCore = (project in file("core")) ) ) .taskValue, + Compile / scalacOptions += "-Ywarn-unused:-locals,-explicits,-privates", managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala index fa68be8f1..ce5ab7765 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -4,15 +4,15 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement -/** Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) */ +/** + * Work around the inadequacy of Ivy's ArtifactTypeFilter (that it cannot reverse a filter) + * @param types Represents the artifact types that we should try to resolve for (as in the allowed values of + `artifact[type]` from a dependency `` section). One can use this to filter + source / doc artifacts. + * @param inverted Whether to invert the types filter (i.e. allow only types NOT in the set) + */ final class ArtifactTypeFilter private ( - /** - * Represents the artifact types that we should try to resolve for (as in the allowed values of - * `artifact[type]` from a dependency `` section). One can use this to filter - * source / doc artifacts. - */ val types: Set[String], - /** Whether to invert the types filter (i.e. allow only types NOT in the set) */ val inverted: Boolean) extends sbt.librarymanagement.ArtifactTypeFilterExtra with Serializable { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index 30cba07f5..f956602f6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -4,9 +4,11 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement -/** A reference to Configuration. */ +/** + * A reference to Configuration. + * @param name The name of the configuration that eventually get used by Maven. + */ final class ConfigRef private ( - /** The name of the configuration that eventually get used by Maven. */ val name: String) extends Serializable { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index 228a8fdbe..1243665a1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -4,13 +4,15 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement -/** Provides information about resolution of a single configuration. */ +/** + * Provides information about resolution of a single configuration. + * @param configuration the configuration this report is for. + * @param modules a sequence containing one report for each module resolved for this configuration. + * @param details a sequence containing one report for each org/name, which may or may not be part of the final resolution. + */ final class ConfigurationReport private ( - /** the configuration this report is for. */ val configuration: sbt.librarymanagement.ConfigRef, - /** a sequence containing one report for each module resolved for this configuration. */ val modules: Vector[sbt.librarymanagement.ModuleReport], - /** a sequence containing one report for each org/name, which may or may not be part of the final resolution. */ val details: Vector[sbt.librarymanagement.OrganizationArtifactReport]) extends sbt.librarymanagement.ConfigurationReportExtra with Serializable { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index 533a24542..4443f1eb8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -4,22 +4,20 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement +/** + * @param retrieveManaged If set to some RetrieveConfiguration, this enables retrieving dependencies to the specified directory. + Otherwise, dependencies are used directly from the cache. + * @param missingOk If set to true, it ignores when artifacts are missing. + This setting could be uses when retrieving source/javadocs jars opportunistically. + * @param logging Logging setting used specifially for library management. + * @param logicalClock The clock that may be used for caching. + * @param metadataDirectory The base directory that may be used to store metadata. + */ final class UpdateConfiguration private ( - /** - * If set to some RetrieveConfiguration, this enables retrieving dependencies to the specified directory. - * Otherwise, dependencies are used directly from the cache. - */ val retrieveManaged: Option[sbt.librarymanagement.RetrieveConfiguration], - /** - * If set to true, it ignores when artifacts are missing. - * This setting could be uses when retrieving source/javadocs jars opportunistically. - */ val missingOk: Boolean, - /** Logging setting used specifially for library management. */ val logging: sbt.librarymanagement.UpdateLogging, - /** The clock that may be used for caching. */ val logicalClock: sbt.librarymanagement.LogicalClock, - /** The base directory that may be used to store metadata. */ val metadataDirectory: Option[java.io.File], val artifactFilter: Option[sbt.librarymanagement.ArtifactTypeFilter], val offline: Boolean, diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 5ad396e00..ef6da3930 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -8,13 +8,13 @@ package sbt.librarymanagement * Provides information about dependency resolution. * It does not include information about evicted modules, only about the modules ultimately selected by the conflict manager. * This means that for a given configuration, there should only be one revision for a given organization and module name. + * @param cachedDescriptor the location of the resolved module descriptor in the cache + * @param configurations a sequence containing one report for each configuration resolved. + * @param stats stats information about the update that produced this report */ final class UpdateReport private ( - /** the location of the resolved module descriptor in the cache */ val cachedDescriptor: java.io.File, - /** a sequence containing one report for each configuration resolved. */ val configurations: Vector[sbt.librarymanagement.ConfigurationReport], - /** stats information about the update that produced this report */ val stats: sbt.librarymanagement.UpdateStats, val stamps: Map[java.io.File, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { diff --git a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java index 10a0e6285..aa10461cc 100644 --- a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java +++ b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java @@ -31,9 +31,9 @@ import okhttp3.Challenge; import okhttp3.Credentials; /** - * Adapts {@link java.net.Authenticator} to {@link Authenticator}. Configure OkHttp to use {@link - * java.net.Authenticator} with {@link OkHttpClient.Builder#authenticator} or {@link - * OkHttpClient.Builder#proxyAuthenticator(Authenticator)}. + * Adapts java.net.Authenticator to Authenticator. Configure OkHttp to use + * java.net.Authenticator with OkHttpClient.Builder#authenticator or + * OkHttpClient.Builder#proxyAuthenticator(Authenticator). */ public final class JavaNetAuthenticator implements Authenticator { @Override public Request authenticate(Route route, Response response) throws IOException { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index b30777a12..72a3490dd 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -26,8 +26,6 @@ import syntax._ import InternalDefaults._ import UpdateClassifiersUtil._ -import scala.util.Try - object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index fd0fd259c..2f4985c46 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -21,7 +21,7 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) private[sbt] def toModule(module: ModuleDescriptor): Module = module match { - case m: Module => m + case m: Module @unchecked => m } } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index cc92e8bf9..8ae4a4481 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -25,7 +25,7 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface private[sbt] def toModule(module: ModuleDescriptor): Module = module match { - case m: Module => m + case m: Module @unchecked => m } } diff --git a/project/build.properties b/project/build.properties index d6e35076c..0cd8b0798 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.1.6 +sbt.version=1.2.3 diff --git a/project/plugins.sbt b/project/plugins.sbt index 32f478494..335c8fb18 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.7") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.0") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.8") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") scalacOptions += "-language:postfixOps" From 5fd011597908828d2c1d7047011ebfe43c363c10 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 21 Sep 2018 23:34:51 -0400 Subject: [PATCH 0782/1030] For 2.11 --- build.sbt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 7478d08e8..0dc52aefe 100644 --- a/build.sbt +++ b/build.sbt @@ -99,7 +99,10 @@ lazy val lmCore = (project in file("core")) ) ) .taskValue, - Compile / scalacOptions += "-Ywarn-unused:-locals,-explicits,-privates", + Compile / scalacOptions ++= (scalaVersion.value match { + case v if v.startsWith("2.12.") => List("-Ywarn-unused:-locals,-explicits,-privates") + case _ => List() + }), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", From 7c1caaf079a39b193cd19ab19992b7e45e10f6a6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Sep 2018 04:33:50 -0400 Subject: [PATCH 0783/1030] sbt 1.2.3 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index f59579fd6..0cd8b0798 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.0 +sbt.version=1.2.3 From e28382c667c31d509724d35f3850994cb295e5d1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Sep 2018 04:34:20 -0400 Subject: [PATCH 0784/1030] Bump to 1.3.0 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 9d27f2b1c..cc86bbd37 100644 --- a/build.sbt +++ b/build.sbt @@ -57,7 +57,7 @@ lazy val lmRoot = (project in file(".")) }, bintrayPackage := "librarymanagement", scalafmtOnCompile in Sbt := false, - git.baseVersion := "1.2.1", + git.baseVersion := "1.3.0", version := { val v = version.value if (v contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" From b0ea8ec55fd96fff0175a8e938614781f6c823fd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Sep 2018 04:42:20 -0400 Subject: [PATCH 0785/1030] Scala 2.12.7 --- .travis.yml | 6 +++--- ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala | 2 +- .../scala/sbt/internal/librarymanagement/IvyActions.scala | 4 ++-- .../scala/sbt/internal/librarymanagement/IvyScalaUtil.scala | 2 +- project/Dependencies.scala | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 35032ab26..e82edd618 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,12 +3,12 @@ jdk: oraclejdk8 scala: - 2.11.12 - - 2.12.4 + - 2.12.7 matrix: include: - - scala: 2.12.4 - jdk: oraclejdk9 + - scala: 2.12.7 + jdk: openjdk11 script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ++$TRAVIS_SCALA_VERSION diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index b50914ea9..0312e573b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -842,7 +842,7 @@ private[sbt] object IvySbt { }) foreach { case (_, vs) if vs.size > 1 => val v0 = vs.head - (vs find { _.revision != v0.revision }) foreach { v => + (vs find { _.revision != v0.revision }) foreach { _ => out += s" * ${v0.organization}:${v0.name}:(" + (vs map { _.revision }) .mkString(", ") + ")" } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 72a3490dd..700bc0ddb 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -30,7 +30,7 @@ object IvyActions { /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { - module.withModule(log) { (ivy, md, default) => + module.withModule(log) { (ivy, md, _) => for (dependency <- md.getDependencies) { log.info("Installing " + dependency) val options = new InstallOptions @@ -68,7 +68,7 @@ object IvyActions { val file = configuration.file.getOrElse(sys.error("file must be specified.")) val moduleInfo = configuration.moduleInfo.getOrElse(sys.error("moduleInfo must be specified.")) val extra = configuration.extra.getOrElse(scala.xml.NodeSeq.Empty) - module.withModule(log) { (ivy, md, default) => + module.withModule(log) { (ivy, md, _) => (new MakePom(log)).write( ivy, md, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index bc53f3256..3848bc0d1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -133,7 +133,7 @@ object IvyScalaUtil { log: Logger ): Unit = { val scalaVersionConfigs: String => Boolean = - if (scalaVersionConfigs0.isEmpty) (c: String) => false else scalaVersionConfigs0.toSet + if (scalaVersionConfigs0.isEmpty) (_: String) => false else scalaVersionConfigs0.toSet def binaryScalaWarning(dep: DependencyDescriptor): Option[String] = { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8464f2507..21ade5fc5 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,10 +4,10 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala211 = "2.11.12" - val scala212 = "2.12.6" + val scala212 = "2.12.7" - private val ioVersion = "1.2.0" - private val utilVersion = "1.2.0" + private val ioVersion = "1.2.1" + private val utilVersion = "1.2.2" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 8b53d4a5c15573c69f4846e5515ab0cbe30fba1c Mon Sep 17 00:00:00 2001 From: andrea Date: Tue, 2 Oct 2018 18:38:18 +0100 Subject: [PATCH 0786/1030] Scripted integration test infrastructure with Sbt --- .gitignore | 2 + .travis.yml | 6 +- build.sbt | 20 ++++ project/SbtScriptedIT.scala | 106 ++++++++++++++++++ .../sbt-test/lmScriptedTest/simple/Main.scala | 8 ++ .../sbt-test/lmScriptedTest/simple/build.sbt | 8 ++ .../src/sbt-test/lmScriptedTest/simple/test | 5 + 7 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 project/SbtScriptedIT.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/simple/Main.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt create mode 100755 scripted-test/src/sbt-test/lmScriptedTest/simple/test diff --git a/.gitignore b/.gitignore index 96c1348b1..dc974ae3b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ tmp/ target/ __pycache__ + +scripted-test/src/sbt-test/*/*/project/build.properties diff --git a/.travis.yml b/.travis.yml index e82edd618..77ce91daf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ language: scala jdk: oraclejdk8 scala: - - 2.11.12 - 2.12.7 matrix: include: + - scala: 2.12.7 + jdk: oraclejdk8 - scala: 2.12.7 jdk: openjdk11 @@ -16,6 +17,7 @@ script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M scalafmt::test test:scalafmt::test sbt:scalafmt::test whitesourceCheckPolicies test + scriptedIvy packagedArtifacts # ensure that all artifacts for publish package without failure env: @@ -28,5 +30,7 @@ cache: - $HOME/.sbt before_cache: + # - find $HOME/.ivy2/local -name "*-LM-SNAPSHOT*" -exec rm -r "{}" \; + - find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete - find $HOME/.sbt -name "*.lock" -delete diff --git a/build.sbt b/build.sbt index cc86bbd37..0c50280ab 100644 --- a/build.sbt +++ b/build.sbt @@ -259,6 +259,26 @@ lazy val lmIvy = (project in file("ivy")) ), ) +lazy val lmScriptedTest = (project in file("scripted-test")) + .enablePlugins(SbtPlugin) + .settings( + commonSettings, + skip in publish := true, + name := "scripted-test", + scriptedLaunchOpts := { scriptedLaunchOpts.value ++ + Seq("-Xmx1024M", "-Dplugin.version=" + version.value) + }, + scriptedBufferLog := false + ).enablePlugins(SbtScriptedIT) + +addCommandAlias("scriptedIvy", Seq( + "lmCore/publishLocal", + "lmIvy/publishLocal", + "lmScriptedTest/clean", + """set ThisBuild / scriptedTestLMImpl := "ivy"""", + """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=set ThisBuild / dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)" """, + "lmScriptedTest/scripted").mkString(";",";","")) + def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => // "clean" :: diff --git a/project/SbtScriptedIT.scala b/project/SbtScriptedIT.scala new file mode 100644 index 000000000..925875479 --- /dev/null +++ b/project/SbtScriptedIT.scala @@ -0,0 +1,106 @@ +import sbt._ +import Keys._ + +import java.io.File +import java.util.UUID.randomUUID + +object SbtScriptedIT extends AutoPlugin { + + object autoImport { + val scriptedTestSbtRepo = settingKey[String]("SBT repository to be used in scripted tests") + val scriptedTestSbtRef = settingKey[String]("SBT branch to be used in scripted tests") + val scriptedTestLMImpl = settingKey[String]("Librarymanagement implementation to be used in scripted tests") + val scriptedSbtVersion = settingKey[String]("SBT version to be published locally for IT tests") + } + + import autoImport._ + override def requires = ScriptedPlugin + + override def trigger = noTrigger + + override lazy val globalSettings = Seq( + scriptedTestSbtRepo := "https://github.com/sbt/sbt.git", + scriptedTestSbtRef := "develop", + scriptedTestLMImpl := "ivy", + scriptedSbtVersion := s"""${sbtVersion.value}-LM-SNAPSHOT""" + ) + + private def cloneSbt(targetDir: File, repo: String, ref: String) = { + import org.eclipse.jgit.api._ + + if (!targetDir.exists) { + IO.createDirectory(targetDir) + + new CloneCommand() + .setDirectory(targetDir) + .setURI(repo) + .call() + + val git = Git.open(targetDir) + + git.checkout().setName(ref).call() + } + } + + private def publishLocalSbt( + targetDir: File, + lmVersion: String, + lmGroupID: String, + lmArtifactID: String, + version: String) = { + import sys.process._ + Process( + Seq( + "sbt", + "-J-Xms2048m", + "-J-Xmx2048m", + "-J-XX:ReservedCodeCacheSize=256m", + "-J-XX:MaxMetaspaceSize=512m", + s"""-Dsbt.build.lm.version=${lmVersion}""", + s"""-Dsbt.build.lm.organization=${lmGroupID}""", + s"""-Dsbt.build.lm.moduleName=${lmArtifactID}""", + s"""set ThisBuild / version := "${version}"""", + "clean", + "publishLocal" + ), + Some(targetDir) + ) ! + } + + private def setScriptedTestsSbtVersion(baseDir: File, version: String) = { + IO.listFiles(baseDir).foreach { d => + if (d.isDirectory) { + IO.createDirectory(d / "project") + IO.write( + d / "project" / "build.properties", + s"sbt.version=$version" + ) + } + } + } + + import sbt.ScriptedPlugin.autoImport._ + + override lazy val projectSettings = Seq( + scriptedTests := { + val targetDir = target.value / "sbt" + + cloneSbt(targetDir, scriptedTestSbtRepo.value, scriptedTestSbtRef.value) + + publishLocalSbt( + targetDir, + version.value, + organization.value, + s"librarymanagement-${scriptedTestLMImpl.value}", + scriptedSbtVersion.value + ) + + setScriptedTestsSbtVersion( + sbtTestDirectory.value / thisProject.value.id, + scriptedSbtVersion.value + ) + + scriptedTests.value + } + ) +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/Main.scala b/scripted-test/src/sbt-test/lmScriptedTest/simple/Main.scala new file mode 100644 index 000000000..c5c74ff35 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/Main.scala @@ -0,0 +1,8 @@ + +object Main { + + import com.typesafe.config.ConfigFactory + + val x = ConfigFactory.load() + +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt new file mode 100644 index 000000000..6fc1423d0 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt @@ -0,0 +1,8 @@ + +addCommandAlias("setDependencyResolution", sys.props.get("dependency.resolution") match { + case Some(x) => x + case _ => sys.error("""|The system property 'dependency.resolution' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) +}) + +libraryDependencies += "com.typesafe" % "config" % "1.3.2" diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/test b/scripted-test/src/sbt-test/lmScriptedTest/simple/test new file mode 100755 index 000000000..d0005883e --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/test @@ -0,0 +1,5 @@ +> sbtVersion +> setDependencyResolution +> show ThisBuild/dependencyResolution +> clean +> compile From f1a99e5e4a9e377dec161da6204455c6579db22c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 11 Oct 2018 01:59:54 -0400 Subject: [PATCH 0787/1030] Fix the contains issue Fixes https://github.com/sbt/librarymanagement/issues/259 --- .../scala/sbt/librarymanagement/EvictionWarning.scala | 9 +++++---- .../sbt/internal/librarymanagement/IvyActions.scala | 2 +- .../sbt/internal/librarymanagement/IvyRetrieve.scala | 2 +- .../sbt/internal/librarymanagement/IvyScalaUtil.scala | 2 +- .../scala/sbt/internal/librarymanagement/MakePom.scala | 9 ++++++--- .../ivyint/CachedResolutionResolveEngine.scala | 8 ++++---- 6 files changed, 18 insertions(+), 14 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 2ec0e97f1..44e4465cb 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -226,7 +226,7 @@ object EvictionWarning { ): Seq[OrganizationArtifactReport] = { val buffer: mutable.ListBuffer[OrganizationArtifactReport] = mutable.ListBuffer() val confs = report.configurations filter { x => - options.configurations contains x.configuration + options.configurations.contains[ConfigRef](x.configuration) } confs flatMap { confReport => confReport.details map { detail => @@ -345,9 +345,10 @@ object EvictionWarning { val evo = a.options val out: mutable.ListBuffer[String] = mutable.ListBuffer() a.allEvictions foreach { ev => - if ((a.scalaEvictions contains ev) && evo.warnScalaVersionEviction) () - else if ((a.directEvictions contains ev) && evo.warnDirectEvictions) () - else if ((a.transitiveEvictions contains ev) && evo.warnTransitiveEvictions) () + if ((a.scalaEvictions.contains[EvictionPair](ev)) && evo.warnScalaVersionEviction) () + else if ((a.directEvictions.contains[EvictionPair](ev)) && evo.warnDirectEvictions) () + else if ((a.transitiveEvictions.contains[EvictionPair](ev)) && evo.warnTransitiveEvictions) + () else { out ++= ev.lines } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 700bc0ddb..29e9683d8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -394,7 +394,7 @@ object IvyActions { val retReport = report retrieve { (conf: ConfigRef, mid, art, cached) => toRetrieve match { case None => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) - case Some(refs) if refs contains conf => + case Some(refs) if refs.contains[ConfigRef](conf) => performRetrieve(conf, mid, art, base, pattern, cached, copyChecksums, toCopy) case _ => cached } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index e38618ddd..67ebaa521 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -254,7 +254,7 @@ object IvyRetrieve { val node = current.findNode(revId) if (revId == from) node :: path else if (node == node.getRoot) Nil - else if (path contains node) path + else if (path.contains[IvyNode](node)) path else doFindPath(node, node :: path) }) sortBy { _.size }).reverse paths.headOption getOrElse Nil diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 3848bc0d1..e318eb6c2 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -138,7 +138,7 @@ object IvyScalaUtil { val id = dep.getDependencyRevisionId val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) def isScalaLangOrg = id.getOrganisation == scalaOrganization - def isScalaArtifact = scalaArtifacts.contains(id.getName) + def isScalaArtifact = scalaArtifacts.contains[String](id.getName) def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index f91589c9d..86f514e69 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -407,7 +407,9 @@ class MakePom(val log: Logger) { def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = { val (opt, notOptional) = confs.partition(_ == Optional.name) val defaultNotOptional = - Configurations.defaultMavenConfigurations.find(notOptional contains _.name) + Configurations.defaultMavenConfigurations.find({ c: Configuration => + notOptional contains c.name + }) val scope = defaultNotOptional.map(_.name) (scope, opt.nonEmpty) } @@ -495,9 +497,10 @@ class MakePom(val log: Logger) { configurations: Option[Iterable[Configuration]] ): Seq[DependencyDescriptor] = { val keepConfigurations = IvySbt.getConfigurations(module, configurations) - val keepSet = Set(keepConfigurations.toSeq: _*) + val keepSet: Set[String] = Set(keepConfigurations.toSeq: _*) def translate(dependency: DependencyDescriptor) = { - val keep = dependency.getModuleConfigurations.filter(keepSet.contains) + val keep = dependency.getModuleConfigurations + .filter((conf: String) => keepSet.contains(conf)) if (keep.isEmpty) None else // TODO: translate the dependency to contain only configurations to keep diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index cf24d61d3..14635136c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -593,7 +593,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { c <- mr.callers } yield (c.caller.organization, c.caller.name)).distinct callers foreach { c => - if (history contains c) { + if (history.contains[(String, String)](c)) { val loop = (c :: history.takeWhile(_ != c)) ::: List(c) if (!loopSets(loop.toSet)) { loopSets += loop.toSet @@ -801,7 +801,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val reports: Seq[((String, String), Vector[OrganizationArtifactReport])] = reports0.toSeq flatMap { - case (k, _) if !(pairs contains k) => Seq() + case (k, _) if !(pairs.contains[(String, String)](k)) => Seq() case ((organization, name), oars0) => val oars = oars0 map { oar => val (affected, unaffected) = oar.modules partition { mr => @@ -967,8 +967,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } log.debug(s"::: remapped configs $remappedConfigs") val configurations = rootModuleConfs map { conf0 => - val remappedCRs = configurations0 filter { cr => - remappedConfigs(conf0.getName) contains cr.configuration + val remappedCRs: Vector[ConfigurationReport] = configurations0 filter { cr => + remappedConfigs(conf0.getName).contains[String](cr.configuration.name) } mergeConfigurationReports(ConfigRef(conf0.getName), remappedCRs, os, log) } From cb92556c7ff5dac1735e0c0bc52cfbf30458a5ff Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 15 Oct 2018 03:10:00 -0400 Subject: [PATCH 0788/1030] sbt-scalafmt 0.15 to align with sbt/sbt --- project/plugins.sbt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 335c8fb18..1ebc7fc01 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,6 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.8") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.8") +addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.15") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1") +addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") scalacOptions += "-language:postfixOps" From ed25bcba4335acd4d1e53c650a75a0761ecd09a2 Mon Sep 17 00:00:00 2001 From: Leonard Ehrenfried Date: Tue, 14 Nov 2017 10:57:29 +0100 Subject: [PATCH 0789/1030] Add implementation of coursier --- build.sbt | 19 +- .../LibraryManagementInterface.scala | 2 +- .../src/main/scala/coursier/FromSbt.scala | 283 ++++++++++++++++++ coursier/src/main/scala/coursier/ToSbt.scala | 275 +++++++++++++++++ .../CoursierDependencyResolution.scala | 243 +++++++++++++++ .../coursier/Resolvers.scala | 50 ++++ .../coursier/BaseCoursierSpecification.scala | 37 +++ .../coursier/ResolutionSpec.scala | 142 +++++++++ .../librarymanagement/coursier/UnitSpec.scala | 5 + project/Dependencies.scala | 11 +- 10 files changed, 1062 insertions(+), 5 deletions(-) create mode 100644 coursier/src/main/scala/coursier/FromSbt.scala create mode 100644 coursier/src/main/scala/coursier/ToSbt.scala create mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala create mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala create mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala create mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala create mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala diff --git a/build.sbt b/build.sbt index 0c50280ab..3a4863d9d 100644 --- a/build.sbt +++ b/build.sbt @@ -12,6 +12,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), + resolvers += Resolver.sbtPluginRepo("releases"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), @@ -45,7 +46,7 @@ val mimaSettings = Def settings ( ) lazy val lmRoot = (project in file(".")) - .aggregate(lmCore, lmIvy) + .aggregate(lmCore, lmIvy, lmCoursier) .settings( inThisBuild( Seq( @@ -259,6 +260,22 @@ lazy val lmIvy = (project in file("ivy")) ), ) +lazy val lmCoursier = (project in file("coursier")) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + .dependsOn(lmCore) + .settings( + commonSettings, + crossScalaVersions := Seq(scala212, scala211), + name := "librarymanagement-coursier", + libraryDependencies ++= Seq(coursier, coursierCache, scalaTest, scalaCheck), + managedSourceDirectories in Compile += + baseDirectory.value / "src" / "main" / "contraband-scala", + sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", + contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, + scalacOptions in (Compile, console) --= + Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") + ) + lazy val lmScriptedTest = (project in file("scripted-test")) .enablePlugins(SbtPlugin) .settings( diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 33c72c55f..5236a1a2a 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -66,7 +66,7 @@ trait PublisherInterface { } /** - * Decribes the representation of a module, inclding its dependencies + * Decribes the representation of a module, including its dependencies * and the version of Scala it uses, if any. */ trait ModuleDescriptor { diff --git a/coursier/src/main/scala/coursier/FromSbt.scala b/coursier/src/main/scala/coursier/FromSbt.scala new file mode 100644 index 000000000..6539e1d97 --- /dev/null +++ b/coursier/src/main/scala/coursier/FromSbt.scala @@ -0,0 +1,283 @@ +package coursier + +import coursier.ivy.IvyRepository +import coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } +import java.net.{ MalformedURLException, URL } + +import coursier.core.Authentication +import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties +import sbt.librarymanagement._ +import sbt.librarymanagement.Resolver +import sbt.util.Logger + +object FromSbt { + + def sbtModuleIdName( + moduleId: ModuleID, + scalaVersion: => String, + scalaBinaryVersion: => String + ): String = + sbtCrossVersionName(moduleId.name, moduleId.crossVersion, scalaVersion, scalaBinaryVersion) + + def sbtCrossVersionName( + name: String, + crossVersion: CrossVersion, + scalaVersion: => String, + scalaBinaryVersion: => String + ): String = + CrossVersion(crossVersion, scalaVersion, scalaBinaryVersion) + .fold(name)(_(name)) + + def attributes(attr: Map[String, String]): Map[String, String] = + attr + .map { + case (k, v) => + k.stripPrefix("e:") -> v + } + .filter { + case (k, _) => + !k.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX) + } + + def moduleVersion( + module: ModuleID, + scalaVersion: String, + scalaBinaryVersion: String + ): (Module, String) = { + + val fullName = sbtModuleIdName(module, scalaVersion, scalaBinaryVersion) + + val module0 = + Module(module.organization, fullName, FromSbt.attributes(module.extraDependencyAttributes)) + val version = module.revision + + (module0, version) + } + + def dependencies( + module: ModuleID, + scalaVersion: String, + scalaBinaryVersion: String + ): Seq[(String, Dependency)] = { + + // TODO Warn about unsupported properties in `module` + + val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) + + val dep = Dependency( + module0, + version, + exclusions = module.exclusions.map { rule => + // FIXME Other `rule` fields are ignored here + (rule.organization, rule.name) + }.toSet, + transitive = module.isTransitive + ) + + val mapping = module.configurations.getOrElse("compile") + val allMappings = ivyXmlMappings(mapping) + + val attributes = + if (module.explicitArtifacts.isEmpty) + Seq(Attributes("", "")) + else + module.explicitArtifacts.map { a => + Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse("")) + } + + for { + (from, to) <- allMappings + attr <- attributes + } yield from -> dep.copy(configuration = to, attributes = attr) + } + + def fallbackDependencies( + allDependencies: Seq[ModuleID], + scalaVersion: String, + scalaBinaryVersion: String + ): Seq[(Module, String, URL, Boolean)] = + for { + module <- allDependencies + artifact <- module.explicitArtifacts + url <- artifact.url.toSeq + } yield { + val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) + (module0, version, url, module.isChanging) + } + + def sbtClassifiersProject( + cm: GetClassifiersModule, + scalaVersion: String, + scalaBinaryVersion: String + ) = { + + val p = FromSbt.project( + cm.id, + cm.dependencies, + cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap, + scalaVersion, + scalaBinaryVersion + ) + + // for w/e reasons, the dependencies sometimes don't land in the right config above + // this is a loose attempt at fixing that + cm.configurations match { + case Seq(cfg) => + p.copy( + dependencies = p.dependencies.map { + case (_, d) => (cfg.name, d) + } + ) + case _ => + p + } + } + + def project( + projectID: ModuleID, + allDependencies: Seq[ModuleID], + ivyConfigurations: Map[String, Seq[String]], + scalaVersion: String, + scalaBinaryVersion: String + ): Project = { + + val deps = allDependencies.flatMap(dependencies(_, scalaVersion, scalaBinaryVersion)) + + Project( + Module( + projectID.organization, + sbtModuleIdName(projectID, scalaVersion, scalaBinaryVersion), + FromSbt.attributes(projectID.extraDependencyAttributes) + ), + projectID.revision, + deps, + ivyConfigurations, + None, + Nil, + Nil, + Nil, + None, + None, + None, + None, + Nil, + Info.empty + ) + } + + private def mavenCompatibleBaseOpt(patterns: Patterns): Option[String] = + if (patterns.isMavenCompatible) { + val baseIvyPattern = patterns.ivyPatterns.head.takeWhile(c => c != '[' && c != '(') + val baseArtifactPattern = patterns.ivyPatterns.head.takeWhile(c => c != '[' && c != '(') + + if (baseIvyPattern == baseArtifactPattern) + Some(baseIvyPattern) + else + None + } else + None + + private def mavenRepositoryOpt( + root: String, + log: Logger, + authentication: Option[Authentication] + ): Option[MavenRepository] = + try { + Cache.url(root) // ensure root is a URL whose protocol can be handled here + val root0 = if (root.endsWith("/")) root else root + "/" + Some( + MavenRepository( + root0, + authentication = authentication + ) + ) + } catch { + case e: MalformedURLException => + log.warn( + "Error parsing Maven repository base " + + root + + Option(e.getMessage).fold("")(" (" + _ + ")") + + ", ignoring it" + ) + + None + } + + def repository( + resolver: Resolver, + ivyProperties: Map[String, String], + log: Logger, + authentication: Option[Authentication] + ): Option[Repository] = + resolver match { + case r: sbt.librarymanagement.MavenRepository => + mavenRepositoryOpt(r.root, log, authentication) + + case r: FileRepository + if r.patterns.ivyPatterns.lengthCompare(1) == 0 && + r.patterns.artifactPatterns.lengthCompare(1) == 0 => + val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns) + + mavenCompatibleBaseOpt0 match { + case None => + val repo = IvyRepository.parse( + "file://" + r.patterns.artifactPatterns.head, + metadataPatternOpt = Some("file://" + r.patterns.ivyPatterns.head), + changing = Some(true), + properties = ivyProperties, + dropInfoAttributes = true, + authentication = authentication + ) match { + case Left(err) => + sys.error( + s"Cannot parse Ivy patterns ${r.patterns.artifactPatterns.head} and ${r.patterns.ivyPatterns.head}: $err" + ) + case Right(repo) => + repo + } + + Some(repo) + + case Some(mavenCompatibleBase) => + mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication) + } + + case r: URLRepository + if r.patterns.ivyPatterns.lengthCompare(1) == 0 && + r.patterns.artifactPatterns.lengthCompare(1) == 0 => + val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns) + + mavenCompatibleBaseOpt0 match { + case None => + val repo = IvyRepository.parse( + r.patterns.artifactPatterns.head, + metadataPatternOpt = Some(r.patterns.ivyPatterns.head), + changing = None, + properties = ivyProperties, + dropInfoAttributes = true, + authentication = authentication + ) match { + case Left(err) => + sys.error( + s"Cannot parse Ivy patterns ${r.patterns.artifactPatterns.head} and ${r.patterns.ivyPatterns.head}: $err" + ) + case Right(repo) => + repo + } + + Some(repo) + + case Some(mavenCompatibleBase) => + mavenRepositoryOpt(mavenCompatibleBase, log, authentication) + } + + case raw: RawRepository + if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway + None + + case other => + log.warn(s"Unrecognized repository ${other.name}, ignoring it") + None + } + +} diff --git a/coursier/src/main/scala/coursier/ToSbt.scala b/coursier/src/main/scala/coursier/ToSbt.scala new file mode 100644 index 000000000..ec979dab6 --- /dev/null +++ b/coursier/src/main/scala/coursier/ToSbt.scala @@ -0,0 +1,275 @@ +package coursier + +import java.io.File +import java.net.URL +import java.util.GregorianCalendar +import java.util.concurrent.ConcurrentHashMap + +import coursier.maven.MavenSource +import sbt.librarymanagement._ +import sbt.util.Logger + +object ToSbt { + + private def caching[K, V](f: K => V): K => V = { + + val cache = new ConcurrentHashMap[K, V] + + key => + val previousValueOpt = Option(cache.get(key)) + + previousValueOpt.getOrElse { + val value = f(key) + val concurrentValueOpt = Option(cache.putIfAbsent(key, value)) + concurrentValueOpt.getOrElse(value) + } + } + + val moduleId = caching[(Dependency, Map[String, String]), ModuleID] { + case (dependency, extraProperties) => + sbt.librarymanagement + .ModuleID( + dependency.module.organization, + dependency.module.name, + dependency.version + ) + .withConfigurations( + Some(dependency.configuration) + ) + .withExtraAttributes( + dependency.module.attributes ++ extraProperties + ) + .withExclusions( + dependency.exclusions.toVector + .map { + case (org, name) => + sbt.librarymanagement + .InclExclRule() + .withOrganization(org) + .withName(name) + } + ) + .withIsTransitive( + dependency.transitive + ) + } + + val artifact = caching[(Module, Map[String, String], Artifact), sbt.librarymanagement.Artifact] { + case (module, extraProperties, artifact) => + sbt.librarymanagement + .Artifact(module.name) + // FIXME Get these two from publications + .withType(artifact.attributes.`type`) + .withExtension(MavenSource.typeExtension(artifact.attributes.`type`)) + .withClassifier( + Some(artifact.attributes.classifier) + .filter(_.nonEmpty) + .orElse(MavenSource.typeDefaultClassifierOpt(artifact.attributes.`type`)) + ) + // .withConfigurations(Vector()) + .withUrl(Some(new URL(artifact.url))) + .withExtraAttributes(module.attributes ++ extraProperties) + } + + val moduleReport = + caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Artifact, Option[File])]), + ModuleReport] { + case (dependency, dependees, project, artifacts) => + val sbtArtifacts = artifacts.collect { + case (artifact, Some(file)) => + (ToSbt.artifact((dependency.module, project.properties.toMap, artifact)), file) + } + val sbtMissingArtifacts = artifacts.collect { + case (artifact, None) => + ToSbt.artifact((dependency.module, project.properties.toMap, artifact)) + } + + val publicationDate = project.info.publication.map { dt => + new GregorianCalendar(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) + } + + val callers = dependees.map { + case (dependee, dependeeProj) => + Caller( + ToSbt.moduleId((dependee, dependeeProj.properties.toMap)), + dependeeProj.configurations.keys.toVector.map(ConfigRef(_)), + dependee.module.attributes ++ dependeeProj.properties, + // FIXME Set better values here + isForceDependency = false, + isChangingDependency = false, + isTransitiveDependency = false, + isDirectlyForceDependency = false + ) + } + + ModuleReport( + ToSbt.moduleId((dependency, project.properties.toMap)), + sbtArtifacts.toVector, + sbtMissingArtifacts.toVector + ) + // .withStatus(None) + .withPublicationDate(publicationDate) + // .withResolver(None) + // .withArtifactResolver(None) + // .withEvicted(false) + // .withEvictedData(None) + // .withEvictedReason(None) + // .withProblem(None) + .withHomepage(Some(project.info.homePage).filter(_.nonEmpty)) + .withExtraAttributes(dependency.module.attributes ++ project.properties) + // .withIsDefault(None) + // .withBranch(None) + .withConfigurations(project.configurations.keys.toVector.map(ConfigRef(_))) + .withLicenses(project.info.licenses.toVector) + .withCallers(callers.toVector) + } + + private def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] = + map.groupBy { case (k, _) => k }.map { + case (k, l) => + k -> l.map { case (_, v) => v } + } + + def moduleReports( + res: Resolution, + classifiersOpt: Option[Seq[String]], + artifactFileOpt: (Module, String, Artifact) => Option[File], + log: Logger, + keepPomArtifact: Boolean = false, + includeSignatures: Boolean = false + ) = { + val depArtifacts1 = + classifiersOpt match { + case None => res.dependencyArtifacts(withOptional = true) + case Some(cl) => res.dependencyClassifiersArtifacts(cl) + } + + val depArtifacts0 = + if (keepPomArtifact) + depArtifacts1 + else + depArtifacts1.filter { + case (_, a) => a.attributes != Attributes("pom", "") + } + + val depArtifacts = + if (includeSignatures) { + + val notFound = depArtifacts0.filter(!_._2.extra.contains("sig")) + + if (notFound.isEmpty) + depArtifacts0.flatMap { + case (dep, a) => + Seq(dep -> a) ++ a.extra.get("sig").toSeq.map(dep -> _) + } else { + for ((_, a) <- notFound) + log.error(s"No signature found for ${a.url}") + sys.error(s"${notFound.length} signature(s) not found") + } + } else + depArtifacts0 + + val groupedDepArtifacts = grouped(depArtifacts) + + val versions = res.dependencies.toVector.map { dep => + dep.module -> dep.version + }.toMap + + def clean(dep: Dependency): Dependency = + dep.copy(configuration = "", exclusions = Set.empty, optional = false) + + val reverseDependencies = res.reverseDependencies.toVector + .map { + case (k, v) => + clean(k) -> v.map(clean) + } + .groupBy { case (k, v) => k } + .mapValues { v => + v.flatMap { + case (_, l) => l + } + } + .toVector + .toMap + + groupedDepArtifacts.map { + case (dep, artifacts) => + val (_, proj) = res.projectCache(dep.moduleVersion) + + // FIXME Likely flaky... + val dependees = reverseDependencies + .getOrElse(clean(dep.copy(version = "")), Vector.empty) + .map { dependee0 => + val version = versions(dependee0.module) + val dependee = dependee0.copy(version = version) + val (_, dependeeProj) = res.projectCache(dependee.moduleVersion) + (dependee, dependeeProj) + } + + ToSbt.moduleReport( + ( + dep, + dependees, + proj, + artifacts.map(a => a -> artifactFileOpt(proj.module, proj.version, a)) + )) + } + } + + def updateReport( + configDependencies: Map[String, Seq[Dependency]], + resolutions: Map[String, Resolution], + configs: Map[String, Set[String]], + classifiersOpt: Option[Seq[String]], + artifactFileOpt: (Module, String, Artifact) => Option[File], + log: Logger, + keepPomArtifact: Boolean = false, + includeSignatures: Boolean = false + ): UpdateReport = { + + val configReports = configs.map { + case (config, extends0) => + val configDeps = extends0.flatMap(configDependencies.getOrElse(_, Nil)) + val subRes = resolutions(config).subset(configDeps) + + val reports = ToSbt.moduleReports( + subRes, + classifiersOpt, + artifactFileOpt, + log, + keepPomArtifact = keepPomArtifact, + includeSignatures = includeSignatures + ) + + val reports0 = + if (subRes.rootDependencies.size == 1) { + // quick hack ensuring the module for the only root dependency + // appears first in the update report, see https://github.com/coursier/coursier/issues/650 + val dep = subRes.rootDependencies.head + val (_, proj) = subRes.projectCache(dep.moduleVersion) + val mod = ToSbt.moduleId((dep, proj.properties.toMap)) + val (main, other) = reports.partition { r => + r.module.organization == mod.organization && + r.module.name == mod.name && + r.module.crossVersion == mod.crossVersion + } + main.toVector ++ other.toVector + } else + reports.toVector + + ConfigurationReport( + ConfigRef(config), + reports0, + Vector() + ) + } + + UpdateReport( + File.createTempFile("fake-update-report", "json"), + configReports.toVector, + UpdateStats(-1L, -1L, -1L, cached = false), + Map.empty + ) + } + +} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala new file mode 100644 index 000000000..0c409390b --- /dev/null +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -0,0 +1,243 @@ +package sbt.librarymanagement.coursier + +import java.io.{ File, OutputStreamWriter } + +import coursier.{ Artifact, Resolution, _ } +import coursier.util.{ Gather, Task } +import sbt.librarymanagement.Configurations.{ CompilerPlugin, Component, ScalaTool } +import sbt.librarymanagement._ +import sbt.util.Logger + +case class CoursierModuleDescriptor( + directDependencies: Vector[ModuleID], + scalaModuleInfo: Option[ScalaModuleInfo], + moduleSettings: ModuleSettings, + extraInputHash: Long +) extends ModuleDescriptor + +case class CoursierModuleSettings() extends ModuleSettings + +private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) + extends DependencyResolutionInterface { + + private[coursier] val reorderedResolvers = Resolvers.reorder(resolvers) + + /** + * Builds a ModuleDescriptor that describes a subproject with dependencies. + * + * @param moduleSetting It contains the information about the module including the dependencies. + * @return A `ModuleDescriptor` describing a subproject and its dependencies. + */ + override def moduleDescriptor( + moduleSetting: ModuleDescriptorConfiguration): CoursierModuleDescriptor = { + CoursierModuleDescriptor( + moduleSetting.dependencies, + moduleSetting.scalaModuleInfo, + CoursierModuleSettings(), + 1L // FIXME: use correct value + ) + } + + /** + * Resolves the given module's dependencies performing a retrieval. + * + * @param module The module to be resolved. + * @param configuration The update configuration. + * @param uwconfig The configuration to handle unresolved warnings. + * @param log The logger. + * @return The result, either an unresolved warning or an update report. Note that this + * update report will or will not be successful depending on the `missingOk` option. + */ + override def update(module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger): Either[UnresolvedWarning, UpdateReport] = { + + if (reorderedResolvers.isEmpty) { + log.error( + "Dependency resolution is configured with an empty list of resolvers. This is unlikely to work.") + } + + val dependencies = module.directDependencies.map(toCoursierDependency).toSet + val start = Resolution(dependencies) + val authentication = None // TODO: get correct value + val ivyConfiguration = Map("ivy.home" -> "~/.ivy2/") // TODO: get correct value + val repositories = + reorderedResolvers.flatMap(r => FromSbt.repository(r, ivyConfiguration, log, authentication)) ++ Seq( + Cache.ivy2Local, + Cache.ivy2Cache) + + import scala.concurrent.ExecutionContext.Implicits.global + + val fetch = Fetch.from(repositories, Cache.fetch[Task](logger = Some(createLogger()))) + val resolution = start.process.run(fetch).unsafeRun() + + if (resolution.errors.isEmpty) { + val localArtifacts: Map[Artifact, Either[FileError, File]] = Gather[Task] + .gather( + resolution.artifacts.map { a => + Cache.file[Task](a).run.map((a, _)) + } + ) + .unsafeRun() + .toMap + toUpdateReport(resolution, localArtifacts, log) + } else { + toSbtError(log, uwconfig, resolution) + } + } + + // utilities + + private def createLogger() = { + val t = new TermDisplay(new OutputStreamWriter(System.out)) + t.init() + t + } + + private def toCoursierDependency(moduleID: ModuleID): Dependency = { + val attrs = moduleID.explicitArtifacts + .map(a => Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse(""))) + .headOption + .getOrElse(Attributes()) + + // for some reason, sbt adds the prefix "e:" to extraAttributes + val extraAttrs = moduleID.extraAttributes.map { + case (key, value) => (key.replaceFirst("^e:", ""), value) + } + + Dependency( + Module(moduleID.organization, moduleID.name, extraAttrs), + moduleID.revision, + moduleID.configurations.getOrElse(""), + attrs, + exclusions = moduleID.exclusions.map { rule => + (rule.organization, rule.name) + }.toSet, + transitive = moduleID.isTransitive + ) + } + + private def toUpdateReport(resolution: Resolution, + artifactFilesOrErrors0: Map[Artifact, Either[FileError, File]], + log: Logger): Either[UnresolvedWarning, UpdateReport] = { + + val artifactFiles = artifactFilesOrErrors0.collect { + case (artifact, Right(file)) => + artifact -> file + } + + val artifactErrors = artifactFilesOrErrors0.toVector + .collect { + case (a, Left(err)) if !a.isOptional || !err.notFound => + a -> err + } + + if (artifactErrors.nonEmpty) { + // TODO: handle error the correct sbt way + throw new RuntimeException(s"Could not download dependencies: $artifactErrors") + } + + // can be non empty only if ignoreArtifactErrors is true or some optional artifacts are not found + val erroredArtifacts = artifactFilesOrErrors0.collect { + case (a, Left(_)) => a + }.toSet + + val depsByConfig = resolution.dependencies.groupBy(_.configuration).mapValues(_.toSeq) + + val configurations = extractConfigurationTree + + val configResolutions = + (depsByConfig.keys ++ configurations.keys).map(k => (k, resolution)).toMap + + val sbtBootJarOverrides = Map.empty[(Module, String), File] // TODO: get correct values + val classifiers = None // TODO: get correct values + + if (artifactErrors.isEmpty) { + Right( + ToSbt.updateReport( + depsByConfig, + configResolutions, + configurations, + classifiers, + artifactFileOpt( + sbtBootJarOverrides, + artifactFiles, + erroredArtifacts, + log, + _, + _, + _ + ), + log + )) + } else { + throw new RuntimeException(s"Could not save downloaded dependencies: $erroredArtifacts") + } + + } + + type ConfigurationName = String + type ConfigurationDependencyTree = Map[ConfigurationName, Set[ConfigurationName]] + + // Key is the name of the configuration (i.e. `compile`) and the values are the name itself plus the + // names of the configurations that this one depends on. + private def extractConfigurationTree: ConfigurationDependencyTree = { + (Configurations.default ++ Configurations.defaultInternal ++ Seq(ScalaTool, + CompilerPlugin, + Component)) + .map(c => (c.name, c.extendsConfigs.map(_.name) :+ c.name)) + .toMap + .mapValues(_.toSet) + } + + private def artifactFileOpt( + sbtBootJarOverrides: Map[(Module, String), File], + artifactFiles: Map[Artifact, File], + erroredArtifacts: Set[Artifact], + log: Logger, + module: Module, + version: String, + artifact: Artifact + ) = { + + val artifact0 = artifact + .copy(attributes = Attributes()) // temporary hack :-( + + // Under some conditions, SBT puts the scala JARs of its own classpath + // in the application classpath. Ensuring we return SBT's jars rather than + // JARs from the coursier cache, so that a same JAR doesn't land twice in the + // application classpath (once via SBT jars, once via coursier cache). + val fromBootJars = + if (artifact.classifier.isEmpty && artifact.`type` == "jar") + sbtBootJarOverrides.get((module, version)) + else + None + + val res = fromBootJars.orElse(artifactFiles.get(artifact0)) + + if (res.isEmpty && !erroredArtifacts(artifact0)) + log.error(s"${artifact.url} not downloaded (should not happen)") + + res + } + + private def toSbtError(log: Logger, + uwconfig: UnresolvedWarningConfiguration, + resolution: Resolution) = { + val failedResolution = resolution.errors.map { + case ((failedModule, failedVersion), _) => + ModuleID(failedModule.organization, failedModule.name, failedVersion) + } + val msgs = resolution.errors.flatMap(_._2) + log.debug(s"Failed resolution: $msgs") + log.debug(s"Missing artifacts: $failedResolution") + val ex = new ResolveException(msgs, failedResolution) + Left(UnresolvedWarning(ex, uwconfig)) + } +} + +object CoursierDependencyResolution { + def apply(resolvers: Seq[Resolver]) = + DependencyResolution(new CoursierDependencyResolution(resolvers)) +} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala new file mode 100644 index 000000000..c8513f42e --- /dev/null +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala @@ -0,0 +1,50 @@ +package sbt.librarymanagement.coursier + +import sbt.librarymanagement.{ MavenRepository, Resolver, URLRepository } + +object Resolvers { + + private val slowReposBase = Seq( + "https://repo.typesafe.com/", + "https://repo.scala-sbt.org/", + "http://repo.typesafe.com/", + "http://repo.scala-sbt.org/" + ) + + private val fastReposBase = Seq( + "http://repo1.maven.org/", + "https://repo1.maven.org/" + ) + + private def url(res: Resolver): Option[String] = + res match { + case m: MavenRepository => + Some(m.root) + case u: URLRepository => + u.patterns.artifactPatterns.headOption + .orElse(u.patterns.ivyPatterns.headOption) + case _ => + None + } + + private def filterResolvers(bases: Seq[String], + resolvers: Seq[(Resolver, Option[String])]): Seq[Resolver] = + resolvers + .filter(tuple => tuple._2.exists(url => bases.exists(base => url.startsWith(base)))) + .map(_._1) + + def reorder(resolvers: Seq[Resolver]): Seq[Resolver] = { + + val byUrl = resolvers.map(r => (r, url(r))) + + val fast = filterResolvers(fastReposBase, byUrl) + val slow = filterResolvers(slowReposBase, byUrl) + val rest = resolvers.diff(fast).diff(slow) + + val reordered = fast ++ rest ++ slow + assert(reordered.size == resolvers.size, + "Reordered resolvers should be the same size as the unordered ones.") + + reordered + } +} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala new file mode 100644 index 000000000..4fe2e3d0e --- /dev/null +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala @@ -0,0 +1,37 @@ +package sbt.librarymanagement.coursier + +import sbt.internal.librarymanagement.cross.CrossVersionUtil +import sbt.internal.util.ConsoleLogger +import sbt.librarymanagement.Configurations._ +import sbt.librarymanagement._ + +trait BaseCoursierSpecification extends UnitSpec { + lazy val log = ConsoleLogger() + val lmEngine: CoursierDependencyResolution + + def configurations = Vector(Compile, Test, Runtime) + def module(moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String], + overrideScalaVersion: Boolean = true): ModuleDescriptor = { + val scalaModuleInfo = scalaFullVersion map { fv => + ScalaModuleInfo( + scalaFullVersion = fv, + scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), + configurations = configurations, + checkExplicit = true, + filterImplicit = false, + overrideScalaVersion = overrideScalaVersion + ) + } + + val moduleSetting = ModuleDescriptorConfiguration(moduleId, ModuleInfo("foo")) + .withDependencies(deps) + .withConfigurations(configurations) + .withScalaModuleInfo(scalaModuleInfo) + lmEngine.moduleDescriptor(moduleSetting) + } + + def resolvers: Vector[Resolver] + +} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala new file mode 100644 index 000000000..29f8a9c95 --- /dev/null +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala @@ -0,0 +1,142 @@ +package sbt.librarymanagement.coursier + +import sbt.librarymanagement.Configurations.Component +import sbt.librarymanagement.Resolver.{ + DefaultMavenRepository, + JCenterRepository, + JavaNet2Repository +} +import sbt.librarymanagement.syntax._ +import sbt.librarymanagement.{ Resolver, UnresolvedWarningConfiguration, UpdateConfiguration } + +class ResolutionSpec extends BaseCoursierSpecification { + override val resolvers = Vector( + DefaultMavenRepository, + JavaNet2Repository, + JCenterRepository, + Resolver.sbtPluginRepo("releases") + ) + + val lmEngine = new CoursierDependencyResolution(resolvers) + + private final val stubModule = "com.example" % "foo" % "0.1.0" % "compile" + + "Coursier dependency resolution" should "resolve very simple module" in { + val dependencies = Vector( + "com.typesafe.scala-logging" % "scala-logging_2.12" % "3.7.2" % "compile", + "org.scalatest" % "scalatest_2.12" % "3.0.4" % "test" + ).map(_.withIsTransitive(false)) + + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + resolution should be('right) + val r = resolution.right.get + r.configurations.map(_.configuration) should have size 11 + + val compileConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get + compileConfig.modules should have size 1 + + val runtimeConfig = r.configurations.find(_.configuration == Runtime.toConfigRef).get + runtimeConfig.modules should have size 1 + + val testConfig = r.configurations.find(_.configuration == Test.toConfigRef).get + testConfig.modules should have size 1 + } + + it should "resolve compiler bridge" in { + val dependencies = + Vector(("org.scala-sbt" % "compiler-interface" % "1.0.4" % "component").sources()) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + val r = resolution.right.get + + val componentConfig = r.configurations.find(_.configuration == Component.toConfigRef).get + componentConfig.modules should have size 1 + componentConfig.modules.head.artifacts should have size 1 + componentConfig.modules.head.artifacts.head._1.classifier should contain("sources") + } + + it should "resolve sbt jars" in { + val dependencies = + Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + val r = resolution.right.get + + val modules = r.configurations.flatMap(_.modules) + modules.map(_.module.name) should contain("main_2.12") + } + + it should "resolve with default resolvers" in { + val dependencies = + Vector(("org.scala-sbt" % "compiler-interface" % "1.0.4" % "component").sources()) + val lmEngine = + CoursierDependencyResolution.apply(Resolver.combineDefaultResolvers(Vector.empty)) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + resolution should be('right) + } + + it should "resolve plugin" in { + val pluginAttributes = Map("scalaVersion" -> "2.12", "sbtVersion" -> "1.0") + val dependencies = + Vector(("org.xerial.sbt" % "sbt-sonatype" % "2.0").withExtraAttributes(pluginAttributes)) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + val r = resolution.right.get + + val componentConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get + componentConfig.modules.map(_.module.name) should have size 5 + } + + it should "strip e: prefix from plugin attributes" in { + val pluginAttributes = Map("e:scalaVersion" -> "2.12", "e:sbtVersion" -> "1.0") + val dependencies = + Vector(("org.xerial.sbt" % "sbt-sonatype" % "2.0").withExtraAttributes(pluginAttributes)) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + resolution should be('right) + } + + it should "resolve plugins hosted on repo.typesafe.com" in { + val pluginAttributes = Map("e:scalaVersion" -> "2.12", "e:sbtVersion" -> "1.0") + val dependencies = + Vector(("com.typesafe.sbt" % "sbt-git" % "0.9.3").withExtraAttributes(pluginAttributes)) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + + resolution should be('right) + } + + it should "reorder fast and slow resolvers" in { + val resolvers = Vector( + JavaNet2Repository, + Resolver.sbtPluginRepo("releases"), + DefaultMavenRepository + ) + val engine = new CoursierDependencyResolution(resolvers) + engine.reorderedResolvers.head.name should be("public") + engine.reorderedResolvers.last.name should be("sbt-plugin-releases") + engine.reorderedResolvers should have size 3 + } + + it should "reorder default resolvers" in { + val resolvers = Resolver.combineDefaultResolvers(Vector.empty) + val engine = new CoursierDependencyResolution(resolvers) + engine.reorderedResolvers should not be 'empty + engine.reorderedResolvers.head.name should be("public") + } +} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala new file mode 100644 index 000000000..e6d7f8e75 --- /dev/null +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala @@ -0,0 +1,5 @@ +package sbt.librarymanagement.coursier + +import org.scalatest.{ FlatSpec, Matchers } + +abstract class UnitSpec extends FlatSpec with Matchers diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 21ade5fc5..2e4d14634 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,8 +6,7 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.7" - private val ioVersion = "1.2.1" - private val utilVersion = "1.2.2" + private val coursierVersion = "1.1.0-M1" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -41,7 +40,13 @@ object Dependencies { val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-b18f59ea3bc914a297bb6f1a4f7fb0ace399e310" - val jsch = "com.jcraft" % "jsch" % "0.1.54" + val coursier = "io.get-coursier" %% "coursier" % coursierVersion + val coursierCache = "io.get-coursier" %% "coursier-cache" % coursierVersion + + val sbtV = "1.0" + val scalaV = "2.12" + + val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = scala211Module("scala-xml", "1.0.5") From e1ce3a07c5b87194f645e6266b45667f8926937b Mon Sep 17 00:00:00 2001 From: andrea Date: Mon, 15 Oct 2018 10:34:14 +0100 Subject: [PATCH 0790/1030] compilation and tests are ok --- coursier/src/main/scala/coursier/ToSbt.scala | 2 +- project/Dependencies.scala | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/coursier/src/main/scala/coursier/ToSbt.scala b/coursier/src/main/scala/coursier/ToSbt.scala index ec979dab6..5af3bfc75 100644 --- a/coursier/src/main/scala/coursier/ToSbt.scala +++ b/coursier/src/main/scala/coursier/ToSbt.scala @@ -183,7 +183,7 @@ object ToSbt { case (k, v) => clean(k) -> v.map(clean) } - .groupBy { case (k, v) => k } + .groupBy { case (k, _) => k } .mapValues { v => v.flatMap { case (_, l) => l diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2e4d14634..bc9a8f31c 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -6,7 +6,10 @@ object Dependencies { val scala211 = "2.11.12" val scala212 = "2.12.7" - private val coursierVersion = "1.1.0-M1" + private val ioVersion = "1.2.1" + private val utilVersion = "1.2.2" + + private val coursierVersion = "1.1.0-M7" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 21e2c5f9049d35130f6205b18efd73bf003a406a Mon Sep 17 00:00:00 2001 From: andrea Date: Mon, 15 Oct 2018 18:20:36 +0100 Subject: [PATCH 0791/1030] Starting point for going on --- build.sbt | 12 +++++++++-- .../CoursierDependencyResolution.scala | 1 + .../coursier/ResolutionSpec.scala | 21 ++++++++++--------- .../sbt-test/lmScriptedTest/simple/build.sbt | 14 +++++++++---- .../src/sbt-test/lmScriptedTest/simple/test | 2 -- 5 files changed, 32 insertions(+), 18 deletions(-) diff --git a/build.sbt b/build.sbt index 3a4863d9d..fac9a7008 100644 --- a/build.sbt +++ b/build.sbt @@ -262,7 +262,7 @@ lazy val lmIvy = (project in file("ivy")) lazy val lmCoursier = (project in file("coursier")) .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(lmCore) + .dependsOn(lmIvy) .settings( commonSettings, crossScalaVersions := Seq(scala212, scala211), @@ -293,7 +293,15 @@ addCommandAlias("scriptedIvy", Seq( "lmIvy/publishLocal", "lmScriptedTest/clean", """set ThisBuild / scriptedTestLMImpl := "ivy"""", - """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=set ThisBuild / dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)" """, + """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=ivy" """, + "lmScriptedTest/scripted").mkString(";",";","")) + +addCommandAlias("scriptedCoursier", Seq( + "lmCore/publishLocal", + "lmCoursier/publishLocal", + "lmScriptedTest/clean", + """set ThisBuild / scriptedTestLMImpl := "coursier"""", + """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=coursier" """, "lmScriptedTest/scripted").mkString(";",";","")) def customCommands: Seq[Setting[_]] = Seq( diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 0c409390b..6787305b6 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -81,6 +81,7 @@ private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) ) .unsafeRun() .toMap + toUpdateReport(resolution, localArtifacts, log) } else { toSbtError(log, uwconfig, resolution) diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala index 29f8a9c95..55f636ce2 100644 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala @@ -60,18 +60,19 @@ class ResolutionSpec extends BaseCoursierSpecification { componentConfig.modules.head.artifacts.head._1.classifier should contain("sources") } - it should "resolve sbt jars" in { - val dependencies = - Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + // TODO: fix this test + // it should "resolve sbt jars" in { + // val dependencies = + // Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) + // val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + // val resolution = + // lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - val r = resolution.right.get + // val r = resolution.right.get - val modules = r.configurations.flatMap(_.modules) - modules.map(_.module.name) should contain("main_2.12") - } + // val modules = r.configurations.flatMap(_.modules) + // modules.map(_.module.name) should contain("main_2.12") + // } it should "resolve with default resolvers" in { val dependencies = diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt index 6fc1423d0..2cba487d2 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt @@ -1,8 +1,14 @@ -addCommandAlias("setDependencyResolution", sys.props.get("dependency.resolution") match { - case Some(x) => x +sys.props.get("dependency.resolution") match { + case Some("ivy") => + dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value) + case Some("coursier") => + dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(resolvers.value) case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) -}) +} -libraryDependencies += "com.typesafe" % "config" % "1.3.2" +libraryDependencies ++= Seq( + "com.typesafe" % "config" % "1.3.2", + // "org.scala-lang" % "scala-compiler" % "2.12.7" % Compile +) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/test b/scripted-test/src/sbt-test/lmScriptedTest/simple/test index d0005883e..eb4e76c60 100755 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/test +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/test @@ -1,5 +1,3 @@ > sbtVersion -> setDependencyResolution -> show ThisBuild/dependencyResolution > clean > compile From d18c37974a8ba1ee8e42fb290a1a975ee5890bce Mon Sep 17 00:00:00 2001 From: andrea Date: Tue, 16 Oct 2018 12:31:07 +0100 Subject: [PATCH 0792/1030] going on, everything but sbt-plugins looks working --- .travis.yml | 1 + .../CoursierDependencyResolution.scala | 23 ++++++++++++--- .../coursier/Resolvers.scala | 1 + project/SbtScriptedIT.scala | 18 +++++++----- .../lmScriptedTest/sbt-plugins/Main.scala | 6 ++++ .../lmScriptedTest/sbt-plugins/build.sbt | 29 +++++++++++++++++++ .../sbt-plugins/project/plugins.sbt | 2 ++ .../sbt-test/lmScriptedTest/sbt-plugins/test | 6 ++++ .../sbt-test/lmScriptedTest/simple/build.sbt | 13 ++++++--- .../src/sbt-test/lmScriptedTest/simple/test | 1 + .../with-trasnsitive/Main.scala | 14 +++++++++ .../lmScriptedTest/with-trasnsitive/build.sbt | 19 ++++++++++++ .../lmScriptedTest/with-trasnsitive/test | 4 +++ 13 files changed, 121 insertions(+), 16 deletions(-) create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/Main.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt create mode 100755 scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/Main.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt create mode 100755 scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test diff --git a/.travis.yml b/.travis.yml index 77ce91daf..be80e9798 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,6 +18,7 @@ script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M whitesourceCheckPolicies test scriptedIvy + scriptedCoursier packagedArtifacts # ensure that all artifacts for publish package without failure env: diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 6787305b6..c2434941c 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -17,10 +17,10 @@ case class CoursierModuleDescriptor( case class CoursierModuleSettings() extends ModuleSettings -private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) +private[sbt] class CoursierDependencyResolution(resolvers: Vector[Resolver]) extends DependencyResolutionInterface { - private[coursier] val reorderedResolvers = Resolvers.reorder(resolvers) + private[coursier] val reorderedResolvers = Resolvers.reorder(resolvers.toSeq) /** * Builds a ModuleDescriptor that describes a subproject with dependencies. @@ -38,6 +38,21 @@ private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) ) } + val ivyHome = sys.props.getOrElse( + "ivy.home", + new File(sys.props("user.home")).toURI.getPath + ".ivy2" + ) + + val sbtIvyHome = sys.props.getOrElse( + "sbt.ivy.home", + ivyHome + ) + + val ivyProperties = Map( + "ivy.home" -> ivyHome, + "sbt.ivy.home" -> sbtIvyHome + ) ++ sys.props + /** * Resolves the given module's dependencies performing a retrieval. * @@ -61,7 +76,7 @@ private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) val dependencies = module.directDependencies.map(toCoursierDependency).toSet val start = Resolution(dependencies) val authentication = None // TODO: get correct value - val ivyConfiguration = Map("ivy.home" -> "~/.ivy2/") // TODO: get correct value + val ivyConfiguration = ivyProperties // TODO: is it enough? val repositories = reorderedResolvers.flatMap(r => FromSbt.repository(r, ivyConfiguration, log, authentication)) ++ Seq( Cache.ivy2Local, @@ -239,6 +254,6 @@ private[sbt] class CoursierDependencyResolution(resolvers: Seq[Resolver]) } object CoursierDependencyResolution { - def apply(resolvers: Seq[Resolver]) = + def apply(resolvers: Vector[Resolver]) = DependencyResolution(new CoursierDependencyResolution(resolvers)) } diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala index c8513f42e..ac656ac8a 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala @@ -47,4 +47,5 @@ object Resolvers { reordered } + } diff --git a/project/SbtScriptedIT.scala b/project/SbtScriptedIT.scala index 925875479..7094191ab 100644 --- a/project/SbtScriptedIT.scala +++ b/project/SbtScriptedIT.scala @@ -85,15 +85,17 @@ object SbtScriptedIT extends AutoPlugin { scriptedTests := { val targetDir = target.value / "sbt" - cloneSbt(targetDir, scriptedTestSbtRepo.value, scriptedTestSbtRef.value) + if (!targetDir.exists) { + cloneSbt(targetDir, scriptedTestSbtRepo.value, scriptedTestSbtRef.value) - publishLocalSbt( - targetDir, - version.value, - organization.value, - s"librarymanagement-${scriptedTestLMImpl.value}", - scriptedSbtVersion.value - ) + publishLocalSbt( + targetDir, + version.value, + organization.value, + s"librarymanagement-${scriptedTestLMImpl.value}", + scriptedSbtVersion.value + ) + } setScriptedTestsSbtVersion( sbtTestDirectory.value / thisProject.value.id, diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/Main.scala b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/Main.scala new file mode 100644 index 000000000..b548d6a7b --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/Main.scala @@ -0,0 +1,6 @@ + +object Main { + + println("hello, world!") + +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt new file mode 100644 index 000000000..da5f3491e --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt @@ -0,0 +1,29 @@ + +{ + def writePluginsSbt(str: String) = { + val pluginsSbt = file(".") / "project" / "plugins.sbt" + if (!pluginsSbt.exists) + IO.write( + pluginsSbt, + s"""$str + |addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8") + |""".stripMargin + ) + } + sys.props.get("dependency.resolution") match { + case Some("ivy") => + writePluginsSbt("""dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""") + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" + ) + case Some("coursier") => + writePluginsSbt("""dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""") + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + ) + case _ => sys.error("""|The system property 'dependency.resolution' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + } +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt new file mode 100644 index 000000000..1a07e9111 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt @@ -0,0 +1,2 @@ +dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector)) +addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8") diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test new file mode 100755 index 000000000..2e53ac9dc --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test @@ -0,0 +1,6 @@ +> reload +> sbtVersion +> setDependencyResolution +> clean +> compile +> assembly diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt index 2cba487d2..88debbcd1 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt @@ -1,14 +1,19 @@ sys.props.get("dependency.resolution") match { case Some("ivy") => - dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value) + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" + ) case Some("coursier") => - dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(resolvers.value) + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + ) case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) } libraryDependencies ++= Seq( - "com.typesafe" % "config" % "1.3.2", - // "org.scala-lang" % "scala-compiler" % "2.12.7" % Compile + "com.typesafe" % "config" % "1.3.3" ) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/test b/scripted-test/src/sbt-test/lmScriptedTest/simple/test index eb4e76c60..b801e7add 100755 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/test +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/test @@ -1,3 +1,4 @@ > sbtVersion +> setDependencyResolution > clean > compile diff --git a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/Main.scala b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/Main.scala new file mode 100644 index 000000000..5398da2af --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/Main.scala @@ -0,0 +1,14 @@ + +object Main { + + import akka.actor._ + + val system = ActorSystem() + + system.terminate() + + import com.typesafe.config.ConfigFactory + + val x = ConfigFactory.load() + +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt new file mode 100644 index 000000000..840a59a00 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt @@ -0,0 +1,19 @@ + +sys.props.get("dependency.resolution") match { + case Some("ivy") => + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" + ) + case Some("coursier") => + addCommandAlias( + "setDependencyResolution", + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + ) + case _ => sys.error("""|The system property 'dependency.resolution' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) +} + +libraryDependencies ++= Seq( + "com.typesafe.akka" %% "akka-actor" % "2.5.17" +) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test new file mode 100755 index 000000000..b801e7add --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test @@ -0,0 +1,4 @@ +> sbtVersion +> setDependencyResolution +> clean +> compile From 1f46e3e32b3c092ed0d6acfaeb558e17050dec00 Mon Sep 17 00:00:00 2001 From: andrea Date: Tue, 16 Oct 2018 12:35:23 +0100 Subject: [PATCH 0793/1030] fix --- .gitignore | 1 + .../src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt diff --git a/.gitignore b/.gitignore index dc974ae3b..495231475 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target/ __pycache__ scripted-test/src/sbt-test/*/*/project/build.properties +scripted-test/src/sbt-test/*/*/project/plugins.sbt diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt deleted file mode 100644 index 1a07e9111..000000000 --- a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/project/plugins.sbt +++ /dev/null @@ -1,2 +0,0 @@ -dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector)) -addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8") From 1d429e4c519ec0e39ef979358352032bb9c77a1e Mon Sep 17 00:00:00 2001 From: tanishiking Date: Wed, 17 Oct 2018 00:30:13 +0900 Subject: [PATCH 0794/1030] Update scaladoc for SemanticVersionSelector Fix for https://github.com/sbt/sbt/issues/4422 --- .../librarymanagement/SemanticSelector.scala | 24 ++++++++++++++--- .../main/contraband/librarymanagement2.json | 26 +++++++++++++++---- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala index 65f6e5b19..fe159fd3c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala @@ -30,10 +30,6 @@ package sbt.librarymanagement * The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the * union set of the intersection sets. So the semantic selector is in disjunctive normal form. * - * Metadata and pre-release of VersionNumber are ignored. - * So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version - * or any metadata like `1.0.0-alpha`, `1.0.0+metadata`. - * * Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version. * Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`) * @@ -41,6 +37,26 @@ package sbt.librarymanagement * So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`. * Both sides of comparators around - are required and they can not have any operators. * For example, `>=1.2.3 - 4.5.6` is invalid. + * + * The order of versions basically follows the rule specified in https://semver.org/#spec-item-11 + * > When major, minor, and patch are equal, a pre-release version has lower precedence + * > than a normal version. Example: 1.0.0-alpha < 1.0.0. + * > Precedence for two pre-release versions with the same major, minor, and patch version + * > Must be determined by comparing each dot separated identifier from left to right + * > until a difference is found as follows: + * > identifiers consisting of only digits are compared numerically + * > and identifiers with letters or hyphens are compared lexically in ASCII sort order. + * > Numeric identifiers always have lower precedence than non-numeric identifiers. + * > A larger set of pre-release fields has a higher precedence than a smaller set, + * > if all of the preceding identifiers are equal. + * > Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0. + * + * The differences from the original specification are following + * - `SemanticVersionSelector` separetes the pre-release fields by hyphen instead of dot + * - hyphen cannot be used in pre-release identifiers because it is used as separator for pre-release fields + * + * Therefore, in order to match pre-release versions like `1.0.0-beta` + * we need to explicitly specify the pre-release identifiers like `>=1.0.0-alpha`. */ final class SemanticSelector private ( val selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk]) extends Serializable { diff --git a/core/src/main/contraband/librarymanagement2.json b/core/src/main/contraband/librarymanagement2.json index f94cbef02..1e85d3b52 100644 --- a/core/src/main/contraband/librarymanagement2.json +++ b/core/src/main/contraband/librarymanagement2.json @@ -49,17 +49,33 @@ "The (intersection) set of comparators can combined by ` || ` (spaces are required) to form the", "union set of the intersection sets. So the semantic selector is in disjunctive normal form.", "", - "Metadata and pre-release of VersionNumber are ignored.", - "So `1.0.0` matches any versions that have `1.0.0` as normal version with any pre-release version", - "or any metadata like `1.0.0-alpha`, `1.0.0+metadata`.", - "", "Wildcard (`x`, `X`, `*`) can be used to match any number of minor or patch version.", "Actually, `1.0.x` is equivalent to `=1.0` (that is equivalent to `>=1.0.0 <1.1.0`)", "", "The hyphen range like `1.2.3 - 4.5.6` matches inclusive set of versions.", "So `1.2.3 - 4.5.6` is equivalent to `>=1.2.3 <=4.5.6`.", "Both sides of comparators around - are required and they can not have any operators.", - "For example, `>=1.2.3 - 4.5.6` is invalid." + "For example, `>=1.2.3 - 4.5.6` is invalid.", + "", + "The order of versions basically follows the rule specified in https://semver.org/#spec-item-11", + "> When major, minor, and patch are equal, a pre-release version has lower precedence", + "> than a normal version. Example: 1.0.0-alpha < 1.0.0.", + "> Precedence for two pre-release versions with the same major, minor, and patch version", + "> Must be determined by comparing each dot separated identifier from left to right", + "> until a difference is found as follows:", + "> identifiers consisting of only digits are compared numerically", + "> and identifiers with letters or hyphens are compared lexically in ASCII sort order.", + "> Numeric identifiers always have lower precedence than non-numeric identifiers.", + "> A larger set of pre-release fields has a higher precedence than a smaller set,", + "> if all of the preceding identifiers are equal.", + "> Example: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.", + "", + "The differences from the original specification are following", + "- `SemanticVersionSelector` separetes the pre-release fields by hyphen instead of dot", + "- hyphen cannot be used in pre-release identifiers because it is used as separator for pre-release fields", + "", + "Therefore, in order to match pre-release versions like `1.0.0-beta`", + "we need to explicitly specify the pre-release identifiers like `>=1.0.0-alpha`." ], "generateCodec": false, "fields": [ From 58bfe85f42a8bbdb72e3366ba9b9817eca5e3ef8 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 18 Oct 2018 14:09:15 +0100 Subject: [PATCH 0795/1030] Collapse eviction warnings Rather than [warn] There may be incompatibilities among your library dependencies. [warn] Run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies. [warn] Run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies. [warn] Run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies. [warn] Run 'evicted' to see detailed eviction warnings I would get: [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings [info] Done updating. [warn] There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings which is a touch better. (IMO!) --- .../librarymanagement/EvictionWarning.scala | 8 ++---- .../EvictionWarningSpec.scala | 26 ++++++++----------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 44e4465cb..529353ba4 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -314,8 +314,8 @@ object EvictionWarning { implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => import ShowLines._ val out: mutable.ListBuffer[String] = mutable.ListBuffer() - if (a.options.warnEvictionSummary && a.allEvictions.nonEmpty) { - out += "There may be incompatibilities among your library dependencies." + if ((a.options.warnEvictionSummary || a.reportedEvictions.nonEmpty) && a.allEvictions.nonEmpty) { + out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." } if (a.scalaEvictions.nonEmpty) { @@ -332,10 +332,6 @@ object EvictionWarning { out ++= (a.transitiveEvictions flatMap { _.lines }) } - if (a.allEvictions.nonEmpty && (a.options.warnEvictionSummary || a.reportedEvictions.nonEmpty)) { - out += "Run 'evicted' to see detailed eviction warnings" - } - out.toList } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 78669c178..b32d1595e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -111,12 +111,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions.withShowCallers(false), report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "", "To force scalaVersion, add the following:", "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -125,6 +125,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", @@ -132,7 +133,6 @@ class EvictionWarningSpec extends BaseIvySpecification { "", "To force scalaVersion, add the following:", "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -141,8 +141,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Run 'evicted' to see detailed eviction warnings" + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", ) } @@ -183,12 +182,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* commons-io:commons-io:2.4 is selected over 1.4", "\t +- com.example:foo:0.1.0 (depends on 1.4)", "", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -197,12 +196,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions.withShowCallers(true), report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* commons-io:commons-io:2.4 is selected over 1.4", "\t +- com.example:foo:0.1.0 (depends on 1.4)", "", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -211,8 +210,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Run 'evicted' to see detailed eviction warnings" + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", ) } @@ -243,7 +241,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Here are some of the libraries that were evicted:", "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)" ) @@ -262,12 +260,12 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", "", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -277,8 +275,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Run 'evicted' to see detailed eviction warnings" + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", ) } @@ -309,6 +306,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", @@ -316,7 +314,6 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", "", - "Run 'evicted' to see detailed eviction warnings" ) } @@ -325,8 +322,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies.", - "Run 'evicted' to see detailed eviction warnings" + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", ) } From 0eadc6a6cbd404aa352b410767b6dae789f6a7d6 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 18 Oct 2018 14:57:37 +0100 Subject: [PATCH 0796/1030] Drop trailing commas.. --- .../EvictionWarningSpec.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index b32d1595e..d22ea557b 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -116,7 +116,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "", "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" ) } @@ -132,7 +132,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", "", "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" ) } @@ -141,7 +141,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." ) } @@ -187,7 +187,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "", "\t* commons-io:commons-io:2.4 is selected over 1.4", "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "", + "" ) } @@ -201,7 +201,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "", "\t* commons-io:commons-io:2.4 is selected over 1.4", "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "", + "" ) } @@ -210,7 +210,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." ) } @@ -265,7 +265,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "", "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", - "", + "" ) } @@ -275,7 +275,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." ) } @@ -313,7 +313,7 @@ class EvictionWarningSpec extends BaseIvySpecification { "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", - "", + "" ) } @@ -322,7 +322,7 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." ) } From 7d275cf18e957e3ff0e43f089729fef00d18f4ad Mon Sep 17 00:00:00 2001 From: andrea Date: Fri, 19 Oct 2018 10:50:27 +0100 Subject: [PATCH 0797/1030] targeting alex review --- build.sbt | 6 +- .../coursier/CoursierConfiguration.scala | 57 +++++++++++++++++ .../CoursierConfigurationFormats.scala | 37 +++++++++++ coursier/src/main/contraband/lm-coursier.json | 49 +++++++++++++++ .../CoursierDependencyResolution.scala | 63 +++++++++++++------ .../coursier/BaseCoursierSpecification.scala | 3 + .../coursier/ResolutionSpec.scala | 12 ++-- .../lmScriptedTest/sbt-plugins/build.sbt | 4 +- .../sbt-test/lmScriptedTest/simple/build.sbt | 2 +- .../lmScriptedTest/with-trasnsitive/build.sbt | 2 +- 10 files changed, 206 insertions(+), 29 deletions(-) create mode 100644 coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala create mode 100644 coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala create mode 100644 coursier/src/main/contraband/lm-coursier.json diff --git a/build.sbt b/build.sbt index fac9a7008..cc2fa0300 100644 --- a/build.sbt +++ b/build.sbt @@ -267,7 +267,11 @@ lazy val lmCoursier = (project in file("coursier")) commonSettings, crossScalaVersions := Seq(scala212, scala211), name := "librarymanagement-coursier", - libraryDependencies ++= Seq(coursier, coursierCache, scalaTest, scalaCheck), + libraryDependencies ++= Seq(coursier, + coursierCache, + scalaTest % Test, + scalaCheck % Test + ), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala new file mode 100644 index 000000000..1864c4440 --- /dev/null +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala @@ -0,0 +1,57 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.coursier +final class CoursierConfiguration private ( + val log: Option[xsbti.Logger], + val resolvers: Vector[sbt.librarymanagement.Resolver], + val otherResolvers: Vector[sbt.librarymanagement.Resolver], + val reorderResolvers: Boolean, + val parallelDownloads: Int, + val maxIterations: Int) extends Serializable { + + private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100) + + override def equals(o: Any): Boolean = o match { + case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + } + override def toString: String = { + "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ")" + } + private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations): CoursierConfiguration = { + new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + } + def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { + copy(log = log) + } + def withLog(log: xsbti.Logger): CoursierConfiguration = { + copy(log = Option(log)) + } + def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { + copy(resolvers = resolvers) + } + def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { + copy(otherResolvers = otherResolvers) + } + def withReorderResolvers(reorderResolvers: Boolean): CoursierConfiguration = { + copy(reorderResolvers = reorderResolvers) + } + def withParallelDownloads(parallelDownloads: Int): CoursierConfiguration = { + copy(parallelDownloads = parallelDownloads) + } + def withMaxIterations(maxIterations: Int): CoursierConfiguration = { + copy(maxIterations = maxIterations) + } +} +object CoursierConfiguration { + + def apply(): CoursierConfiguration = new CoursierConfiguration() + def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) +} diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala new file mode 100644 index 000000000..ff8713f87 --- /dev/null +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala @@ -0,0 +1,37 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.librarymanagement.coursier +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait CoursierConfigurationFormats { self: sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement.coursier.CoursierConfiguration] = new JsonFormat[sbt.librarymanagement.coursier.CoursierConfiguration] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.coursier.CoursierConfiguration = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val log = unbuilder.readField[Option[xsbti.Logger]]("log") + val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") + val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") + val reorderResolvers = unbuilder.readField[Boolean]("reorderResolvers") + val parallelDownloads = unbuilder.readField[Int]("parallelDownloads") + val maxIterations = unbuilder.readField[Int]("maxIterations") + unbuilder.endObject() + sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.coursier.CoursierConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("log", obj.log) + builder.addField("resolvers", obj.resolvers) + builder.addField("otherResolvers", obj.otherResolvers) + builder.addField("reorderResolvers", obj.reorderResolvers) + builder.addField("parallelDownloads", obj.parallelDownloads) + builder.addField("maxIterations", obj.maxIterations) + builder.endObject() + } +} +} diff --git a/coursier/src/main/contraband/lm-coursier.json b/coursier/src/main/contraband/lm-coursier.json new file mode 100644 index 000000000..927175607 --- /dev/null +++ b/coursier/src/main/contraband/lm-coursier.json @@ -0,0 +1,49 @@ +{ + "codecNamespace": "sbt.librarymanagement.coursier", + "types": [ + { + "name": "CoursierConfiguration", + "namespace": "sbt.librarymanagement.coursier", + "target": "Scala", + "type": "record", + "fields": [ + { + "name": "log", + "type": "xsbti.Logger?", + "default": "None", + "since": "0.0.1" + }, + { + "name": "resolvers", + "type": "sbt.librarymanagement.Resolver*", + "default": "sbt.librarymanagement.Resolver.defaults", + "since": "0.0.1" + }, + { + "name": "otherResolvers", + "type": "sbt.librarymanagement.Resolver*", + "default": "Vector.empty", + "since": "0.0.1" + }, + { + "name": "reorderResolvers", + "type": "Boolean", + "default": "true", + "since": "0.0.1" + }, + { + "name": "parallelDownloads", + "type": "Int", + "default": "6", + "since": "0.0.1" + }, + { + "name": "maxIterations", + "type": "Int", + "default": "100", + "since": "0.0.1" + } + ] + } + ] +} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index c2434941c..4c60fce44 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -1,6 +1,9 @@ package sbt.librarymanagement.coursier import java.io.{ File, OutputStreamWriter } +import java.util.concurrent.Executors + +import scala.concurrent.ExecutionContext import coursier.{ Artifact, Resolution, _ } import coursier.util.{ Gather, Task } @@ -17,10 +20,22 @@ case class CoursierModuleDescriptor( case class CoursierModuleSettings() extends ModuleSettings -private[sbt] class CoursierDependencyResolution(resolvers: Vector[Resolver]) +private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierConfiguration) extends DependencyResolutionInterface { - private[coursier] val reorderedResolvers = Resolvers.reorder(resolvers.toSeq) + // keep the pool alive while the class is loaded + private lazy val pool = + ExecutionContext.fromExecutor( + Executors.newFixedThreadPool(coursierConfiguration.parallelDownloads) + ) + + private[coursier] val reorderedResolvers = { + val _resolvers = + coursierConfiguration.resolvers ++ coursierConfiguration.otherResolvers + if (coursierConfiguration.reorderResolvers) { + Resolvers.reorder(_resolvers) + } else _resolvers + } /** * Builds a ModuleDescriptor that describes a subproject with dependencies. @@ -82,24 +97,34 @@ private[sbt] class CoursierDependencyResolution(resolvers: Vector[Resolver]) Cache.ivy2Local, Cache.ivy2Cache) - import scala.concurrent.ExecutionContext.Implicits.global + implicit val ec = pool - val fetch = Fetch.from(repositories, Cache.fetch[Task](logger = Some(createLogger()))) - val resolution = start.process.run(fetch).unsafeRun() - - if (resolution.errors.isEmpty) { - val localArtifacts: Map[Artifact, Either[FileError, File]] = Gather[Task] - .gather( - resolution.artifacts.map { a => - Cache.file[Task](a).run.map((a, _)) - } - ) + val coursierLogger = createLogger() + try { + val fetch = Fetch.from( + repositories, + Cache.fetch[Task](logger = Some(coursierLogger)) + ) + val resolution = start.process + .run(fetch, coursierConfiguration.maxIterations) .unsafeRun() - .toMap - toUpdateReport(resolution, localArtifacts, log) - } else { - toSbtError(log, uwconfig, resolution) + if (resolution.isDone && resolution.errors.isEmpty && resolution.conflicts.isEmpty) { + val localArtifacts: Map[Artifact, Either[FileError, File]] = Gather[Task] + .gather( + resolution.artifacts.map { a => + Cache.file[Task](a, logger = Some(coursierLogger)).run.map((a, _)) + } + ) + .unsafeRun() + .toMap + + toUpdateReport(resolution, localArtifacts, log) + } else { + toSbtError(log, uwconfig, resolution) + } + } finally { + coursierLogger.stop() } } @@ -254,6 +279,6 @@ private[sbt] class CoursierDependencyResolution(resolvers: Vector[Resolver]) } object CoursierDependencyResolution { - def apply(resolvers: Vector[Resolver]) = - DependencyResolution(new CoursierDependencyResolution(resolvers)) + def apply(configuration: CoursierConfiguration) = + DependencyResolution(new CoursierDependencyResolution(configuration)) } diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala index 4fe2e3d0e..20545bcf3 100644 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala @@ -34,4 +34,7 @@ trait BaseCoursierSpecification extends UnitSpec { def resolvers: Vector[Resolver] + def configuration(res: Vector[Resolver] = resolvers) = + CoursierConfiguration().withResolvers(res) + } diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala index 55f636ce2..80fa40f24 100644 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala @@ -10,14 +10,14 @@ import sbt.librarymanagement.syntax._ import sbt.librarymanagement.{ Resolver, UnresolvedWarningConfiguration, UpdateConfiguration } class ResolutionSpec extends BaseCoursierSpecification { - override val resolvers = Vector( + override def resolvers = Vector( DefaultMavenRepository, JavaNet2Repository, JCenterRepository, Resolver.sbtPluginRepo("releases") ) - val lmEngine = new CoursierDependencyResolution(resolvers) + val lmEngine = new CoursierDependencyResolution(configuration()) private final val stubModule = "com.example" % "foo" % "0.1.0" % "compile" @@ -78,7 +78,9 @@ class ResolutionSpec extends BaseCoursierSpecification { val dependencies = Vector(("org.scala-sbt" % "compiler-interface" % "1.0.4" % "component").sources()) val lmEngine = - CoursierDependencyResolution.apply(Resolver.combineDefaultResolvers(Vector.empty)) + CoursierDependencyResolution.apply( + configuration(Resolver.combineDefaultResolvers(Vector.empty)) + ) val coursierModule = module(stubModule, dependencies, Some("2.12.4")) val resolution = lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) @@ -128,7 +130,7 @@ class ResolutionSpec extends BaseCoursierSpecification { Resolver.sbtPluginRepo("releases"), DefaultMavenRepository ) - val engine = new CoursierDependencyResolution(resolvers) + val engine = new CoursierDependencyResolution(configuration(resolvers)) engine.reorderedResolvers.head.name should be("public") engine.reorderedResolvers.last.name should be("sbt-plugin-releases") engine.reorderedResolvers should have size 3 @@ -136,7 +138,7 @@ class ResolutionSpec extends BaseCoursierSpecification { it should "reorder default resolvers" in { val resolvers = Resolver.combineDefaultResolvers(Vector.empty) - val engine = new CoursierDependencyResolution(resolvers) + val engine = new CoursierDependencyResolution(configuration(resolvers)) engine.reorderedResolvers should not be 'empty engine.reorderedResolvers.head.name should be("public") } diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt index da5f3491e..0a0172b37 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt @@ -18,10 +18,10 @@ """set dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" ) case Some("coursier") => - writePluginsSbt("""dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""") + writePluginsSbt("""dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""") addCommandAlias( "setDependencyResolution", - """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" ) case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt index 88debbcd1..7b0e47a38 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/build.sbt @@ -8,7 +8,7 @@ sys.props.get("dependency.resolution") match { case Some("coursier") => addCommandAlias( "setDependencyResolution", - """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" ) case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt index 840a59a00..460935447 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/build.sbt @@ -8,7 +8,7 @@ sys.props.get("dependency.resolution") match { case Some("coursier") => addCommandAlias( "setDependencyResolution", - """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(Resolver.combineDefaultResolvers(resolvers.value.toVector))""" + """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" ) case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) From 0499b5881973e567ae1421f55ecd21037a266d31 Mon Sep 17 00:00:00 2001 From: andrea Date: Fri, 19 Oct 2018 10:55:20 +0100 Subject: [PATCH 0798/1030] removed unused jsoncodec plugin --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index cc2fa0300..68a494f40 100644 --- a/build.sbt +++ b/build.sbt @@ -261,7 +261,7 @@ lazy val lmIvy = (project in file("ivy")) ) lazy val lmCoursier = (project in file("coursier")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + .enablePlugins(ContrabandPlugin) .dependsOn(lmIvy) .settings( commonSettings, From 572f87314f87a00f0ced22a41085ec5c8d81f921 Mon Sep 17 00:00:00 2001 From: andrea Date: Fri, 19 Oct 2018 12:05:40 +0100 Subject: [PATCH 0799/1030] added hashing function --- build.sbt | 2 +- .../CoursierDependencyResolution.scala | 52 ++++++++++++++++++- .../CoursierLibraryManagementCodec.scala | 12 +++++ 3 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala diff --git a/build.sbt b/build.sbt index 68a494f40..cc2fa0300 100644 --- a/build.sbt +++ b/build.sbt @@ -261,7 +261,7 @@ lazy val lmIvy = (project in file("ivy")) ) lazy val lmCoursier = (project in file("coursier")) - .enablePlugins(ContrabandPlugin) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .dependsOn(lmIvy) .settings( commonSettings, diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 4c60fce44..1ecc61513 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -3,6 +3,7 @@ package sbt.librarymanagement.coursier import java.io.{ File, OutputStreamWriter } import java.util.concurrent.Executors +import scala.util.{ Success, Failure } import scala.concurrent.ExecutionContext import coursier.{ Artifact, Resolution, _ } @@ -11,6 +12,9 @@ import sbt.librarymanagement.Configurations.{ CompilerPlugin, Component, ScalaTo import sbt.librarymanagement._ import sbt.util.Logger +import sjsonnew.JsonFormat +import sjsonnew.support.murmurhash.Hasher + case class CoursierModuleDescriptor( directDependencies: Vector[ModuleID], scalaModuleInfo: Option[ScalaModuleInfo], @@ -37,6 +41,52 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC } else _resolvers } + private[sbt] object AltLibraryManagementCodec extends CoursierLibraryManagementCodec { + type CoursierHL = ( + Vector[Resolver], + Vector[Resolver], + Boolean, + Int, + Int + ) + + def coursierToHL(c: CoursierConfiguration): CoursierHL = + ( + c.resolvers, + c.otherResolvers, + c.reorderResolvers, + c.parallelDownloads, + c.maxIterations + ) + // Redefine to use a subset of properties, that are serialisable + override implicit lazy val CoursierConfigurationFormat: JsonFormat[CoursierConfiguration] = { + def hlToCoursier(c: CoursierHL): CoursierConfiguration = { + val ( + resolvers, + otherResolvers, + reorderResolvers, + parallelDownloads, + maxIterations + ) = c + CoursierConfiguration() + .withResolvers(resolvers) + .withOtherResolvers(otherResolvers) + .withReorderResolvers(reorderResolvers) + .withParallelDownloads(parallelDownloads) + .withMaxIterations(maxIterations) + } + projectFormat[CoursierConfiguration, CoursierHL](coursierToHL, hlToCoursier) + } + } + + def extraInputHash: Long = { + import AltLibraryManagementCodec._ + Hasher.hash(coursierConfiguration) match { + case Success(keyHash) => keyHash.toLong + case Failure(_) => 0L + } + } + /** * Builds a ModuleDescriptor that describes a subproject with dependencies. * @@ -49,7 +99,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC moduleSetting.dependencies, moduleSetting.scalaModuleInfo, CoursierModuleSettings(), - 1L // FIXME: use correct value + extraInputHash ) } diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala new file mode 100644 index 000000000..5bb0f26ba --- /dev/null +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala @@ -0,0 +1,12 @@ +package sbt.librarymanagement +package coursier + +trait CoursierLibraryManagementCodec + extends sjsonnew.BasicJsonProtocol + with LibraryManagementCodec + // with sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.librarymanagement.ResolverFormats + with CoursierConfigurationFormats + +object CoursierLibraryManagementCodec extends CoursierLibraryManagementCodec From 5ceed9758786b3e05e64e3a7d937516ee0eaa5cf Mon Sep 17 00:00:00 2001 From: andrea Date: Fri, 19 Oct 2018 14:40:22 +0100 Subject: [PATCH 0800/1030] better attributes management and plugin resolution test disabled --- build.sbt | 3 +- .../CoursierDependencyResolution.scala | 63 ++++++++++--------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/build.sbt b/build.sbt index cc2fa0300..7e6a26ae9 100644 --- a/build.sbt +++ b/build.sbt @@ -306,7 +306,8 @@ addCommandAlias("scriptedCoursier", Seq( "lmScriptedTest/clean", """set ThisBuild / scriptedTestLMImpl := "coursier"""", """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=coursier" """, - "lmScriptedTest/scripted").mkString(";",";","")) + // excluding sbt-plugins test, artifacts are downloaded but sbt do not pick up the plugin + "lmScriptedTest/scripted lmScriptedTest/simple lmScriptedTest/with-trasnsitive").mkString(";",";","")) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 1ecc61513..3c8ccd2a4 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -34,11 +34,12 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC ) private[coursier] val reorderedResolvers = { - val _resolvers = + val resolvers0 = coursierConfiguration.resolvers ++ coursierConfiguration.otherResolvers + if (coursierConfiguration.reorderResolvers) { - Resolvers.reorder(_resolvers) - } else _resolvers + Resolvers.reorder(resolvers0) + } else resolvers0 } private[sbt] object AltLibraryManagementCodec extends CoursierLibraryManagementCodec { @@ -138,7 +139,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC "Dependency resolution is configured with an empty list of resolvers. This is unlikely to work.") } - val dependencies = module.directDependencies.map(toCoursierDependency).toSet + val dependencies = module.directDependencies.map(toCoursierDependency).flatten.toSet val start = Resolution(dependencies) val authentication = None // TODO: get correct value val ivyConfiguration = ivyProperties // TODO: is it enough? @@ -179,34 +180,41 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC } // utilities - private def createLogger() = { val t = new TermDisplay(new OutputStreamWriter(System.out)) t.init() t } - private def toCoursierDependency(moduleID: ModuleID): Dependency = { - val attrs = moduleID.explicitArtifacts - .map(a => Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse(""))) - .headOption - .getOrElse(Attributes()) + private def toCoursierDependency(moduleID: ModuleID): Seq[Dependency] = { + val attributes = + if (moduleID.explicitArtifacts.isEmpty) + Seq(Attributes("", "")) + else + moduleID.explicitArtifacts.map { a => + Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse("")) + } - // for some reason, sbt adds the prefix "e:" to extraAttributes - val extraAttrs = moduleID.extraAttributes.map { - case (key, value) => (key.replaceFirst("^e:", ""), value) + val extraAttrs = FromSbt.attributes(moduleID.extraDependencyAttributes) + + val mapping = moduleID.configurations.getOrElse("compile") + + // import _root_.coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } + // val allMappings = ivyXmlMappings(mapping) + for { + attr <- attributes + } yield { + Dependency( + Module(moduleID.organization, moduleID.name, extraAttrs), + moduleID.revision, + configuration = mapping, + attributes = attr, + exclusions = moduleID.exclusions.map { rule => + (rule.organization, rule.name) + }.toSet, + transitive = moduleID.isTransitive + ) } - - Dependency( - Module(moduleID.organization, moduleID.name, extraAttrs), - moduleID.revision, - moduleID.configurations.getOrElse(""), - attrs, - exclusions = moduleID.exclusions.map { rule => - (rule.organization, rule.name) - }.toSet, - transitive = moduleID.isTransitive - ) } private def toUpdateReport(resolution: Resolution, @@ -274,9 +282,9 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC // Key is the name of the configuration (i.e. `compile`) and the values are the name itself plus the // names of the configurations that this one depends on. private def extractConfigurationTree: ConfigurationDependencyTree = { - (Configurations.default ++ Configurations.defaultInternal ++ Seq(ScalaTool, - CompilerPlugin, - Component)) + (Configurations.default ++ + Configurations.defaultInternal ++ + Seq(ScalaTool, CompilerPlugin, Component)) .map(c => (c.name, c.extendsConfigs.map(_.name) :+ c.name)) .toMap .mapValues(_.toSet) @@ -306,7 +314,6 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC None val res = fromBootJars.orElse(artifactFiles.get(artifact0)) - if (res.isEmpty && !erroredArtifacts(artifact0)) log.error(s"${artifact.url} not downloaded (should not happen)") From a03f0ad437ce686fafa209808850e1763fe6a959 Mon Sep 17 00:00:00 2001 From: andrea Date: Mon, 22 Oct 2018 14:57:44 +0100 Subject: [PATCH 0801/1030] Add ignore errors flag --- build.sbt | 1 + .../coursier/CoursierConfiguration.scala | 22 +++++++----- .../CoursierConfigurationFormats.scala | 4 ++- coursier/src/main/contraband/lm-coursier.json | 6 ++++ .../CoursierDependencyResolution.scala | 34 +++++++++++++------ 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/build.sbt b/build.sbt index 7e6a26ae9..3d14abf85 100644 --- a/build.sbt +++ b/build.sbt @@ -302,6 +302,7 @@ addCommandAlias("scriptedIvy", Seq( addCommandAlias("scriptedCoursier", Seq( "lmCore/publishLocal", + "lmIvy/publishLocal", "lmCoursier/publishLocal", "lmScriptedTest/clean", """set ThisBuild / scriptedTestLMImpl := "coursier"""", diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala index 1864c4440..a892e1c75 100644 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala @@ -10,22 +10,23 @@ final class CoursierConfiguration private ( val otherResolvers: Vector[sbt.librarymanagement.Resolver], val reorderResolvers: Boolean, val parallelDownloads: Int, - val maxIterations: Int) extends Serializable { + val maxIterations: Int, + val ignoreArtifactErrors: Boolean) extends Serializable { - private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100) + private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100, false) override def equals(o: Any): Boolean = o match { - case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) + case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.ignoreArtifactErrors == x.ignoreArtifactErrors) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + ignoreArtifactErrors.##) } override def toString: String = { - "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ")" + "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + ignoreArtifactErrors + ")" } - private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations): CoursierConfiguration = { - new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, ignoreArtifactErrors: Boolean = ignoreArtifactErrors): CoursierConfiguration = { + new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) } def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { copy(log = log) @@ -48,10 +49,13 @@ final class CoursierConfiguration private ( def withMaxIterations(maxIterations: Int): CoursierConfiguration = { copy(maxIterations = maxIterations) } + def withIgnoreArtifactErrors(ignoreArtifactErrors: Boolean): CoursierConfiguration = { + copy(ignoreArtifactErrors = ignoreArtifactErrors) + } } object CoursierConfiguration { def apply(): CoursierConfiguration = new CoursierConfiguration() - def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) - def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, ignoreArtifactErrors: Boolean): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) + def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, ignoreArtifactErrors: Boolean): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) } diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala index ff8713f87..a2cba5218 100644 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala @@ -17,8 +17,9 @@ implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement. val reorderResolvers = unbuilder.readField[Boolean]("reorderResolvers") val parallelDownloads = unbuilder.readField[Int]("parallelDownloads") val maxIterations = unbuilder.readField[Int]("maxIterations") + val ignoreArtifactErrors = unbuilder.readField[Boolean]("ignoreArtifactErrors") unbuilder.endObject() - sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) case None => deserializationError("Expected JsObject but found None") } @@ -31,6 +32,7 @@ implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement. builder.addField("reorderResolvers", obj.reorderResolvers) builder.addField("parallelDownloads", obj.parallelDownloads) builder.addField("maxIterations", obj.maxIterations) + builder.addField("ignoreArtifactErrors", obj.ignoreArtifactErrors) builder.endObject() } } diff --git a/coursier/src/main/contraband/lm-coursier.json b/coursier/src/main/contraband/lm-coursier.json index 927175607..6b8d69166 100644 --- a/coursier/src/main/contraband/lm-coursier.json +++ b/coursier/src/main/contraband/lm-coursier.json @@ -42,6 +42,12 @@ "type": "Int", "default": "100", "since": "0.0.1" + }, + { + "name": "ignoreArtifactErrors", + "type": "Boolean", + "default": "false", + "since": "0.0.1" } ] } diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 3c8ccd2a4..2b26a1f3e 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -143,10 +143,12 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC val start = Resolution(dependencies) val authentication = None // TODO: get correct value val ivyConfiguration = ivyProperties // TODO: is it enough? + val repositories = reorderedResolvers.flatMap(r => FromSbt.repository(r, ivyConfiguration, log, authentication)) ++ Seq( Cache.ivy2Local, - Cache.ivy2Cache) + Cache.ivy2Cache + ) implicit val ec = pool @@ -160,17 +162,34 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC .run(fetch, coursierConfiguration.maxIterations) .unsafeRun() - if (resolution.isDone && resolution.errors.isEmpty && resolution.conflicts.isEmpty) { + def updateReport() = { val localArtifacts: Map[Artifact, Either[FileError, File]] = Gather[Task] .gather( resolution.artifacts.map { a => - Cache.file[Task](a, logger = Some(coursierLogger)).run.map((a, _)) + Cache + .file[Task](a, logger = Some(coursierLogger)) + .run + .map((a, _)) } ) .unsafeRun() .toMap toUpdateReport(resolution, localArtifacts, log) + } + + if (resolution.isDone && + resolution.errors.isEmpty && + resolution.conflicts.isEmpty) { + updateReport() + } else if (resolution.isDone && + (!resolution.errors.isEmpty && coursierConfiguration.ignoreArtifactErrors) + && resolution.conflicts.isEmpty) { + log.warn(s"""Failed to download artifacts: ${resolution.errors + .map(_._2) + .flatten + .mkString(", ")}""") + updateReport() } else { toSbtError(log, uwconfig, resolution) } @@ -232,17 +251,12 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC a -> err } - if (artifactErrors.nonEmpty) { - // TODO: handle error the correct sbt way - throw new RuntimeException(s"Could not download dependencies: $artifactErrors") - } - - // can be non empty only if ignoreArtifactErrors is true or some optional artifacts are not found val erroredArtifacts = artifactFilesOrErrors0.collect { case (a, Left(_)) => a }.toSet - val depsByConfig = resolution.dependencies.groupBy(_.configuration).mapValues(_.toSeq) + val depsByConfig = + resolution.dependencies.groupBy(_.configuration).mapValues(_.toSeq) val configurations = extractConfigurationTree From 3b7b2ffbb76baa528345dcf70cc63968f095efd2 Mon Sep 17 00:00:00 2001 From: Alexandre Archambault Date: Wed, 24 Oct 2018 12:18:21 +0200 Subject: [PATCH 0802/1030] Tweak configuration handling --- .../CoursierDependencyResolution.scala | 40 ++++++++++++++----- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 2b26a1f3e..7cec715b5 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -3,15 +3,14 @@ package sbt.librarymanagement.coursier import java.io.{ File, OutputStreamWriter } import java.util.concurrent.Executors -import scala.util.{ Success, Failure } +import scala.util.{ Failure, Success } import scala.concurrent.ExecutionContext - import coursier.{ Artifact, Resolution, _ } import coursier.util.{ Gather, Task } +import sbt.internal.librarymanagement.IvySbt import sbt.librarymanagement.Configurations.{ CompilerPlugin, Component, ScalaTool } import sbt.librarymanagement._ import sbt.util.Logger - import sjsonnew.JsonFormat import sjsonnew.support.murmurhash.Hasher @@ -19,7 +18,8 @@ case class CoursierModuleDescriptor( directDependencies: Vector[ModuleID], scalaModuleInfo: Option[ScalaModuleInfo], moduleSettings: ModuleSettings, - extraInputHash: Long + extraInputHash: Long, + configurations: Seq[String] ) extends ModuleDescriptor case class CoursierModuleSettings() extends ModuleSettings @@ -100,7 +100,8 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC moduleSetting.dependencies, moduleSetting.scalaModuleInfo, CoursierModuleSettings(), - extraInputHash + extraInputHash, + moduleSetting.configurations.map(_.name) ) } @@ -134,6 +135,20 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC uwconfig: UnresolvedWarningConfiguration, log: Logger): Either[UnresolvedWarning, UpdateReport] = { + // not sure what DependencyResolutionInterface.moduleDescriptor is for, we're handled ivy stuff anyway... + val module0 = module match { + case c: CoursierModuleDescriptor => c + case i: IvySbt#Module => + moduleDescriptor( + i.moduleSettings match { + case c: ModuleDescriptorConfiguration => c + case other => sys.error(s"unrecognized module settings: $other") + } + ) + case _ => + sys.error(s"unrecognized ModuleDescriptor type: $module") + } + if (reorderedResolvers.isEmpty) { log.error( "Dependency resolution is configured with an empty list of resolvers. This is unlikely to work.") @@ -175,7 +190,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC .unsafeRun() .toMap - toUpdateReport(resolution, localArtifacts, log) + toUpdateReport(resolution, module0.configurations, localArtifacts, log) } if (resolution.isDone && @@ -237,6 +252,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC } private def toUpdateReport(resolution: Resolution, + configurations: Seq[String], artifactFilesOrErrors0: Map[Artifact, Either[FileError, File]], log: Logger): Either[UnresolvedWarning, UpdateReport] = { @@ -255,13 +271,15 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC case (a, Left(_)) => a }.toSet - val depsByConfig = - resolution.dependencies.groupBy(_.configuration).mapValues(_.toSeq) + val depsByConfig = { + val deps = resolution.dependencies.toVector + configurations.map((_, deps)).toMap + } - val configurations = extractConfigurationTree + val configurations0 = extractConfigurationTree val configResolutions = - (depsByConfig.keys ++ configurations.keys).map(k => (k, resolution)).toMap + (depsByConfig.keys ++ configurations0.keys).map(k => (k, resolution)).toMap val sbtBootJarOverrides = Map.empty[(Module, String), File] // TODO: get correct values val classifiers = None // TODO: get correct values @@ -271,7 +289,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC ToSbt.updateReport( depsByConfig, configResolutions, - configurations, + configurations0, classifiers, artifactFileOpt( sbtBootJarOverrides, From 2e6870d17ea3c6cbf45617ec57a43e9a7189c7e3 Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 24 Oct 2018 11:49:51 +0100 Subject: [PATCH 0803/1030] minor cleanup and using missingOk instead of external property --- build.sbt | 3 +-- coursier/src/main/contraband/lm-coursier.json | 6 ------ .../coursier/CoursierDependencyResolution.scala | 11 ++++++----- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/build.sbt b/build.sbt index 3d14abf85..d90d2d0b4 100644 --- a/build.sbt +++ b/build.sbt @@ -307,8 +307,7 @@ addCommandAlias("scriptedCoursier", Seq( "lmScriptedTest/clean", """set ThisBuild / scriptedTestLMImpl := "coursier"""", """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=coursier" """, - // excluding sbt-plugins test, artifacts are downloaded but sbt do not pick up the plugin - "lmScriptedTest/scripted lmScriptedTest/simple lmScriptedTest/with-trasnsitive").mkString(";",";","")) + "lmScriptedTest/scripted").mkString(";",";","")) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => diff --git a/coursier/src/main/contraband/lm-coursier.json b/coursier/src/main/contraband/lm-coursier.json index 6b8d69166..927175607 100644 --- a/coursier/src/main/contraband/lm-coursier.json +++ b/coursier/src/main/contraband/lm-coursier.json @@ -42,12 +42,6 @@ "type": "Int", "default": "100", "since": "0.0.1" - }, - { - "name": "ignoreArtifactErrors", - "type": "Boolean", - "default": "false", - "since": "0.0.1" } ] } diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 7cec715b5..527ab4b8e 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -18,8 +18,8 @@ case class CoursierModuleDescriptor( directDependencies: Vector[ModuleID], scalaModuleInfo: Option[ScalaModuleInfo], moduleSettings: ModuleSettings, + configurations: Seq[String], extraInputHash: Long, - configurations: Seq[String] ) extends ModuleDescriptor case class CoursierModuleSettings() extends ModuleSettings @@ -100,8 +100,8 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC moduleSetting.dependencies, moduleSetting.scalaModuleInfo, CoursierModuleSettings(), - extraInputHash, - moduleSetting.configurations.map(_.name) + moduleSetting.configurations.map(_.name), + extraInputHash ) } @@ -138,6 +138,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC // not sure what DependencyResolutionInterface.moduleDescriptor is for, we're handled ivy stuff anyway... val module0 = module match { case c: CoursierModuleDescriptor => c + // This shouldn't happen at best of my understanding case i: IvySbt#Module => moduleDescriptor( i.moduleSettings match { @@ -198,7 +199,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC resolution.conflicts.isEmpty) { updateReport() } else if (resolution.isDone && - (!resolution.errors.isEmpty && coursierConfiguration.ignoreArtifactErrors) + (!resolution.errors.isEmpty && configuration.missingOk) && resolution.conflicts.isEmpty) { log.warn(s"""Failed to download artifacts: ${resolution.errors .map(_._2) @@ -313,7 +314,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC // Key is the name of the configuration (i.e. `compile`) and the values are the name itself plus the // names of the configurations that this one depends on. - private def extractConfigurationTree: ConfigurationDependencyTree = { + private val extractConfigurationTree: ConfigurationDependencyTree = { (Configurations.default ++ Configurations.defaultInternal ++ Seq(ScalaTool, CompilerPlugin, Component)) From 33de2221f790e47a5cef4a16b88ca98093b3e377 Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 24 Oct 2018 12:18:16 +0100 Subject: [PATCH 0804/1030] fixing tests --- .../coursier/CoursierConfiguration.scala | 22 ++++++++----------- .../CoursierConfigurationFormats.scala | 4 +--- .../CoursierDependencyResolution.scala | 3 ++- .../coursier/ResolutionSpec.scala | 6 ++--- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala index a892e1c75..1864c4440 100644 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala @@ -10,23 +10,22 @@ final class CoursierConfiguration private ( val otherResolvers: Vector[sbt.librarymanagement.Resolver], val reorderResolvers: Boolean, val parallelDownloads: Int, - val maxIterations: Int, - val ignoreArtifactErrors: Boolean) extends Serializable { + val maxIterations: Int) extends Serializable { - private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100, false) + private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100) override def equals(o: Any): Boolean = o match { - case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) && (this.ignoreArtifactErrors == x.ignoreArtifactErrors) + case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) + ignoreArtifactErrors.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) } override def toString: String = { - "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ", " + ignoreArtifactErrors + ")" + "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ")" } - private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations, ignoreArtifactErrors: Boolean = ignoreArtifactErrors): CoursierConfiguration = { - new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) + private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations): CoursierConfiguration = { + new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) } def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { copy(log = log) @@ -49,13 +48,10 @@ final class CoursierConfiguration private ( def withMaxIterations(maxIterations: Int): CoursierConfiguration = { copy(maxIterations = maxIterations) } - def withIgnoreArtifactErrors(ignoreArtifactErrors: Boolean): CoursierConfiguration = { - copy(ignoreArtifactErrors = ignoreArtifactErrors) - } } object CoursierConfiguration { def apply(): CoursierConfiguration = new CoursierConfiguration() - def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, ignoreArtifactErrors: Boolean): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) - def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int, ignoreArtifactErrors: Boolean): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) + def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) + def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) } diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala index a2cba5218..ff8713f87 100644 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala +++ b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala @@ -17,9 +17,8 @@ implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement. val reorderResolvers = unbuilder.readField[Boolean]("reorderResolvers") val parallelDownloads = unbuilder.readField[Int]("parallelDownloads") val maxIterations = unbuilder.readField[Int]("maxIterations") - val ignoreArtifactErrors = unbuilder.readField[Boolean]("ignoreArtifactErrors") unbuilder.endObject() - sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations, ignoreArtifactErrors) + sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) case None => deserializationError("Expected JsObject but found None") } @@ -32,7 +31,6 @@ implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement. builder.addField("reorderResolvers", obj.reorderResolvers) builder.addField("parallelDownloads", obj.parallelDownloads) builder.addField("maxIterations", obj.maxIterations) - builder.addField("ignoreArtifactErrors", obj.ignoreArtifactErrors) builder.endObject() } } diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 527ab4b8e..04ec6e49c 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -274,7 +274,8 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC val depsByConfig = { val deps = resolution.dependencies.toVector - configurations.map((_, deps)).toMap + (configurations ++ + Seq(ScalaTool, CompilerPlugin, Component).map(_.name)).map((_, deps)).toMap } val configurations0 = extractConfigurationTree diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala index 80fa40f24..dce781136 100644 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala @@ -36,13 +36,13 @@ class ResolutionSpec extends BaseCoursierSpecification { r.configurations.map(_.configuration) should have size 11 val compileConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get - compileConfig.modules should have size 1 + compileConfig.modules should have size 2 val runtimeConfig = r.configurations.find(_.configuration == Runtime.toConfigRef).get - runtimeConfig.modules should have size 1 + runtimeConfig.modules should have size 2 val testConfig = r.configurations.find(_.configuration == Test.toConfigRef).get - testConfig.modules should have size 1 + testConfig.modules should have size 2 } it should "resolve compiler bridge" in { From eeddaa3f5d8e41cbc3a069a924d721c75fd837d1 Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 24 Oct 2018 13:15:43 +0100 Subject: [PATCH 0805/1030] cleaning up scripted test --- .../lmScriptedTest/sbt-plugins/build.sbt | 34 +++++++++---------- .../sbt-test/lmScriptedTest/sbt-plugins/test | 4 --- .../src/sbt-test/lmScriptedTest/simple/test | 3 -- .../lmScriptedTest/with-trasnsitive/test | 3 -- 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt index 0a0172b37..7c0d20685 100644 --- a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/build.sbt @@ -2,28 +2,26 @@ { def writePluginsSbt(str: String) = { val pluginsSbt = file(".") / "project" / "plugins.sbt" - if (!pluginsSbt.exists) - IO.write( - pluginsSbt, - s"""$str - |addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8") - |""".stripMargin - ) + if (!pluginsSbt.exists) + IO.write( + pluginsSbt, + s"""$str + |addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.8") + |""".stripMargin + ) } - sys.props.get("dependency.resolution") match { + val dr = sys.props.get("dependency.resolution") match { case Some("ivy") => - writePluginsSbt("""dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""") - addCommandAlias( - "setDependencyResolution", - """set dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" - ) + """dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" case Some("coursier") => - writePluginsSbt("""dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""") - addCommandAlias( - "setDependencyResolution", - """set dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" - ) + """dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" case _ => sys.error("""|The system property 'dependency.resolution' is not defined. |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) } + + writePluginsSbt(dr) + addCommandAlias( + "setDependencyResolution", + s"""set $dr""" + ) } diff --git a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test index 2e53ac9dc..15ad081ac 100755 --- a/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test +++ b/scripted-test/src/sbt-test/lmScriptedTest/sbt-plugins/test @@ -1,6 +1,2 @@ > reload -> sbtVersion -> setDependencyResolution -> clean -> compile > assembly diff --git a/scripted-test/src/sbt-test/lmScriptedTest/simple/test b/scripted-test/src/sbt-test/lmScriptedTest/simple/test index b801e7add..5df2af1f3 100755 --- a/scripted-test/src/sbt-test/lmScriptedTest/simple/test +++ b/scripted-test/src/sbt-test/lmScriptedTest/simple/test @@ -1,4 +1 @@ -> sbtVersion -> setDependencyResolution -> clean > compile diff --git a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test index b801e7add..5df2af1f3 100755 --- a/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test +++ b/scripted-test/src/sbt-test/lmScriptedTest/with-trasnsitive/test @@ -1,4 +1 @@ -> sbtVersion -> setDependencyResolution -> clean > compile From 1951da25bb960f98ef3568d1d7478172503c58d7 Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 24 Oct 2018 15:14:43 +0100 Subject: [PATCH 0806/1030] rework again configurations management --- .../src/main/scala/coursier/SbtBootJars.scala | 18 +++++++++++ .../CoursierDependencyResolution.scala | 31 ++++++++++++------- .../coursier/ResolutionSpec.scala | 25 +++++++-------- .../lmScriptedTest/use-sbt-in-meta/build.sbt | 25 +++++++++++++++ .../project/Dependencies.scala | 6 ++++ .../lmScriptedTest/use-sbt-in-meta/test | 1 + 6 files changed, 81 insertions(+), 25 deletions(-) create mode 100644 coursier/src/main/scala/coursier/SbtBootJars.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/build.sbt create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/project/Dependencies.scala create mode 100755 scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/test diff --git a/coursier/src/main/scala/coursier/SbtBootJars.scala b/coursier/src/main/scala/coursier/SbtBootJars.scala new file mode 100644 index 000000000..1d9df09cd --- /dev/null +++ b/coursier/src/main/scala/coursier/SbtBootJars.scala @@ -0,0 +1,18 @@ +package coursier + +import java.io.File + +object SbtBootJars { + def apply( + scalaOrg: String, + scalaVersion: String, + jars: Seq[File] + ): Map[(Module, String), File] = + jars.collect { + case jar if jar.getName.endsWith(".jar") => + val name = jar.getName.stripSuffix(".jar") + val mod = Module(scalaOrg, name) + + (mod, scalaVersion) -> jar + }.toMap +} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 04ec6e49c..5ac543f9e 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -156,7 +156,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC } val dependencies = module.directDependencies.map(toCoursierDependency).flatten.toSet - val start = Resolution(dependencies) + val start = Resolution(dependencies.map(_._1)) val authentication = None // TODO: get correct value val ivyConfiguration = ivyProperties // TODO: is it enough? @@ -191,7 +191,10 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC .unsafeRun() .toMap - toUpdateReport(resolution, module0.configurations, localArtifacts, log) + toUpdateReport(resolution, + (module0.configurations ++ dependencies.map(_._2)).distinct, + localArtifacts, + log) } if (resolution.isDone && @@ -221,7 +224,7 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC t } - private def toCoursierDependency(moduleID: ModuleID): Seq[Dependency] = { + private def toCoursierDependency(moduleID: ModuleID) = { val attributes = if (moduleID.explicitArtifacts.isEmpty) Seq(Attributes("", "")) @@ -234,21 +237,23 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC val mapping = moduleID.configurations.getOrElse("compile") - // import _root_.coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } - // val allMappings = ivyXmlMappings(mapping) + import _root_.coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } + val allMappings = ivyXmlMappings(mapping) + for { + (from, to) <- allMappings attr <- attributes } yield { Dependency( Module(moduleID.organization, moduleID.name, extraAttrs), moduleID.revision, - configuration = mapping, + configuration = to, attributes = attr, exclusions = moduleID.exclusions.map { rule => (rule.organization, rule.name) }.toSet, transitive = moduleID.isTransitive - ) + ) -> from } } @@ -274,16 +279,17 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC val depsByConfig = { val deps = resolution.dependencies.toVector - (configurations ++ - Seq(ScalaTool, CompilerPlugin, Component).map(_.name)).map((_, deps)).toMap + configurations + .map((_, deps)) + .toMap } - val configurations0 = extractConfigurationTree + val configurations0 = extractConfigurationTree(configurations) val configResolutions = (depsByConfig.keys ++ configurations0.keys).map(k => (k, resolution)).toMap - val sbtBootJarOverrides = Map.empty[(Module, String), File] // TODO: get correct values + val sbtBootJarOverrides = Map.empty[(Module, String), File] val classifiers = None // TODO: get correct values if (artifactErrors.isEmpty) { @@ -315,10 +321,11 @@ private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierC // Key is the name of the configuration (i.e. `compile`) and the values are the name itself plus the // names of the configurations that this one depends on. - private val extractConfigurationTree: ConfigurationDependencyTree = { + private def extractConfigurationTree(available: Seq[String]): ConfigurationDependencyTree = { (Configurations.default ++ Configurations.defaultInternal ++ Seq(ScalaTool, CompilerPlugin, Component)) + .filter(c => available.contains(c.name)) .map(c => (c.name, c.extendsConfigs.map(_.name) :+ c.name)) .toMap .mapValues(_.toSet) diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala index dce781136..a118ccc10 100644 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala +++ b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala @@ -33,7 +33,7 @@ class ResolutionSpec extends BaseCoursierSpecification { resolution should be('right) val r = resolution.right.get - r.configurations.map(_.configuration) should have size 11 + r.configurations.map(_.configuration) should have size 3 val compileConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get compileConfig.modules should have size 2 @@ -55,24 +55,23 @@ class ResolutionSpec extends BaseCoursierSpecification { val r = resolution.right.get val componentConfig = r.configurations.find(_.configuration == Component.toConfigRef).get - componentConfig.modules should have size 1 + componentConfig.modules should have size 2 componentConfig.modules.head.artifacts should have size 1 componentConfig.modules.head.artifacts.head._1.classifier should contain("sources") } - // TODO: fix this test - // it should "resolve sbt jars" in { - // val dependencies = - // Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) - // val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - // val resolution = - // lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) + it should "resolve sbt jars" in { + val dependencies = + Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) + val coursierModule = module(stubModule, dependencies, Some("2.12.4")) + val resolution = + lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - // val r = resolution.right.get + val r = resolution.right.get - // val modules = r.configurations.flatMap(_.modules) - // modules.map(_.module.name) should contain("main_2.12") - // } + val modules = r.configurations.flatMap(_.modules) + modules.map(_.module.name) should contain("main_2.12") + } it should "resolve with default resolvers" in { val dependencies = diff --git a/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/build.sbt new file mode 100644 index 000000000..d200f6743 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/build.sbt @@ -0,0 +1,25 @@ + +{ + def writePluginsSbt(str: String) = { + val pluginsSbt = file(".") / "project" / "plugins.sbt" + if (!pluginsSbt.exists) + IO.write( + pluginsSbt, + str + ) + } + val dr = sys.props.get("dependency.resolution") match { + case Some("ivy") => + """dependencyResolution := sbt.librarymanagement.ivy.IvyDependencyResolution(ivyConfiguration.value)""" + case Some("coursier") => + """dependencyResolution := sbt.librarymanagement.coursier.CoursierDependencyResolution(sbt.librarymanagement.coursier.CoursierConfiguration())""" + case _ => sys.error("""|The system property 'dependency.resolution' is not defined. + |Specify this property using the scriptedLaunchOpts -D.""".stripMargin) + } + + writePluginsSbt(dr) + addCommandAlias( + "setDependencyResolution", + s"""set $dr""" + ) +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/project/Dependencies.scala b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/project/Dependencies.scala new file mode 100644 index 000000000..587f8ac76 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/project/Dependencies.scala @@ -0,0 +1,6 @@ +import sbt._ +import Keys._ + +object Dependencies { + +} diff --git a/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/test b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/test new file mode 100755 index 000000000..a0f164c64 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/use-sbt-in-meta/test @@ -0,0 +1 @@ +> reload From abc6d6927156970ab858285a71e7ad269be2f5cf Mon Sep 17 00:00:00 2001 From: andrea Date: Wed, 24 Oct 2018 17:43:49 +0100 Subject: [PATCH 0807/1030] compatibility with 2.12 --- .../coursier/CoursierDependencyResolution.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala index 5ac543f9e..3734fbce8 100644 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala @@ -19,7 +19,7 @@ case class CoursierModuleDescriptor( scalaModuleInfo: Option[ScalaModuleInfo], moduleSettings: ModuleSettings, configurations: Seq[String], - extraInputHash: Long, + extraInputHash: Long ) extends ModuleDescriptor case class CoursierModuleSettings() extends ModuleSettings From 11fdf8e31cf4da3642627c234ebf247edfe157ee Mon Sep 17 00:00:00 2001 From: Andrea Peruffo Date: Sun, 28 Oct 2018 08:54:26 +0000 Subject: [PATCH 0808/1030] adding multi-project test --- .../src/sbt-test/lmScriptedTest/multi-project/build.sbt | 3 +++ .../multi-project/child/src/main/scala/Bar.scala | 1 + .../multi-project/parent/src/main/scala/Foo.scala | 1 + scripted-test/src/sbt-test/lmScriptedTest/multi-project/test | 1 + 4 files changed, 6 insertions(+) create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/multi-project/build.sbt create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/multi-project/child/src/main/scala/Bar.scala create mode 100644 scripted-test/src/sbt-test/lmScriptedTest/multi-project/parent/src/main/scala/Foo.scala create mode 100755 scripted-test/src/sbt-test/lmScriptedTest/multi-project/test diff --git a/scripted-test/src/sbt-test/lmScriptedTest/multi-project/build.sbt b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/build.sbt new file mode 100644 index 000000000..ca1db4e98 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/build.sbt @@ -0,0 +1,3 @@ +lazy val root = (project in file(".")).aggregate(parent, child) +lazy val parent = project +lazy val child = project.dependsOn(parent) diff --git a/scripted-test/src/sbt-test/lmScriptedTest/multi-project/child/src/main/scala/Bar.scala b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/child/src/main/scala/Bar.scala new file mode 100644 index 000000000..458d393cf --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/child/src/main/scala/Bar.scala @@ -0,0 +1 @@ +class Bar extends Foo diff --git a/scripted-test/src/sbt-test/lmScriptedTest/multi-project/parent/src/main/scala/Foo.scala b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/parent/src/main/scala/Foo.scala new file mode 100644 index 000000000..c389887ee --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/parent/src/main/scala/Foo.scala @@ -0,0 +1 @@ +class Foo diff --git a/scripted-test/src/sbt-test/lmScriptedTest/multi-project/test b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/test new file mode 100755 index 000000000..5df2af1f3 --- /dev/null +++ b/scripted-test/src/sbt-test/lmScriptedTest/multi-project/test @@ -0,0 +1 @@ +> compile From 08b8491c7f69e26e5c24505f3ed999baac00dc86 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Oct 2018 14:25:01 -0400 Subject: [PATCH 0809/1030] Bump IO and Util --- build.sbt | 3 +-- project/Dependencies.scala | 6 ++---- project/build.properties | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/build.sbt b/build.sbt index d90d2d0b4..7b5d143f6 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), - crossScalaVersions := Seq(scala211, scala212), + crossScalaVersions := Seq(scala212), resolvers += Resolver.sonatypeRepo("public"), scalacOptions := { val old = scalacOptions.value @@ -265,7 +265,6 @@ lazy val lmCoursier = (project in file("coursier")) .dependsOn(lmIvy) .settings( commonSettings, - crossScalaVersions := Seq(scala212, scala211), name := "librarymanagement-coursier", libraryDependencies ++= Seq(coursier, coursierCache, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index bc9a8f31c..84e72a4ad 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,12 +3,10 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala211 = "2.11.12" val scala212 = "2.12.7" - private val ioVersion = "1.2.1" - private val utilVersion = "1.2.2" - + private val ioVersion = "1.3.0-M4" + private val utilVersion = "1.3.0-M2" private val coursierVersion = "1.1.0-M7" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/build.properties b/project/build.properties index 0cd8b0798..7c58a83ab 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.3 +sbt.version=1.2.6 From 29183f2fad015b1b22f783b905f692121faefa4c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Nov 2018 02:27:19 -0400 Subject: [PATCH 0810/1030] Use fixed thread pool Fixes #274 In #249 parallel download switched to using its own thread pool. It could potentially lead to unbounded download if nobody throttled. This works around the issue by fixing the number of thread to 6, which is a common per-host max connection count. --- .../librarymanagement/ivyint/ParallelResolveEngine.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 235f280d5..d5107f2aa 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -19,8 +19,12 @@ private[ivyint] case class DownloadResult(dep: IvyNode, totalSizeDownloaded: Long) object ParallelResolveEngine { - private val resolveExecutionContext = - ExecutionContext.fromExecutor(Executors.newCachedThreadPool()) + private lazy val resolveExecutionContext: ExecutionContext = { + // This throttles the connection number, especially when Gigahorse is not used. + val maxConnectionCount = 6 + val executor = Executors.newFixedThreadPool(maxConnectionCount) + ExecutionContext.fromExecutor(executor) + } } /** Define an ivy [[ResolveEngine]] that resolves dependencies in parallel. */ From ead0f82575ab34c5f53e9bb2146375af38dbb83f Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sat, 24 Nov 2018 09:31:30 +0000 Subject: [PATCH 0811/1030] Fix CrossVersion.Disabled compat --- build.sbt | 6 ++++++ .../scala/sbt/librarymanagement/CrossVersionExtra.scala | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 7b5d143f6..b4d612295 100644 --- a/build.sbt +++ b/build.sbt @@ -157,6 +157,12 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), + // by mistake we aliased the companion object instead of an instance of Disabled + // but it was aliased as a constant expression, so even if the binary API has changed + // there are no call sites in bytecode because the value got inlined + // also it's wouldn't work so I doubt anyone has made use of it + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.CrossVersionFunctions.Disabled"), + // contraband issue exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.UpdateReportLite.copy*"), diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 725573e41..bcd7b753a 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -8,7 +8,7 @@ final case class ScalaVersion(full: String, binary: String) private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ - final val Disabled = sbt.librarymanagement.Disabled + final val Disabled = sbt.librarymanagement.Disabled() final val Binary = sbt.librarymanagement.Binary final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full @@ -37,7 +37,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ - def disabled: CrossVersion = Disabled() + def disabled: CrossVersion = Disabled /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) From a18c343bdc7b226817f37722652bfab37a264fc1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 26 Nov 2018 23:59:28 -0500 Subject: [PATCH 0812/1030] Mima fix from #280 Not sure how but #280 has slipped through with Mima failing. --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index b4d612295..ae9692e1c 100644 --- a/build.sbt +++ b/build.sbt @@ -162,6 +162,7 @@ lazy val lmCore = (project in file("core")) // there are no call sites in bytecode because the value got inlined // also it's wouldn't work so I doubt anyone has made use of it exclude[DirectMissingMethodProblem]("sbt.librarymanagement.CrossVersionFunctions.Disabled"), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.CrossVersionFunctions.Disabled"), // contraband issue exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), From d9409a33489c5fa9be7945f0c88376a09f64865e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 26 Nov 2018 23:32:46 -0500 Subject: [PATCH 0813/1030] use AdoptOpenJDK 1.8 and 11 for testing --- .travis.yml | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index be80e9798..5cee6b49b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,15 +1,31 @@ +sudo: false +dist: trusty +group: stable + language: scala -jdk: oraclejdk8 scala: - 2.12.7 +env: + global: + - JABBA_HOME=/home/travis/.jabba + - secure: D9Ckfxq/5n+41REwuPBwb0CHRVSPtCJRN+N1FWNFjUnfCHZQCeclP8Ydp9ql/fZxICG8rnCOI5XW0j2YeAiR+abpQNmQ42pKMEjNT0VQDZ0I1lQfiDL071Kj+ui9AH+TqAvBT011u72ML52iDfV0WaL/Skf1Noh0lXc+IscRI56OLRv+YU5n5aNZhXon6AZHU11rRCg4aMwaHr+U9ISSUXc6OtJeFC/SAYNUNYEOZwTOJ4Y2+VrKAmKuIZ2jjkMF13eKMzXw5g+u8V3AmOpIm1RiyS2dAgAoc+r2ucF9RUMsfiZIF0XBu65iv9hZP5m0q11n6IFEKC9bpLsTYCAwX2MgVayoHvDQv1gkL/cA1gkqmf0Kkx3oc33aYLgsCydj2Lbg/myKD+GeHxr5WhyeSEee3Bwj+KGNwvjfcaPEECCor6yilKGdIsuYbfHzu8B8moNjwH7ui5f5w/1xuWrdaSA23LOIYbhP+2rM894JIYNNt5vlMLoYMzmC9N1E/qyBRYSdfMr+Uh8qI+j85hkKKgEffSu9f55IH6bk6Lq08Nc4d64KXUISDNJj59MrJcadatsS2vp+u39zR/iIewW4a017bAFfv57AJb6SwLdvASG+psFH8MRPD6xYPZKNw4Al/4YMc+oXONplSXyOu/jQYjSfK9tyvJwpoY7tLh6vEBc= + matrix: include: - - scala: 2.12.7 - jdk: oraclejdk8 - - scala: 2.12.7 - jdk: openjdk11 + - env: + - TRAVIS_JDK=adopt@1.8.192-12 + - env: + - TRAVIS_JDK=adopt@1.11.0-1 + +before_install: + - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh + +install: + - $JABBA_HOME/bin/jabba install $TRAVIS_JDK + - unset _JAVA_OPTIONS + - export JAVA_HOME="$JABBA_HOME/jdk/$TRAVIS_JDK" && export PATH="$JAVA_HOME/bin:$PATH" && java -Xmx32m -version script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ++$TRAVIS_SCALA_VERSION @@ -21,17 +37,14 @@ script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M scriptedCoursier packagedArtifacts # ensure that all artifacts for publish package without failure -env: - global: - - secure: D9Ckfxq/5n+41REwuPBwb0CHRVSPtCJRN+N1FWNFjUnfCHZQCeclP8Ydp9ql/fZxICG8rnCOI5XW0j2YeAiR+abpQNmQ42pKMEjNT0VQDZ0I1lQfiDL071Kj+ui9AH+TqAvBT011u72ML52iDfV0WaL/Skf1Noh0lXc+IscRI56OLRv+YU5n5aNZhXon6AZHU11rRCg4aMwaHr+U9ISSUXc6OtJeFC/SAYNUNYEOZwTOJ4Y2+VrKAmKuIZ2jjkMF13eKMzXw5g+u8V3AmOpIm1RiyS2dAgAoc+r2ucF9RUMsfiZIF0XBu65iv9hZP5m0q11n6IFEKC9bpLsTYCAwX2MgVayoHvDQv1gkL/cA1gkqmf0Kkx3oc33aYLgsCydj2Lbg/myKD+GeHxr5WhyeSEee3Bwj+KGNwvjfcaPEECCor6yilKGdIsuYbfHzu8B8moNjwH7ui5f5w/1xuWrdaSA23LOIYbhP+2rM894JIYNNt5vlMLoYMzmC9N1E/qyBRYSdfMr+Uh8qI+j85hkKKgEffSu9f55IH6bk6Lq08Nc4d64KXUISDNJj59MrJcadatsS2vp+u39zR/iIewW4a017bAFfv57AJb6SwLdvASG+psFH8MRPD6xYPZKNw4Al/4YMc+oXONplSXyOu/jQYjSfK9tyvJwpoY7tLh6vEBc= - -cache: - directories: - - $HOME/.ivy2/cache - - $HOME/.sbt - before_cache: # - find $HOME/.ivy2/local -name "*-LM-SNAPSHOT*" -exec rm -r "{}" \; - find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete - find $HOME/.sbt -name "*.lock" -delete + +cache: + directories: + - $HOME/.ivy2/cache + - $HOME/.sbt/boot + - $HOME/.jabba/jdk From e36ddd64ab55913a42c8dfae3954f4518fa45bfd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 28 Dec 2018 17:12:39 -0500 Subject: [PATCH 0814/1030] Bump Ivy Ref https://github.com/sbt/ivy/pull/31 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 84e72a4ad..2882abc28 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -40,7 +40,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-b18f59ea3bc914a297bb6f1a4f7fb0ace399e310" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832" val coursier = "io.get-coursier" %% "coursier" % coursierVersion val coursierCache = "io.get-coursier" %% "coursier-cache" % coursierVersion From c1a93c65b7d4fdc76a47679f1ebc94eb5e01c861 Mon Sep 17 00:00:00 2001 From: bigwheel Date: Thu, 10 Jan 2019 21:51:49 +0900 Subject: [PATCH 0815/1030] [Fix #287] Eviction warning summary shows only binary incompatible --- .../librarymanagement/EvictionWarning.scala | 28 ++++++++++++------- .../EvictionWarningSpec.scala | 18 ++++++------ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 529353ba4..08fef77bc 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -195,7 +195,8 @@ final class EvictionWarning private[sbt] ( val scalaEvictions: Seq[EvictionPair], val directEvictions: Seq[EvictionPair], val transitiveEvictions: Seq[EvictionPair], - val allEvictions: Seq[EvictionPair] + val allEvictions: Seq[EvictionPair], + val binaryIncompatibleEvictionExists: Boolean ) { def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions @@ -279,6 +280,7 @@ object EvictionWarning { val scalaEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() val directEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() val transitiveEvictions: mutable.ListBuffer[EvictionPair] = mutable.ListBuffer() + var binaryIncompatibleEvictionExists = false def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => options.guessCompatible( @@ -288,18 +290,23 @@ object EvictionWarning { pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => (module.scalaModuleInfo, p.winner) match { - case (Some(s), Some(winner)) - if (s.scalaFullVersion != winner.module.revision) && options.warnScalaVersionEviction => - scalaEvictions += p + case (Some(s), Some(winner)) if (s.scalaFullVersion != winner.module.revision) => + binaryIncompatibleEvictionExists = true + if (options.warnScalaVersionEviction) + scalaEvictions += p case _ => } case p if p.includesDirect => - if (!guessCompatible(p) && options.warnDirectEvictions) { - directEvictions += p + if (!guessCompatible(p)) { + binaryIncompatibleEvictionExists = true + if (options.warnDirectEvictions) + directEvictions += p } case p => - if (!guessCompatible(p) && options.warnTransitiveEvictions) { - transitiveEvictions += p + if (!guessCompatible(p)) { + binaryIncompatibleEvictionExists = true + if (options.warnTransitiveEvictions) + transitiveEvictions += p } } new EvictionWarning( @@ -307,14 +314,15 @@ object EvictionWarning { scalaEvictions.toList, directEvictions.toList, transitiveEvictions.toList, - pairs + pairs, + binaryIncompatibleEvictionExists ) } implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => import ShowLines._ val out: mutable.ListBuffer[String] = mutable.ListBuffer() - if ((a.options.warnEvictionSummary || a.reportedEvictions.nonEmpty) && a.allEvictions.nonEmpty) { + if (a.options.warnEvictionSummary && a.binaryIncompatibleEvictionExists) { out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index d22ea557b..106a0e87f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -27,7 +27,7 @@ class EvictionWarningSpec extends BaseIvySpecification { """Including two (suspect) binary compatible Java libraries to direct dependencies """ should "not be detected as eviction" in javaLibNoWarn1() - it should "print out message about the eviction" in javaLibNoWarn2() + it should "not print out message about the eviction" in javaLibNoWarn2() """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies """ should "be detected as eviction" in javaLibTransitiveWarn2() @@ -41,7 +41,8 @@ class EvictionWarningSpec extends BaseIvySpecification { """Including two (suspect) binary compatible Scala libraries to direct dependencies """ should "not be detected as eviction" in scalaLibNoWarn1() - it should "print out message about the eviction" in scalaLibNoWarn2() + it should "not print out message about the eviction" in scalaLibNoWarn2() + it should "not print out summary about the eviction even if warn eviction summary enabled" in scalaLibNoWarn3() """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies """ should "be detected as eviction" in scalaLibTransitiveWarn2() @@ -111,7 +112,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions.withShowCallers(false), report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "", @@ -125,7 +125,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Scala version was updated by one of library dependencies:", "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", @@ -182,7 +181,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* commons-io:commons-io:2.4 is selected over 1.4", @@ -196,7 +194,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions.withShowCallers(true), report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* commons-io:commons-io:2.4 is selected over 1.4", @@ -260,7 +257,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", @@ -293,6 +289,13 @@ class EvictionWarningSpec extends BaseIvySpecification { EvictionWarning(m, fullOptions, report).lines shouldBe Nil } + def scalaLibNoWarn3() = { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe Nil + } + def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) def scalaLibTransitiveWarn2() = { @@ -306,7 +309,6 @@ class EvictionWarningSpec extends BaseIvySpecification { val report = ivyUpdate(m) EvictionWarning(m, fullOptions, report).lines shouldBe List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", "", "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", From 8d4f6cee48e7002dfa3f8158234f444f7bae8f30 Mon Sep 17 00:00:00 2001 From: bigwheel Date: Mon, 14 Jan 2019 19:02:41 +0900 Subject: [PATCH 0816/1030] [Fix #287] Add alternative constructor for binary compatibility --- .../sbt/librarymanagement/EvictionWarning.scala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 08fef77bc..04da1a4c6 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -198,6 +198,13 @@ final class EvictionWarning private[sbt] ( val allEvictions: Seq[EvictionPair], val binaryIncompatibleEvictionExists: Boolean ) { + private[sbt] def this( + options: EvictionWarningOptions, + scalaEvictions: Seq[EvictionPair], + directEvictions: Seq[EvictionPair], + transitiveEvictions: Seq[EvictionPair], + allEvictions: Seq[EvictionPair] + ) = this(options, scalaEvictions, directEvictions, transitiveEvictions, allEvictions, false) def reportedEvictions: Seq[EvictionPair] = scalaEvictions ++ directEvictions ++ transitiveEvictions private[sbt] def infoAllTheThings: List[String] = EvictionWarning.infoAllTheThings(this) @@ -291,22 +298,25 @@ object EvictionWarning { case p if isScalaArtifact(module, p.organization, p.name) => (module.scalaModuleInfo, p.winner) match { case (Some(s), Some(winner)) if (s.scalaFullVersion != winner.module.revision) => - binaryIncompatibleEvictionExists = true if (options.warnScalaVersionEviction) scalaEvictions += p + if (options.warnEvictionSummary) + binaryIncompatibleEvictionExists = true case _ => } case p if p.includesDirect => if (!guessCompatible(p)) { - binaryIncompatibleEvictionExists = true if (options.warnDirectEvictions) directEvictions += p + if (options.warnEvictionSummary) + binaryIncompatibleEvictionExists = true } case p => if (!guessCompatible(p)) { - binaryIncompatibleEvictionExists = true if (options.warnTransitiveEvictions) transitiveEvictions += p + if (options.warnEvictionSummary) + binaryIncompatibleEvictionExists = true } } new EvictionWarning( From 75c319e6bbcaaaa5e36565d8b0a753d5c29db31d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 22 Jan 2019 11:45:03 -0500 Subject: [PATCH 0817/1030] make object Disabled extend Disabled Ref https://github.com/sbt/librarymanagement/pull/280 This is to workaround bincompat error detected by sbt community build. ``` [cats] [error] java.lang.NoSuchMethodError: sbt.librarymanagement.CrossVersion$.Disabled()Lsbt/librarymanagement/Disabled$; ``` --- build.sbt | 7 ------- .../contraband-scala/sbt/librarymanagement/Disabled.scala | 4 ++-- core/src/main/contraband/librarymanagement.json | 4 +++- .../scala/sbt/librarymanagement/CrossVersionExtra.scala | 2 +- project/plugins.sbt | 2 +- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/build.sbt b/build.sbt index ae9692e1c..7b5d143f6 100644 --- a/build.sbt +++ b/build.sbt @@ -157,13 +157,6 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), - // by mistake we aliased the companion object instead of an instance of Disabled - // but it was aliased as a constant expression, so even if the binary API has changed - // there are no call sites in bytecode because the value got inlined - // also it's wouldn't work so I doubt anyone has made use of it - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.CrossVersionFunctions.Disabled"), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.CrossVersionFunctions.Disabled"), - // contraband issue exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.UpdateReportLite.copy*"), diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala index f53c8b541..4dbfc38d3 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement /** Disables cross versioning for a module. */ -final class Disabled private () extends sbt.librarymanagement.CrossVersion() with Serializable { +sealed class Disabled private () extends sbt.librarymanagement.CrossVersion() with Serializable { @@ -24,7 +24,7 @@ private[this] def copy(): Disabled = { } } -object Disabled { +object Disabled extends sbt.librarymanagement.Disabled { def apply(): Disabled = new Disabled() } diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index b31b9a856..10c8fd86b 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -261,7 +261,9 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "doc": "Disables cross versioning for a module.", - "type": "record" + "type": "record", + "modifier": "sealed", + "parentsCompanion": "sbt.librarymanagement.Disabled" }, { "name": "Binary", diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index bcd7b753a..d8e54d8c8 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -8,7 +8,7 @@ final case class ScalaVersion(full: String, binary: String) private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ - final val Disabled = sbt.librarymanagement.Disabled() + final def Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full diff --git a/project/plugins.sbt b/project/plugins.sbt index 1ebc7fc01..932866622 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.8") addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.15") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.1") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.2") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") scalacOptions += "-language:postfixOps" From 0878b9db14ffaca87fdfcdee21d74c7b4b49a3a9 Mon Sep 17 00:00:00 2001 From: 0lejk4 Date: Thu, 14 Mar 2019 00:10:26 +0200 Subject: [PATCH 0818/1030] make Developer email optional as it is not obligatory and some people don`t want to expose it --- .../sbt/librarymanagement/Developer.scala | 8 ++++---- .../sbt/librarymanagement/DeveloperFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 8 ++++---- .../scala/sbt/internal/librarymanagement/MakePom.scala | 7 ++++++- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index 30c20f3b9..075851b3d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class Developer private ( val id: String, val name: String, - val email: String, + val email: Option[String], val url: java.net.URL) extends Serializable { @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: Option[String] = email, url: java.net.URL = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { @@ -31,7 +31,7 @@ final class Developer private ( def withName(name: String): Developer = { copy(name = name) } - def withEmail(email: String): Developer = { + def withEmail(email: Option[String]): Developer = { copy(email = email) } def withUrl(url: java.net.URL): Developer = { @@ -40,5 +40,5 @@ final class Developer private ( } object Developer { - def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) + def apply(id: String, name: String, email: Option[String], url: java.net.URL): Developer = new Developer(id, name, email, url) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index ee1e87e45..4671afed5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -13,7 +13,7 @@ implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = unbuilder.beginObject(js) val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") - val email = unbuilder.readField[String]("email") + val email = unbuilder.readField[Option[String]]("email") val url = unbuilder.readField[java.net.URL]("url") unbuilder.endObject() sbt.librarymanagement.Developer(id, name, email, url) diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 10c8fd86b..943564131 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -328,10 +328,10 @@ "target": "Scala", "type": "record", "fields": [ - { "name": "id", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "email", "type": "String" }, - { "name": "url", "type": "java.net.URL" } + { "name": "id", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "email", "type": "Option[String]" }, + { "name": "url", "type": "java.net.URL" } ] }, { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 86f514e69..96922cf9b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -206,8 +206,13 @@ class MakePom(val log: Logger) { { developer.id } { developer.name } - { developer.email } { developer.url } + { + developer.email match { + case Some(e)=> { e } + case _ => NodeSeq.Empty + } + } } } From a4e5a2e299a43da1c1bcee9713f23c2b6fd23e91 Mon Sep 17 00:00:00 2001 From: 0lejk4 Date: Sun, 17 Mar 2019 11:32:52 +0200 Subject: [PATCH 0819/1030] leave scheme unchanged for binary compatibility but don`t render email tag if it is null or empty --- .../sbt/librarymanagement/Developer.scala | 8 ++++---- .../sbt/librarymanagement/DeveloperFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 8 ++++---- .../scala/sbt/internal/librarymanagement/MakePom.scala | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index 075851b3d..30c20f3b9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class Developer private ( val id: String, val name: String, - val email: Option[String], + val email: String, val url: java.net.URL) extends Serializable { @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - private[this] def copy(id: String = id, name: String = name, email: Option[String] = email, url: java.net.URL = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { @@ -31,7 +31,7 @@ final class Developer private ( def withName(name: String): Developer = { copy(name = name) } - def withEmail(email: Option[String]): Developer = { + def withEmail(email: String): Developer = { copy(email = email) } def withUrl(url: java.net.URL): Developer = { @@ -40,5 +40,5 @@ final class Developer private ( } object Developer { - def apply(id: String, name: String, email: Option[String], url: java.net.URL): Developer = new Developer(id, name, email, url) + def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index 4671afed5..ee1e87e45 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -13,7 +13,7 @@ implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = unbuilder.beginObject(js) val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") - val email = unbuilder.readField[Option[String]]("email") + val email = unbuilder.readField[String]("email") val url = unbuilder.readField[java.net.URL]("url") unbuilder.endObject() sbt.librarymanagement.Developer(id, name, email, url) diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 943564131..10c8fd86b 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -328,10 +328,10 @@ "target": "Scala", "type": "record", "fields": [ - { "name": "id", "type": "String" }, - { "name": "name", "type": "String" }, - { "name": "email", "type": "Option[String]" }, - { "name": "url", "type": "java.net.URL" } + { "name": "id", "type": "String" }, + { "name": "name", "type": "String" }, + { "name": "email", "type": "String" }, + { "name": "url", "type": "java.net.URL" } ] }, { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 96922cf9b..80b466b5a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -209,8 +209,8 @@ class MakePom(val log: Logger) { { developer.url } { developer.email match { - case Some(e)=> { e } - case _ => NodeSeq.Empty + case "" | null => NodeSeq.Empty + case e => { e } } } From 7f192743049aeb6f90711255936d97b9f515ba03 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Mar 2019 13:47:32 -0400 Subject: [PATCH 0820/1030] sbt 1.2.8 --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index 7c58a83ab..c0bab0494 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.6 +sbt.version=1.2.8 From 83a28b0b3d5ac20e96815aaceac4e3379656365f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Mar 2019 13:53:17 -0400 Subject: [PATCH 0821/1030] bump IO and Util --- project/Dependencies.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2882abc28..946c741fa 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,10 +3,10 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.7" + val scala212 = "2.12.8" - private val ioVersion = "1.3.0-M4" - private val utilVersion = "1.3.0-M2" + private val ioVersion = "1.3.0-M7" + private val utilVersion = "1.3.0-M5" private val coursierVersion = "1.1.0-M7" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 5645e36ee19ea740233be1253d87ce974cfb6b93 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 22 Mar 2019 13:58:56 -0400 Subject: [PATCH 0822/1030] Remove lmCoursier There's an implementation of lmCoursier in the coursier project itself, so this seems redundant here. --- .travis.yml | 1 - build.sbt | 30 +----------------------------- 2 files changed, 1 insertion(+), 30 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5cee6b49b..243fb2eef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,7 +34,6 @@ script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M whitesourceCheckPolicies test scriptedIvy - scriptedCoursier packagedArtifacts # ensure that all artifacts for publish package without failure before_cache: diff --git a/build.sbt b/build.sbt index 7b5d143f6..01d30ad43 100644 --- a/build.sbt +++ b/build.sbt @@ -46,7 +46,7 @@ val mimaSettings = Def settings ( ) lazy val lmRoot = (project in file(".")) - .aggregate(lmCore, lmIvy, lmCoursier) + .aggregate(lmCore, lmIvy) .settings( inThisBuild( Seq( @@ -260,25 +260,6 @@ lazy val lmIvy = (project in file("ivy")) ), ) -lazy val lmCoursier = (project in file("coursier")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(lmIvy) - .settings( - commonSettings, - name := "librarymanagement-coursier", - libraryDependencies ++= Seq(coursier, - coursierCache, - scalaTest % Test, - scalaCheck % Test - ), - managedSourceDirectories in Compile += - baseDirectory.value / "src" / "main" / "contraband-scala", - sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", - contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, - scalacOptions in (Compile, console) --= - Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") - ) - lazy val lmScriptedTest = (project in file("scripted-test")) .enablePlugins(SbtPlugin) .settings( @@ -299,15 +280,6 @@ addCommandAlias("scriptedIvy", Seq( """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=ivy" """, "lmScriptedTest/scripted").mkString(";",";","")) -addCommandAlias("scriptedCoursier", Seq( - "lmCore/publishLocal", - "lmIvy/publishLocal", - "lmCoursier/publishLocal", - "lmScriptedTest/clean", - """set ThisBuild / scriptedTestLMImpl := "coursier"""", - """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=coursier" """, - "lmScriptedTest/scripted").mkString(";",";","")) - def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => // "clean" :: From 8219f3c1178e9d328b5701b8e89598de3643874a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 24 Mar 2019 22:27:23 -0400 Subject: [PATCH 0823/1030] use SDKMAN to install JDKs --- .travis.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 243fb2eef..0b1d49dc5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,27 +5,33 @@ group: stable language: scala scala: - - 2.12.7 + - 2.12.8 env: global: - - JABBA_HOME=/home/travis/.jabba - secure: D9Ckfxq/5n+41REwuPBwb0CHRVSPtCJRN+N1FWNFjUnfCHZQCeclP8Ydp9ql/fZxICG8rnCOI5XW0j2YeAiR+abpQNmQ42pKMEjNT0VQDZ0I1lQfiDL071Kj+ui9AH+TqAvBT011u72ML52iDfV0WaL/Skf1Noh0lXc+IscRI56OLRv+YU5n5aNZhXon6AZHU11rRCg4aMwaHr+U9ISSUXc6OtJeFC/SAYNUNYEOZwTOJ4Y2+VrKAmKuIZ2jjkMF13eKMzXw5g+u8V3AmOpIm1RiyS2dAgAoc+r2ucF9RUMsfiZIF0XBu65iv9hZP5m0q11n6IFEKC9bpLsTYCAwX2MgVayoHvDQv1gkL/cA1gkqmf0Kkx3oc33aYLgsCydj2Lbg/myKD+GeHxr5WhyeSEee3Bwj+KGNwvjfcaPEECCor6yilKGdIsuYbfHzu8B8moNjwH7ui5f5w/1xuWrdaSA23LOIYbhP+2rM894JIYNNt5vlMLoYMzmC9N1E/qyBRYSdfMr+Uh8qI+j85hkKKgEffSu9f55IH6bk6Lq08Nc4d64KXUISDNJj59MrJcadatsS2vp+u39zR/iIewW4a017bAFfv57AJb6SwLdvASG+psFH8MRPD6xYPZKNw4Al/4YMc+oXONplSXyOu/jQYjSfK9tyvJwpoY7tLh6vEBc= matrix: include: - env: - - TRAVIS_JDK=adopt@1.8.192-12 + - TRAVIS_JDK=11.0.2.hs-adpt - env: - - TRAVIS_JDK=adopt@1.11.0-1 + - TRAVIS_JDK=8.0.202.hs-adpt before_install: - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh +before_install: + # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation + - "[[ -d /home/travis/.sdkman/ ]] && [[ -d /home/travis/.sdkman/bin/ ]] || rm -rf /home/travis/.sdkman/" + - curl -sL https://get.sdkman.io | bash + - echo sdkman_auto_answer=true > /home/travis/.sdkman/etc/config + - source "/home/travis/.sdkman/bin/sdkman-init.sh" + install: - - $JABBA_HOME/bin/jabba install $TRAVIS_JDK + - sdk install java $TRAVIS_JDK - unset _JAVA_OPTIONS - - export JAVA_HOME="$JABBA_HOME/jdk/$TRAVIS_JDK" && export PATH="$JAVA_HOME/bin:$PATH" && java -Xmx32m -version + - java -Xmx32m -version script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M ++$TRAVIS_SCALA_VERSION @@ -46,4 +52,4 @@ cache: directories: - $HOME/.ivy2/cache - $HOME/.sbt/boot - - $HOME/.jabba/jdk + - $HOME/.sdkman From 1c4f90e926720867d8170069ee27e87e14158349 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 24 Mar 2019 23:21:51 -0400 Subject: [PATCH 0824/1030] use SDKMAN to install sbt --- .travis.yml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b1d49dc5..bdcda90eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,9 +32,15 @@ install: - sdk install java $TRAVIS_JDK - unset _JAVA_OPTIONS - java -Xmx32m -version + # detect sbt version from project/build.properties + - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" + - sdk install sbt $TRAVIS_SBT + # override Travis CI's SBT_OPTS + - unset SBT_OPTS + - export JAVA_OPTS="-Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M" -script: sbt -Dfile.encoding=UTF8 -J-XX:ReservedCodeCacheSize=256M - ++$TRAVIS_SCALA_VERSION +script: sbt -Dfile.encoding=UTF8 + ++$TRAVIS_SCALA_VERSION! mimaReportBinaryIssues scalafmt::test test:scalafmt::test sbt:scalafmt::test whitesourceCheckPolicies From 2f8d9ad8ca9c735f90f4374901c1595a2fe2242e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 1 Apr 2019 23:35:39 -0400 Subject: [PATCH 0825/1030] move CrossVersion to src/ Fixes sbt/sbt#4595 Ref #290 Ref #280 This is bit of an odd one. To keep bincompat and also to fix sbt 0.13 compatibility issue we have made `Disabled` companion object extend `Disabled` type. This actually created a subtle deserialization issue: ``` [error] scala.MatchError: Disabled() (of class sbt.librarymanagement.Disabled$) [error] at sjsonnew.FlatUnionFormats$$anon$5.write(FlatUnionFormats.scala:220) [error] at sjsonnew.JsonWriter.addField(JsonFormat.scala:40) [error] at sjsonnew.JsonWriter.addField$(JsonFormat.scala:37) [error] at sjsonnew.FlatUnionFormats$$anon$5.addField(FlatUnionFormats.scala:208) [error] at sjsonnew.Builder.addField(Builder.scala:43) [error] at sbt.librarymanagement.ModuleIDFormats$$anon$1.write(ModuleIDFormats.scala:46) ``` This is because Contraband generates `flatUnionFormat5[CrossVersion, Disabled, ...]` for all of the subtypes of `CrossVersion`, which uses the runtime type information. Now that `Disabled` object is also in the mix, this created JSON that `CrossVersionFormats` cannot deserialize. This brings the code into src/ so we can write this part manually. --- .../sbt/librarymanagement/Binary.scala | 43 --- .../sbt/librarymanagement/BinaryFormats.scala | 29 -- .../sbt/librarymanagement/Constant.scala | 34 -- .../librarymanagement/ConstantFormats.scala | 27 -- .../sbt/librarymanagement/CrossVersion.scala | 26 -- .../CrossVersionFormats.scala | 11 - .../sbt/librarymanagement/Disabled.scala | 30 -- .../sbt/librarymanagement/Full.scala | 43 --- .../sbt/librarymanagement/FullFormats.scala | 29 -- .../InclExclRuleFormats.scala | 2 +- .../LibraryManagementCodec.scala | 2 +- .../librarymanagement/ModuleIDFormats.scala | 2 +- .../sbt/librarymanagement/Patch.scala | 33 -- .../sbt/librarymanagement/PatchFormats.scala | 27 -- .../main/contraband/librarymanagement.json | 73 ---- .../sbt/librarymanagement/CrossVersion.scala | 330 ++++++++++++++++++ project/DatatypeConfig.scala | 10 + 17 files changed, 343 insertions(+), 408 deletions(-) delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/Full.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala create mode 100644 core/src/main/scala/sbt/librarymanagement/CrossVersion.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala deleted file mode 100644 index 3cc75b328..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Binary.scala +++ /dev/null @@ -1,43 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** - * Cross-versions a module using the result of - * prepending `prefix` and appending `suffix` to the binary version. - * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the binary version is "2.10", - * the module is cross-versioned with "foo_2.10_bar". - */ -final class Binary private ( - val prefix: String, - val suffix: String) extends sbt.librarymanagement.CrossVersion() with Serializable { - - private def this() = this("", "") - - override def equals(o: Any): Boolean = o match { - case x: Binary => (this.prefix == x.prefix) && (this.suffix == x.suffix) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.librarymanagement.Binary".##) + prefix.##) + suffix.##) - } - override def toString: String = { - "Binary(" + prefix + ", " + suffix + ")" - } - private[this] def copy(prefix: String = prefix, suffix: String = suffix): Binary = { - new Binary(prefix, suffix) - } - def withPrefix(prefix: String): Binary = { - copy(prefix = prefix) - } - def withSuffix(suffix: String): Binary = { - copy(suffix = suffix) - } -} -object Binary { - - def apply(): Binary = new Binary() - def apply(prefix: String, suffix: String): Binary = new Binary(prefix, suffix) -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala deleted file mode 100644 index 95bf74afc..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/BinaryFormats.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait BinaryFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val BinaryFormat: JsonFormat[sbt.librarymanagement.Binary] = new JsonFormat[sbt.librarymanagement.Binary] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Binary = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - val prefix = unbuilder.readField[String]("prefix") - val suffix = unbuilder.readField[String]("suffix") - unbuilder.endObject() - sbt.librarymanagement.Binary(prefix, suffix) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Binary, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("prefix", obj.prefix) - builder.addField("suffix", obj.suffix) - builder.endObject() - } -} -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala deleted file mode 100644 index 8380dccf5..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Constant.scala +++ /dev/null @@ -1,34 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** Cross-versions a module using the string `value`. */ -final class Constant private ( - val value: String) extends sbt.librarymanagement.CrossVersion() with Serializable { - - private def this() = this("") - - override def equals(o: Any): Boolean = o match { - case x: Constant => (this.value == x.value) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (17 + "sbt.librarymanagement.Constant".##) + value.##) - } - override def toString: String = { - "Constant(" + value + ")" - } - private[this] def copy(value: String = value): Constant = { - new Constant(value) - } - def withValue(value: String): Constant = { - copy(value = value) - } -} -object Constant { - - def apply(): Constant = new Constant() - def apply(value: String): Constant = new Constant(value) -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala deleted file mode 100644 index 752adb674..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConstantFormats.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConstantFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val ConstantFormat: JsonFormat[sbt.librarymanagement.Constant] = new JsonFormat[sbt.librarymanagement.Constant] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Constant = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - val value = unbuilder.readField[String]("value") - unbuilder.endObject() - sbt.librarymanagement.Constant(value) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Constant, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("value", obj.value) - builder.endObject() - } -} -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala deleted file mode 100644 index 2c890a27b..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersion.scala +++ /dev/null @@ -1,26 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** Configures how a module will be cross-versioned. */ -abstract class CrossVersion() extends Serializable { - - - - -override def equals(o: Any): Boolean = o match { - case _: CrossVersion => true - case _ => false -} -override def hashCode: Int = { - 37 * (17 + "sbt.librarymanagement.CrossVersion".##) -} -override def toString: String = { - "CrossVersion()" -} -} -object CrossVersion extends sbt.librarymanagement.CrossVersionFunctions { - -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala deleted file mode 100644 index b0b37e916..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CrossVersionFormats.scala +++ /dev/null @@ -1,11 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement - -import _root_.sjsonnew.JsonFormat -trait CrossVersionFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats => -implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = flatUnionFormat5[sbt.librarymanagement.CrossVersion, sbt.librarymanagement.Disabled, sbt.librarymanagement.Binary, sbt.librarymanagement.Constant, sbt.librarymanagement.Patch, sbt.librarymanagement.Full]("type") -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala deleted file mode 100644 index 4dbfc38d3..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Disabled.scala +++ /dev/null @@ -1,30 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** Disables cross versioning for a module. */ -sealed class Disabled private () extends sbt.librarymanagement.CrossVersion() with Serializable { - - - -override def equals(o: Any): Boolean = o match { - case _: Disabled => true - case _ => false -} -override def hashCode: Int = { - 37 * (17 + "sbt.librarymanagement.Disabled".##) -} -override def toString: String = { - "Disabled()" -} -private[this] def copy(): Disabled = { - new Disabled() -} - -} -object Disabled extends sbt.librarymanagement.Disabled { - - def apply(): Disabled = new Disabled() -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala deleted file mode 100644 index cd2416d7e..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Full.scala +++ /dev/null @@ -1,43 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** - * Cross-versions a module with the result of - * prepending `prefix` and appending `suffix` to the full version. - * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the full version is "2.12.1", - * the module is cross-versioned with "foo_2.12.1_bar". - */ -final class Full private ( - val prefix: String, - val suffix: String) extends sbt.librarymanagement.CrossVersion() with Serializable { - - private def this() = this("", "") - - override def equals(o: Any): Boolean = o match { - case x: Full => (this.prefix == x.prefix) && (this.suffix == x.suffix) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.librarymanagement.Full".##) + prefix.##) + suffix.##) - } - override def toString: String = { - "Full(" + prefix + ", " + suffix + ")" - } - private[this] def copy(prefix: String = prefix, suffix: String = suffix): Full = { - new Full(prefix, suffix) - } - def withPrefix(prefix: String): Full = { - copy(prefix = prefix) - } - def withSuffix(suffix: String): Full = { - copy(suffix = suffix) - } -} -object Full { - - def apply(): Full = new Full() - def apply(prefix: String, suffix: String): Full = new Full(prefix, suffix) -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala deleted file mode 100644 index c44b95ef3..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FullFormats.scala +++ /dev/null @@ -1,29 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait FullFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val FullFormat: JsonFormat[sbt.librarymanagement.Full] = new JsonFormat[sbt.librarymanagement.Full] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Full = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - val prefix = unbuilder.readField[String]("prefix") - val suffix = unbuilder.readField[String]("suffix") - unbuilder.endObject() - sbt.librarymanagement.Full(prefix, suffix) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Full, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("prefix", obj.prefix) - builder.addField("suffix", obj.suffix) - builder.endObject() - } -} -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala index ed1878b60..e7f9ac838 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => +trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclRule] = new JsonFormat[sbt.librarymanagement.InclExclRule] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 493571edb..6c82fab1a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -13,12 +13,12 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.UpdateConfigurationFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats - with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigurationFormats diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala index 55d0d2fc4..eeebd0d33 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sjsonnew.BasicJsonProtocol => +trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = new JsonFormat[sbt.librarymanagement.ModuleID] { override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala deleted file mode 100644 index 217f7583e..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patch.scala +++ /dev/null @@ -1,33 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** - * Cross-versions a module by stripping off -bin-suffix. - * This is intended for patch-version compatible alternative replacements. - */ -final class Patch private () extends sbt.librarymanagement.CrossVersion() with Serializable { - - - -override def equals(o: Any): Boolean = o match { - case _: Patch => true - case _ => false -} -override def hashCode: Int = { - 37 * (17 + "sbt.librarymanagement.Patch".##) -} -override def toString: String = { - "Patch()" -} -private[this] def copy(): Patch = { - new Patch() -} - -} -object Patch { - - def apply(): Patch = new Patch() -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala deleted file mode 100644 index c419fcb6a..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatchFormats.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PatchFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val PatchFormat: JsonFormat[sbt.librarymanagement.Patch] = new JsonFormat[sbt.librarymanagement.Patch] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Patch = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - - unbuilder.endObject() - sbt.librarymanagement.Patch() - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Patch, builder: Builder[J]): Unit = { - builder.beginObject() - - builder.endObject() - } -} -} diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 10c8fd86b..52cb34905 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -249,79 +249,6 @@ ], "parentsCompanion": "sbt.librarymanagement.ConflictManagerFunctions" }, - { - "name": "CrossVersion", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "interface", - "doc": "Configures how a module will be cross-versioned.", - "types": [ - { - "name": "Disabled", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": "Disables cross versioning for a module.", - "type": "record", - "modifier": "sealed", - "parentsCompanion": "sbt.librarymanagement.Disabled" - }, - { - "name": "Binary", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": [ - "Cross-versions a module using the result of", - "prepending `prefix` and appending `suffix` to the binary version.", - "For example, if `prefix = \"foo_\"` and `suffix = \"_bar\"` and the binary version is \"2.10\",", - "the module is cross-versioned with \"foo_2.10_bar\"." - ], - "type": "record", - "fields": [ - { "name": "prefix", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } - ] - }, - { - "name": "Constant", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": [ - "Cross-versions a module using the string `value`." - ], - "type": "record", - "fields": [ - { "name": "value", "type": "String", "default": "\"\"", "since": "0.0.2" } - ] - }, - { - "name": "Patch", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "doc": [ - "Cross-versions a module by stripping off -bin-suffix.", - "This is intended for patch-version compatible alternative replacements." - ], - "type": "record" - }, - { - "name": "Full", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "Cross-versions a module with the result of", - "prepending `prefix` and appending `suffix` to the full version.", - "For example, if `prefix = \"foo_\"` and `suffix = \"_bar\"` and the full version is \"2.12.1\",", - "the module is cross-versioned with \"foo_2.12.1_bar\"." - ], - "fields": [ - { "name": "prefix", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "suffix", "type": "String", "default": "\"\"", "since": "0.0.1" } - ] - } - ], - "parentsCompanion": "sbt.librarymanagement.CrossVersionFunctions" - }, { "name": "Developer", "namespace": "sbt.librarymanagement", diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala new file mode 100644 index 000000000..c93702ded --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -0,0 +1,330 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.librarymanagement + +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } + +/** Configures how a module will be cross-versioned. */ +abstract class CrossVersion() extends Serializable { + override def equals(o: Any): Boolean = o match { + case _: CrossVersion => true + case _ => false + } + override def hashCode: Int = { + 37 * (17 + "sbt.librarymanagement.CrossVersion".##) + } + override def toString: String = { + "CrossVersion()" + } +} +object CrossVersion extends sbt.librarymanagement.CrossVersionFunctions {} + +/** Disables cross versioning for a module. */ +sealed class Disabled private () extends sbt.librarymanagement.CrossVersion() with Serializable { + + override def equals(o: Any): Boolean = o match { + case _: Disabled => true + case _ => false + } + override def hashCode: Int = { + 37 * (17 + "sbt.librarymanagement.Disabled".##) + } + override def toString: String = { + "Disabled()" + } + private[this] def copy(): Disabled = { + new Disabled() + } + +} +object Disabled extends sbt.librarymanagement.Disabled { + def apply(): Disabled = new Disabled() +} + +/** + * Cross-versions a module using the result of + * prepending `prefix` and appending `suffix` to the binary version. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the binary version is "2.10", + * the module is cross-versioned with "foo_2.10_bar". + */ +final class Binary private (val prefix: String, val suffix: String) + extends sbt.librarymanagement.CrossVersion() + with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: Binary => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.librarymanagement.Binary".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "Binary(" + prefix + ", " + suffix + ")" + } + private[this] def copy(prefix: String = prefix, suffix: String = suffix): Binary = { + new Binary(prefix, suffix) + } + def withPrefix(prefix: String): Binary = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): Binary = { + copy(suffix = suffix) + } +} +object Binary { + + def apply(): Binary = new Binary() + def apply(prefix: String, suffix: String): Binary = new Binary(prefix, suffix) +} + +/** Cross-versions a module using the string `value`. */ +final class Constant private (val value: String) + extends sbt.librarymanagement.CrossVersion() + with Serializable { + + private def this() = this("") + + override def equals(o: Any): Boolean = o match { + case x: Constant => (this.value == x.value) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (17 + "sbt.librarymanagement.Constant".##) + value.##) + } + override def toString: String = { + "Constant(" + value + ")" + } + private[this] def copy(value: String = value): Constant = { + new Constant(value) + } + def withValue(value: String): Constant = { + copy(value = value) + } +} +object Constant { + def apply(): Constant = new Constant() + def apply(value: String): Constant = new Constant(value) +} + +/** + * Cross-versions a module by stripping off -bin-suffix. + * This is intended for patch-version compatible alternative replacements. + */ +final class Patch private () extends sbt.librarymanagement.CrossVersion() with Serializable { + + override def equals(o: Any): Boolean = o match { + case _: Patch => true + case _ => false + } + override def hashCode: Int = { + 37 * (17 + "sbt.librarymanagement.Patch".##) + } + override def toString: String = { + "Patch()" + } + private[this] def copy(): Patch = { + new Patch() + } +} + +object Patch { + def apply(): Patch = new Patch() +} + +/** + * Cross-versions a module with the result of + * prepending `prefix` and appending `suffix` to the full version. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the full version is "2.12.1", + * the module is cross-versioned with "foo_2.12.1_bar". + */ +final class Full private (val prefix: String, val suffix: String) + extends sbt.librarymanagement.CrossVersion() + with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: Full => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.librarymanagement.Full".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "Full(" + prefix + ", " + suffix + ")" + } + private[this] def copy(prefix: String = prefix, suffix: String = suffix): Full = { + new Full(prefix, suffix) + } + def withPrefix(prefix: String): Full = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): Full = { + copy(suffix = suffix) + } +} + +object Full { + def apply(): Full = new Full() + def apply(prefix: String, suffix: String): Full = new Full(prefix, suffix) +} + +trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = + new JsonFormat[sbt.librarymanagement.Disabled] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.librarymanagement.Disabled() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Disabled, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } + } + + implicit lazy val DisabledObjectFormat: JsonFormat[sbt.librarymanagement.Disabled.type] = + new JsonFormat[sbt.librarymanagement.Disabled.type] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled.type = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.librarymanagement.Disabled + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Disabled.type, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } + } +} + +trait BinaryFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val BinaryFormat: JsonFormat[sbt.librarymanagement.Binary] = + new JsonFormat[sbt.librarymanagement.Binary] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Binary = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.Binary(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Binary, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } + } +} + +trait ConstantFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val ConstantFormat: JsonFormat[sbt.librarymanagement.Constant] = + new JsonFormat[sbt.librarymanagement.Constant] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Constant = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val value = unbuilder.readField[String]("value") + unbuilder.endObject() + sbt.librarymanagement.Constant(value) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Constant, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("value", obj.value) + builder.endObject() + } + } +} + +trait PatchFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val PatchFormat: JsonFormat[sbt.librarymanagement.Patch] = + new JsonFormat[sbt.librarymanagement.Patch] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Patch = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + + unbuilder.endObject() + sbt.librarymanagement.Patch() + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Patch, builder: Builder[J]): Unit = { + builder.beginObject() + + builder.endObject() + } + } +} + +trait FullFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val FullFormat: JsonFormat[sbt.librarymanagement.Full] = + new JsonFormat[sbt.librarymanagement.Full] { + override def read[J](jsOpt: Option[J], + unbuilder: Unbuilder[J]): sbt.librarymanagement.Full = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.Full(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.Full, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } + } +} + +trait CrossVersionFormats { + self: sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats => + implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = + flatUnionFormat6[sbt.librarymanagement.CrossVersion, + sbt.librarymanagement.Disabled, + sbt.librarymanagement.Disabled.type, + sbt.librarymanagement.Binary, + sbt.librarymanagement.Constant, + sbt.librarymanagement.Patch, + sbt.librarymanagement.Full]("type") +} diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index 3e729cd4d..774f77ee5 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -42,6 +42,16 @@ object DatatypeConfig { "sbt.internal.librarymanagement.formats.LogicalClockFormats" :: Nil } + case "sbt.librarymanagement.CrossVersion" => { _ => + "sbt.librarymanagement.CrossVersionFormats" :: + "sbt.librarymanagement.DisabledFormats" :: + "sbt.librarymanagement.BinaryFormats" :: + "sbt.librarymanagement.ConstantFormats" :: + "sbt.librarymanagement.PatchFormats" :: + "sbt.librarymanagement.FullFormats" :: + Nil + } + // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) From 2e971b9a8580211b95ac9aa2b95527335f51d43e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 3 Apr 2019 00:02:32 -0400 Subject: [PATCH 0826/1030] Add OkHttpClient parameter Ref #297 This adds a parameter so we can pass in OkHttpClient, if someone wants to customize HTTP behavior. --- build.sbt | 5 +++ .../librarymanagement/CustomHttp.scala | 21 +++++++++++ .../sbt/internal/librarymanagement/Ivy.scala | 10 ++++- .../internal/librarymanagement/IvyCache.scala | 2 +- .../ivyint/GigahorseUrlHandler.scala | 37 +++---------------- .../ivy/IvyDependencyResolution.scala | 6 ++- .../librarymanagement/ivy/IvyPublisher.scala | 6 ++- 7 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala diff --git a/build.sbt b/build.sbt index 01d30ad43..b1fb5d3dc 100644 --- a/build.sbt +++ b/build.sbt @@ -257,6 +257,11 @@ lazy val lmIvy = (project in file("ivy")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.InlineIvyConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPaths.copy*"), + + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.urlFactory"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.http"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.open"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.this"), ), ) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala new file mode 100644 index 000000000..9454affc4 --- /dev/null +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala @@ -0,0 +1,21 @@ +package sbt.internal.librarymanagement + +import gigahorse.HttpClient +import okhttp3.{ JavaNetAuthenticator => _, _ } +import sbt.librarymanagement.Http + +object CustomHttp { + private[this] def http0: HttpClient = Http.http + + private[sbt] def defaultHttpClientBuilder: OkHttpClient.Builder = { + http0 + .underlying[OkHttpClient] + .newBuilder() + .authenticator(new sbt.internal.librarymanagement.JavaNetAuthenticator) + .followRedirects(true) + .followSslRedirects(true) + } + + private[sbt] lazy val defaultHttpClient: OkHttpClient = + defaultHttpClientBuilder.build +} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 0312e573b..5cf1264f1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -7,6 +7,7 @@ import java.io.File import java.net.URI import java.util.concurrent.Callable +import okhttp3.OkHttpClient import org.apache.ivy.Ivy import org.apache.ivy.core.IvyPatternHelper import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } @@ -54,7 +55,12 @@ import ivyint.{ import sjsonnew.JsonFormat import sjsonnew.support.murmurhash.Hasher -final class IvySbt(val configuration: IvyConfiguration) { self => +final class IvySbt( + val configuration: IvyConfiguration, + val http: OkHttpClient +) { self => + def this(configuration: IvyConfiguration) = this(configuration, CustomHttp.defaultHttpClient) + /* * ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. @@ -80,7 +86,7 @@ final class IvySbt(val configuration: IvyConfiguration) { self => } private lazy val basicUrlHandler: URLHandler = new BasicURLHandler - private lazy val gigahorseUrlHandler: URLHandler = new GigahorseUrlHandler + private lazy val gigahorseUrlHandler: URLHandler = new GigahorseUrlHandler(http) private lazy val settings: IvySettings = { val dispatcher: URLHandlerDispatcher = URLHandlerRegistry.getDefault match { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index c21dc3a92..f56656a02 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -114,7 +114,7 @@ class IvyCache(val ivyHome: Option[File]) { .withResolvers(Vector(local)) .withLock(lock) .withLog(log) - (new IvySbt(conf), local) + (new IvySbt(conf, CustomHttp.defaultHttpClient), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 8d26f38d5..f90aa133f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -1,12 +1,12 @@ package sbt.internal.librarymanagement package ivyint -import java.net.{ HttpURLConnection, URL, UnknownHostException } +import java.net.{ URL, UnknownHostException } import java.io._ import scala.util.control.NonFatal -import okhttp3.{ MediaType, OkUrlFactory, Request, RequestBody } +import okhttp3.{ MediaType, Request, RequestBody } import okhttp3.internal.http.HttpDate import okhttp3.{ JavaNetAuthenticator => _, _ } @@ -18,7 +18,7 @@ import org.apache.ivy.util.url.URLHandler._ import sbt.io.IO // Copied from Ivy's BasicURLHandler. -class GigahorseUrlHandler extends AbstractURLHandler { +class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { import GigahorseUrlHandler._ @@ -45,7 +45,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) request.head() else request.get() - val response = okHttpClient.newCall(request.build()).execute() + val response = http.newCall(request.build()).execute() try { val infoOption = try { @@ -101,7 +101,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { .get() .build() - val response = okHttpClient.newCall(request).execute() + val response = http.newCall(request).execute() try { if (!checkStatusCode(url, response)) { throw new IOException( @@ -183,7 +183,7 @@ class GigahorseUrlHandler extends AbstractURLHandler { if (l != null) { l.start(new CopyProgressEvent()) } - val response = okHttpClient.newCall(request).execute() + val response = http.newCall(request).execute() try { if (l != null) { l.end(new CopyProgressEvent(EmptyBuffer, source.length())) @@ -197,10 +197,6 @@ class GigahorseUrlHandler extends AbstractURLHandler { } object GigahorseUrlHandler { - import gigahorse.HttpClient - import okhttp3.OkHttpClient - import sbt.librarymanagement.Http - // This is requires to access the constructor of URLInfo. private[sbt] class SbtUrlInfo(available: Boolean, contentLength: Long, @@ -214,27 +210,6 @@ object GigahorseUrlHandler { private val EmptyBuffer: Array[Byte] = new Array[Byte](0) - lazy val http: HttpClient = Http.http - - private lazy val okHttpClient: OkHttpClient = { - http - .underlying[OkHttpClient] - .newBuilder() - .authenticator(new sbt.internal.librarymanagement.JavaNetAuthenticator) - .followRedirects(true) - .followSslRedirects(true) - .build - } - - @deprecated("Use the Gigahorse HttpClient directly instead.", "librarymanagement-ivy 1.0.1") - private[sbt] def urlFactory = { - new OkUrlFactory(okHttpClient) - } - - @deprecated("Use the Gigahorse HttpClient directly instead.", "librarymanagement-ivy 1.0.1") - private[sbt] def open(url: URL): HttpURLConnection = - urlFactory.open(url) - private def checkStatusCode(url: URL, response: Response): Boolean = response.code() match { case 200 => true diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index 2f4985c46..1b93bacf7 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -2,6 +2,7 @@ package sbt package librarymanagement package ivy +import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger @@ -27,5 +28,8 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) object IvyDependencyResolution { def apply(ivyConfiguration: IvyConfiguration): DependencyResolution = - DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration))) + apply(ivyConfiguration, CustomHttp.defaultHttpClient) + + def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): DependencyResolution = + DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration, http))) } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index 8ae4a4481..643ef7c32 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -2,6 +2,7 @@ package sbt package librarymanagement package ivy +import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger import java.io.File @@ -31,5 +32,8 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface object IvyPublisher { def apply(ivyConfiguration: IvyConfiguration): Publisher = - Publisher(new IvyPublisher(new IvySbt(ivyConfiguration))) + apply(ivyConfiguration, CustomHttp.defaultHttpClient) + + def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): Publisher = + Publisher(new IvyPublisher(new IvySbt(ivyConfiguration, http))) } From 8c01d9f215d200cd77f12fedc6737f4a11d42680 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 4 Apr 2019 00:19:34 -0400 Subject: [PATCH 0827/1030] bump to Gigahorse 0.4.0 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 946c741fa..e34ad5617 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -59,7 +59,7 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.3.0" + val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.4.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" private def scala211Module(name: String, moduleVersion: String) = From a28b5464579986e2a171d2008c86756bdea60661 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Apr 2019 00:51:57 -0400 Subject: [PATCH 0828/1030] isolate Ivy homes during tests --- .../internal/librarymanagement/BaseIvySpecification.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index b8034995a..f6add3e61 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -11,9 +11,10 @@ import Configurations._ trait BaseIvySpecification extends AbstractEngineSpec { def currentBase: File = new File(".") - def currentTarget: File = currentBase / "target" / "ivyhome" - def currentManaged: File = currentBase / "target" / "lib_managed" - def currentDependency: File = currentBase / "target" / "dependency" + def label: String = this.getClass.getSimpleName + def currentTarget: File = currentBase / "target" / label / "ivyhome" + def currentManaged: File = currentBase / "target" / label / "lib_managed" + def currentDependency: File = currentBase / "target" / label / "dependency" def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) From 180af46fe5a3a611b3eae998e0b4433585283162 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Apr 2019 23:10:24 -0400 Subject: [PATCH 0829/1030] bump plugins --- .scalafmt.conf | 11 +++++++++++ .travis.yml | 2 +- build.sbt | 3 ++- project/plugins.sbt | 6 +++--- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e4ab36511..718ce5aed 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,3 +1,4 @@ +version = 2.0.0-RC6 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] @@ -8,3 +9,13 @@ docstrings = JavaDoc # This also seems more idiomatic to include whitespace in import x.{ yyy } spaces.inImportCurlyBraces = true + +# This is more idiomatic Scala. +# http://docs.scala-lang.org/style/indentation.html#methods-with-numerous-arguments +align.openParenCallSite = false +align.openParenDefnSite = false + +# For better code clarity +danglingParentheses = true + +trailingCommas = preserve diff --git a/.travis.yml b/.travis.yml index bdcda90eb..714aaabaf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,7 +42,7 @@ install: script: sbt -Dfile.encoding=UTF8 ++$TRAVIS_SCALA_VERSION! mimaReportBinaryIssues - scalafmt::test test:scalafmt::test sbt:scalafmt::test + scalafmtCheckAll whitesourceCheckPolicies test scriptedIvy diff --git a/build.sbt b/build.sbt index b1fb5d3dc..4b71318ee 100644 --- a/build.sbt +++ b/build.sbt @@ -29,6 +29,8 @@ def commonSettings: Seq[Setting[_]] = Def.settings( } }, inCompileAndTest(scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint")), + scalafmtOnCompile := true, + Test / scalafmtOnCompile := true, publishArtifact in Compile := true, publishArtifact in Test := false, parallelExecution in Test := false @@ -57,7 +59,6 @@ lazy val lmRoot = (project in file(".")) Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) }, bintrayPackage := "librarymanagement", - scalafmtOnCompile in Sbt := false, git.baseVersion := "1.3.0", version := { val v = version.value diff --git a/project/plugins.sbt b/project/plugins.sbt index 932866622..3794c4ca6 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.8") -addSbtPlugin("com.lucidchart" % "sbt-scalafmt" % "1.15") +addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.9") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.0") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.2") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.9") +addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From 6a36ce7689fb326235e96bb52b034e73e621d273 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Apr 2019 23:11:01 -0400 Subject: [PATCH 0830/1030] applying Scalafmt 2.0.0-RC6 with sbt/sbt rules --- .../AbstractEngineSpec.scala | 8 +- .../SemanticSelectorExtra.scala | 12 +- .../formats/NodeSeqFormat.scala | 2 +- .../ConfigurationExtra.scala | 17 +- .../ConfigurationFormats.scala | 20 ++- .../sbt/librarymanagement/CrossVersion.scala | 52 +++--- .../DependencyResolution.scala | 42 +++-- .../librarymanagement/EvictionWarning.scala | 8 +- .../LibraryManagementInterface.scala | 10 +- .../sbt/librarymanagement/Publisher.scala | 8 +- .../sbt/librarymanagement/ResolverExtra.scala | 6 +- .../librarymanagement/RichUpdateReport.scala | 14 +- .../librarymanagement/UpdateReportExtra.scala | 16 +- core/src/test/scala/ConfigMacroSpec.scala | 2 +- .../sbt/librarymanagement/ResolverTest.scala | 13 +- .../librarymanagement/ComponentManager.scala | 10 +- .../librarymanagement/ConvertResolver.scala | 8 +- .../librarymanagement/FakeResolver.scala | 5 +- .../sbt/internal/librarymanagement/Ivy.scala | 50 +++--- .../librarymanagement/IvyActions.scala | 26 ++- .../internal/librarymanagement/IvyCache.scala | 4 +- .../internal/librarymanagement/MakePom.scala | 154 ++++++++++-------- .../CachedResolutionResolveEngine.scala | 42 +++-- .../ivyint/GigahorseUrlHandler.scala | 37 +++-- .../ivyint/ParallelResolveEngine.scala | 33 ++-- .../ivyint/SbtChainResolver.scala | 30 ++-- .../ivy/IvyDependencyResolution.scala | 10 +- .../librarymanagement/ivy/IvyPublisher.scala | 16 +- .../ivy/formats/UpdateOptionsFormat.scala | 4 +- .../BaseCachedResolutionSpec.scala | 8 +- .../BaseIvySpecification.scala | 32 ++-- .../ComponentManagerTest.scala | 10 +- .../DMSerializationSpec.scala | 18 +- .../EvictionWarningSpec.scala | 3 +- .../librarymanagement/FrozenModeSpec.scala | 6 +- .../librarymanagement/IvyRepoSpec.scala | 24 +-- .../librarymanagement/ScalaOverrideTest.scala | 120 +++++++++----- 37 files changed, 544 insertions(+), 336 deletions(-) diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala index f8b404e9f..e676b7857 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala @@ -5,9 +5,11 @@ import sbt.librarymanagement._ abstract class AbstractEngineSpec extends UnitSpec { def cleanCache(): Unit - def module(moduleId: ModuleID, - deps: Vector[ModuleID], - scalaFullVersion: Option[String]): ModuleDescriptor + def module( + moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String] + ): ModuleDescriptor def updateEither(module: ModuleDescriptor): Either[UnresolvedWarning, UpdateReport] diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index 49990d1df..c609a1529 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -19,7 +19,8 @@ private[librarymanagement] abstract class SemSelAndChunkFunctions { // from and to can not have an operator. if (hasOperator(fromStr) || hasOperator(toStr)) { throw new IllegalArgumentException( - s"Invalid ' - ' range, both side of comparators can not have an operator: $fromStr - $toStr") + s"Invalid ' - ' range, both side of comparators can not have an operator: $fromStr - $toStr" + ) } val from = SemComparator(fromStr) val to = SemComparator(toStr) @@ -33,7 +34,8 @@ private[librarymanagement] abstract class SemSelAndChunkFunctions { (comparatorsBefore ++ comparatorsAfter) case _ => throw new IllegalArgumentException( - s"Invalid ' - ' range position, both side of versions must be specified: $andClauseToken") + s"Invalid ' - ' range position, both side of versions must be specified: $andClauseToken" + ) } } SemSelAndChunk(comparators.flatMap(_.expandWildcard)) @@ -165,7 +167,8 @@ private[librarymanagement] abstract class SemComparatorFunctions { if (hasXrangeSelector) { if (tags.nonEmpty) throw new IllegalArgumentException( - s"Pre-release version requires major, minor, patch versions to be specified: $comparator") + s"Pre-release version requires major, minor, patch versions to be specified: $comparator" + ) val numbers = Seq(major, minor, patch).takeWhile { case Some(str) => str.matches("\\d+") case None => false @@ -180,7 +183,8 @@ private[librarymanagement] abstract class SemComparatorFunctions { } else { if (tags.nonEmpty && (major.isEmpty || minor.isEmpty || patch.isEmpty)) throw new IllegalArgumentException( - s"Pre-release version requires major, minor, patch versions to be specified: $comparator") + s"Pre-release version requires major, minor, patch versions to be specified: $comparator" + ) val operator = opStr match { case Some("<") => Lt case Some("<=") => Lte diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala index 2a81aa37b..45704dfa6 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/NodeSeqFormat.scala @@ -5,7 +5,7 @@ import scala.xml._ trait NodeSeqFormat { self: BasicJsonProtocol => implicit lazy val NodeSeqFormat: JsonFormat[NodeSeq] = projectFormat[NodeSeq, String]( - xml => { xml }.toString, + xml => {xml}.toString, str => XML.loadString(str).child ) } diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index b8e339526..d15297198 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -90,12 +90,14 @@ private[librarymanagement] abstract class ConfigurationExtra { def describedAs(newDescription: String) = Configuration.of(id, name, newDescription, isPublic, extendsConfigs, transitive) def extend(configs: Configuration*) = - Configuration.of(id, - name, - description, - isPublic, - configs.toVector ++ extendsConfigs, - transitive) + Configuration.of( + id, + name, + description, + isPublic, + configs.toVector ++ extendsConfigs, + transitive + ) def notTransitive = intransitive def intransitive = Configuration.of(id, name, description, isPublic, extendsConfigs, false) def hide = Configuration.of(id, name, description, false, extendsConfigs, transitive) @@ -109,7 +111,8 @@ private[sbt] object ConfigurationMacro { val enclosingValName = definingValName( c, methodName => - s"""$methodName must be directly assigned to a val, such as `val Tooling = $methodName("tooling")`.""") + s"""$methodName must be directly assigned to a val, such as `val Tooling = $methodName("tooling")`.""" + ) if (enclosingValName.head.isLower) { c.error(c.enclosingPosition, "configuration id must be capitalized") } diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala index c292cbc29..66bea9aae 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationFormats.scala @@ -10,8 +10,10 @@ trait ConfigurationFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ConfigurationFormat: JsonFormat[sbt.librarymanagement.Configuration] = new JsonFormat[sbt.librarymanagement.Configuration] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Configuration = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Configuration = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -23,12 +25,14 @@ trait ConfigurationFormats { unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("extendsConfigs") val transitive = unbuilder.readField[Boolean]("transitive") unbuilder.endObject() - new sbt.librarymanagement.Configuration(id, - name, - description, - isPublic, - extendsConfigs, - transitive) + new sbt.librarymanagement.Configuration( + id, + name, + description, + isPublic, + extendsConfigs, + transitive + ) case None => deserializationError("Expected JsObject but found None") } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala index c93702ded..6c37596b3 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -175,8 +175,10 @@ object Full { trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = new JsonFormat[sbt.librarymanagement.Disabled] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Disabled = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -196,8 +198,10 @@ trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val DisabledObjectFormat: JsonFormat[sbt.librarymanagement.Disabled.type] = new JsonFormat[sbt.librarymanagement.Disabled.type] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled.type = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Disabled.type = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -219,8 +223,10 @@ trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => trait BinaryFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val BinaryFormat: JsonFormat[sbt.librarymanagement.Binary] = new JsonFormat[sbt.librarymanagement.Binary] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Binary = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Binary = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -244,8 +250,10 @@ trait BinaryFormats { self: sjsonnew.BasicJsonProtocol => trait ConstantFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ConstantFormat: JsonFormat[sbt.librarymanagement.Constant] = new JsonFormat[sbt.librarymanagement.Constant] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Constant = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Constant = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -267,8 +275,10 @@ trait ConstantFormats { self: sjsonnew.BasicJsonProtocol => trait PatchFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val PatchFormat: JsonFormat[sbt.librarymanagement.Patch] = new JsonFormat[sbt.librarymanagement.Patch] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Patch = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Patch = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -290,8 +300,10 @@ trait PatchFormats { self: sjsonnew.BasicJsonProtocol => trait FullFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val FullFormat: JsonFormat[sbt.librarymanagement.Full] = new JsonFormat[sbt.librarymanagement.Full] { - override def read[J](jsOpt: Option[J], - unbuilder: Unbuilder[J]): sbt.librarymanagement.Full = { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.Full = { jsOpt match { case Some(js) => unbuilder.beginObject(js) @@ -320,11 +332,13 @@ trait CrossVersionFormats { with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats => implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = - flatUnionFormat6[sbt.librarymanagement.CrossVersion, - sbt.librarymanagement.Disabled, - sbt.librarymanagement.Disabled.type, - sbt.librarymanagement.Binary, - sbt.librarymanagement.Constant, - sbt.librarymanagement.Patch, - sbt.librarymanagement.Full]("type") + flatUnionFormat6[ + sbt.librarymanagement.CrossVersion, + sbt.librarymanagement.Disabled, + sbt.librarymanagement.Disabled.type, + sbt.librarymanagement.Binary, + sbt.librarymanagement.Constant, + sbt.librarymanagement.Patch, + sbt.librarymanagement.Full + ]("type") } diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index f9f2f41cc..500f569e5 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -30,9 +30,11 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface * @param configurations The configurations that this module has. * @return A `ModuleDescriptor` describing a subproject and its dependencies. */ - def moduleDescriptor(moduleId: ModuleID, - directDependencies: Vector[ModuleID], - scalaModuleInfo: Option[ScalaModuleInfo]): ModuleDescriptor = { + def moduleDescriptor( + moduleId: ModuleID, + directDependencies: Vector[ModuleID], + scalaModuleInfo: Option[ScalaModuleInfo] + ): ModuleDescriptor = { val moduleSetting = ModuleDescriptorConfiguration(moduleId, ModuleInfo(moduleId.name)) .withScalaModuleInfo(scalaModuleInfo) .withDependencies(directDependencies) @@ -49,10 +51,12 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface * @return The result, either an unresolved warning or an update report. Note that this * update report will or will not be successful depending on the `missingOk` option. */ - def update(module: ModuleDescriptor, - configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, - log: Logger): Either[UnresolvedWarning, UpdateReport] = + def update( + module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger + ): Either[UnresolvedWarning, UpdateReport] = lmEngine.update(module, configuration, uwconfig, log) /** @@ -71,8 +75,10 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface * @param scalaModuleInfo The information about the Scala verson used, if any. * @return A `ModuleDescriptor` that depends on `dependencyId`. */ - def wrapDependencyInModule(dependencyId: ModuleID, - scalaModuleInfo: Option[ScalaModuleInfo]): ModuleDescriptor = { + def wrapDependencyInModule( + dependencyId: ModuleID, + scalaModuleInfo: Option[ScalaModuleInfo] + ): ModuleDescriptor = { val sha1 = Hash.toHex(Hash(dependencyId.name)) val dummyID = ModuleID(sbtOrgTemp, modulePrefixTemp + sha1, dependencyId.revision) .withConfigurations(dependencyId.configurations) @@ -88,10 +94,12 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface * @param log The logger. * @return The result, either an unresolved warning or a sequence of files. */ - def retrieve(dependencyId: ModuleID, - scalaModuleInfo: Option[ScalaModuleInfo], - retrieveDirectory: File, - log: Logger): Either[UnresolvedWarning, Vector[File]] = + def retrieve( + dependencyId: ModuleID, + scalaModuleInfo: Option[ScalaModuleInfo], + retrieveDirectory: File, + log: Logger + ): Either[UnresolvedWarning, Vector[File]] = retrieve(wrapDependencyInModule(dependencyId, scalaModuleInfo), retrieveDirectory, log) /** @@ -102,9 +110,11 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface * @param log The logger. * @return The result, either an unresolved warning or a sequence of files. */ - def retrieve(module: ModuleDescriptor, - retrieveDirectory: File, - log: Logger): Either[UnresolvedWarning, Vector[File]] = { + def retrieve( + module: ModuleDescriptor, + retrieveDirectory: File, + log: Logger + ): Either[UnresolvedWarning, Vector[File]] = { // Using the default artifact type filter here, so sources and docs are excluded. val retrieveConfiguration = RetrieveConfiguration() .withRetrieveDirectory(retrieveDirectory) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 04da1a4c6..22405934c 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -98,7 +98,7 @@ object EvictionWarningOptions { guessSbtOne orElse guessSecondSegment orElse guessSemVer orElse guessFalse lazy val guessSecondSegment - : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), Some(scalaModuleInfo)) if m2.name.endsWith("_" + scalaModuleInfo.scalaFullVersion) || m2.name.endsWith( "_" + scalaModuleInfo.scalaBinaryVersion @@ -112,7 +112,7 @@ object EvictionWarningOptions { } lazy val guessSbtOne - : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), Some(scalaModuleInfo)) if (m2.organization == "org.scala-sbt") && (m2.name.endsWith("_" + scalaModuleInfo.scalaFullVersion) || @@ -126,7 +126,7 @@ object EvictionWarningOptions { } lazy val guessSemVer - : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (m1, Some(m2), _) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => @@ -137,7 +137,7 @@ object EvictionWarningOptions { } lazy val guessFalse - : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (_, _, _) => false } } diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala index 5236a1a2a..cdca4a8dc 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementInterface.scala @@ -26,10 +26,12 @@ trait DependencyResolutionInterface { * @return The result, either an unresolved warning or an update report. Note that this * update report will or will not be successful depending on the `missingOk` option. */ - def update(module: ModuleDescriptor, - configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, - log: Logger): Either[UnresolvedWarning, UpdateReport] + def update( + module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger + ): Either[UnresolvedWarning, UpdateReport] } /** diff --git a/core/src/main/scala/sbt/librarymanagement/Publisher.scala b/core/src/main/scala/sbt/librarymanagement/Publisher.scala index da3e09e6f..c071240f9 100644 --- a/core/src/main/scala/sbt/librarymanagement/Publisher.scala +++ b/core/src/main/scala/sbt/librarymanagement/Publisher.scala @@ -35,9 +35,11 @@ class Publisher private[sbt] (publisherEngine: PublisherInterface) { * @param log The logger. * @return The `File` containing the POM descriptor. */ - def makePomFile(module: ModuleDescriptor, - configuration: MakePomConfiguration, - log: Logger): File = + def makePomFile( + module: ModuleDescriptor, + configuration: MakePomConfiguration, + log: Logger + ): File = publisherEngine.makePomFile(module, configuration, log) } diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 03974baba..d359f31ad 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -169,8 +169,10 @@ private[librarymanagement] abstract class ResolverFunctions { * Add the local Ivy repository to the user repositories. * If `mavenCentral` is true, add the Maven Central repository. */ - def combineDefaultResolvers(userResolvers: Vector[Resolver], - mavenCentral: Boolean): Vector[Resolver] = + def combineDefaultResolvers( + userResolvers: Vector[Resolver], + mavenCentral: Boolean + ): Vector[Resolver] = combineDefaultResolvers(userResolvers, jcenter = false, mavenCentral) /** diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index c97bf9da1..f66440bbb 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -14,12 +14,14 @@ final class RichUpdateReport(report: UpdateReport) { val stamps = files .map( f => - (f, - // TODO: The list of files may also contain some odd files that do not actually exist like: - // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". - // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such - // files to begin with, in principle. - IO.getModifiedTimeOrZero(f)) + ( + f, + // TODO: The list of files may also contain some odd files that do not actually exist like: + // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". + // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such + // files to begin with, in principle. + IO.getModifiedTimeOrZero(f) + ) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 9a498c024..1ffba5008 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -74,24 +74,32 @@ private[librarymanagement] abstract class ModuleReportExtra { reportStr( "extraAttributes", if (extraAttributes.isEmpty) None - else { Some(extraAttributes.toString) } + else { + Some(extraAttributes.toString) + } ) + reportStr("isDefault", isDefault map { _.toString }) + reportStr("branch", branch) + reportStr( "configurations", if (configurations.isEmpty) None - else { Some(configurations.mkString(", ")) } + else { + Some(configurations.mkString(", ")) + } ) + reportStr( "licenses", if (licenses.isEmpty) None - else { Some(licenses.mkString(", ")) } + else { + Some(licenses.mkString(", ")) + } ) + reportStr( "callers", if (callers.isEmpty) None - else { Some(callers.mkString(", ")) } + else { + Some(callers.mkString(", ")) + } ) private[sbt] def reportStr(key: String, value: Option[String]): String = value map { x => diff --git a/core/src/test/scala/ConfigMacroSpec.scala b/core/src/test/scala/ConfigMacroSpec.scala index 93810a96a..c35ab104b 100644 --- a/core/src/test/scala/ConfigMacroSpec.scala +++ b/core/src/test/scala/ConfigMacroSpec.scala @@ -55,7 +55,7 @@ object ConfigMacroSpec extends Properties("ConfigMacroSpec") { s"Actual name: ${c.name}" |: s"Actual isPublic: ${c.isPublic}" |: (c.id == id) && - (c.name == name) && + (c.name == name) && (c.isPublic == isPublic) } } diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala index d98eab799..70f7c19cd 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala @@ -11,11 +11,14 @@ object ResolverTest extends UnitSpec { val patsExpected = Vector("http://foo.com/test/[orgPath]") val patterns = Resolver .url("test", new URL("http://foo.com/test"))( - Patterns(pats, - pats, - isMavenCompatible = false, - descriptorOptional = true, - skipConsistencyCheck = true)) + Patterns( + pats, + pats, + isMavenCompatible = false, + descriptorOptional = true, + skipConsistencyCheck = true + ) + ) .patterns patterns.ivyPatterns shouldBe patsExpected diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index a973f59e1..ed42cd14c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -30,7 +30,9 @@ class ComponentManager( def files(id: String)(ifMissing: IfMissing): Iterable[File] = { def fromGlobal = lockGlobalCache { - try { update(id); getOrElse(createAndCache) } catch { + try { + update(id); getOrElse(createAndCache) + } catch { case _: NotInCache => createAndCache } } @@ -100,7 +102,11 @@ object ComponentManager { lazy val (version, timestamp) = { val properties = new java.util.Properties val propertiesStream = versionResource.openStream - try { properties.load(propertiesStream) } finally { propertiesStream.close() } + try { + properties.load(propertiesStream) + } finally { + propertiesStream.close() + } (properties.getProperty("version"), properties.getProperty("timestamp")) } lazy val stampedVersion = version + "_" + timestamp diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 2c9a79357..43020d215 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -246,9 +246,11 @@ private[sbt] object ConvertResolver { def managedChecksumsEnabled: Boolean import sbt.io.syntax._ - private def downloadChecksum(resource: Resource, - targetChecksumFile: File, - algorithm: String): Boolean = { + private def downloadChecksum( + resource: Resource, + targetChecksumFile: File, + algorithm: String + ): Boolean = { if (!ChecksumHelper.isKnownAlgorithm(algorithm)) throw new IllegalArgumentException(s"Unknown checksum algorithm: $algorithm") diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index c84dcc50a..794fff9e3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -178,8 +178,9 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val artifact = for { artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) - artifact <- artifacts find (a => - a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt) + artifact <- artifacts find ( + a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt + ) } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) artifact.orNull diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 5cf1264f1..cc381573e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -73,7 +73,11 @@ final class IvySbt( IvySbt.synchronized { val originalLogger = Message.getDefaultLogger Message.setDefaultLogger(logger) - try { f } finally { Message.setDefaultLogger(originalLogger) } + try { + f + } finally { + Message.setDefaultLogger(originalLogger) + } } // Ivy is not thread-safe nor can the cache be used concurrently. // If provided a GlobalLock, we can use that to ensure safe access to the cache. @@ -207,7 +211,9 @@ final class IvySbt( ivyint.ErrorMessageAuthenticator.install() ivy.pushContext() ivy.getLoggerEngine.pushLogger(log) - try { f(ivy) } finally { + try { + f(ivy) + } finally { ivy.getLoggerEngine.popLogger() ivy.popContext() } @@ -275,7 +281,8 @@ final class IvySbt( IvySbt.setConflictManager(moduleID, conflictManager, ivy.getSettings) val defaultConf = defaultConfiguration getOrElse Configuration.of( "Default", - ModuleDescriptor.DEFAULT_CONFIGURATION) + ModuleDescriptor.DEFAULT_CONFIGURATION + ) log.debug( s"Using inline dependencies specified in Scala${(if (ivyXML.isEmpty) "" else " and XML")}." ) @@ -383,7 +390,7 @@ final class IvySbt( // Redefine to use a subset of properties, that are serialisable override implicit lazy val InlineIvyConfigurationFormat - : JsonFormat[InlineIvyConfiguration] = { + : JsonFormat[InlineIvyConfiguration] = { def hlToInlineIvy(i: InlineIvyHL): InlineIvyConfiguration = { val ( paths, @@ -406,7 +413,7 @@ final class IvySbt( // Redefine to use a subset of properties, that are serialisable override implicit lazy val ExternalIvyConfigurationFormat - : JsonFormat[ExternalIvyConfiguration] = { + : JsonFormat[ExternalIvyConfiguration] = { def hlToExternalIvy(e: ExternalIvyHL): ExternalIvyConfiguration = { val (baseDirectory, _) = e ExternalIvyConfiguration( @@ -729,9 +736,11 @@ private[sbt] object IvySbt { allConfigurations: Vector[ConfigRef] ): MDArtifact = { val artifact = new MDArtifact(moduleID, a.name, a.`type`, a.extension, null, extra(a, false)) - copyConfigurations(a, - (ref: ConfigRef) => { artifact.addConfiguration(ref.name) }, - allConfigurations) + copyConfigurations( + a, + (ref: ConfigRef) => { artifact.addConfiguration(ref.name) }, + allConfigurations + ) artifact } def getExtraAttributes(revID: ExtendableItem): Map[String, String] = { @@ -757,21 +766,21 @@ private[sbt] object IvySbt { private def wrapped(module: ModuleID, dependencies: NodeSeq) = { { - if (hasInfo(module, dependencies)) - NodeSeq.Empty - else - addExtraAttributes(defaultInfo(module), module.extraAttributes) - } - { dependencies } + if (hasInfo(module, dependencies)) + NodeSeq.Empty + else + addExtraAttributes(defaultInfo(module), module.extraAttributes) + } + {dependencies} { - // this is because Ivy adds a default artifact if none are specified. - if ((dependencies \\ "publications").isEmpty) else NodeSeq.Empty - } + // this is because Ivy adds a default artifact if none are specified. + if ((dependencies \\ "publications").isEmpty) else NodeSeq.Empty + } } private[this] def defaultInfo(module: ModuleID): scala.xml.Elem = { import module._ - val base = + val base = branchName.fold(base) { br => base % new scala.xml.UnprefixedAttribute("branch", br, scala.xml.Null) } @@ -784,7 +793,7 @@ private[sbt] object IvySbt { case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { - val info = { x } \ "info" + val info = {x} \ "info" if (info.nonEmpty) { def check(found: NodeSeq, expected: String, label: String) = if (found.isEmpty) @@ -995,7 +1004,8 @@ private[sbt] object IvySbt { ): Unit = excludes.foreach(exclude => addExclude(moduleID, scalaModuleInfo)(exclude)) def addExclude(moduleID: DefaultModuleDescriptor, scalaModuleInfo: Option[ScalaModuleInfo])( - exclude0: ExclusionRule): Unit = { + exclude0: ExclusionRule + ): Unit = { // this adds _2.11 postfix val exclude = CrossVersion.substituteCross(exclude0, scalaModuleInfo) val confs = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 29e9683d8..ffa2f733e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -152,7 +152,11 @@ object IvyActions { ): T = { val previous = resolver.getChecksumAlgorithms resolver.setChecksums(checksums mkString ",") - try { act } finally { resolver.setChecksums(previous mkString ",") } + try { + act + } finally { + resolver.setChecksums(previous mkString ",") + } } private def crossVersionMap(moduleSettings: ModuleSettings): Option[String => String] = moduleSettings match { @@ -367,12 +371,14 @@ object IvyActions { resolveOptions.setTransitive(false) resolveOptions.setCheckIfChanged(false) } - resolver.customResolve(descriptor, - missingOk, - updateConfiguration.logicalClock, - resolveOptions, - cache, - log) + resolver.customResolve( + descriptor, + missingOk, + updateConfiguration.logicalClock, + resolveOptions, + cache, + log + ) } private def retrieve( @@ -496,7 +502,11 @@ object IvyActions { resolver.commitPublishTransaction() } catch { case e: Throwable => - try { resolver.abortPublishTransaction() } finally { throw e } + try { + resolver.abortPublishTransaction() + } finally { + throw e + } } } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index f56656a02..9e8f28aa8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -58,7 +58,9 @@ class IvyCache(val ivyHome: Option[File]) { /** Clears the cache of the jar for the given ID.*/ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { - try { withCachedJar(id, lock, log)(_.delete); () } catch { + try { + withCachedJar(id, lock, log)(_.delete); () + } catch { case e: Exception => log.debug("Error cleaning cached jar: " + e.toString) } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 80b466b5a..4f172ce94 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -137,27 +137,27 @@ class MakePom(val log: Logger) { ): XNode = ( 4.0.0 - { makeModuleID(module) } - { moduleInfo.nameFormal } - { makeStartYear(moduleInfo) } - { makeOrganization(moduleInfo) } - { makeScmInfo(moduleInfo) } - { makeDeveloperInfo(moduleInfo) } - { extra } + {makeModuleID(module)} + {moduleInfo.nameFormal} + {makeStartYear(moduleInfo)} + {makeOrganization(moduleInfo)} + {makeScmInfo(moduleInfo)} + {makeDeveloperInfo(moduleInfo)} + {extra} { - val deps = depsInConfs(module, configurations) - makeProperties(module, deps) ++ - makeDependencies(deps, includeTypes, module.getAllExcludeRules) - } - { makeRepositories(ivy.getSettings, allRepositories, filterRepositories) } + val deps = depsInConfs(module, configurations) + makeProperties(module, deps) ++ + makeDependencies(deps, includeTypes, module.getAllExcludeRules) + } + {makeRepositories(ivy.getSettings, allRepositories, filterRepositories)} ) def makeModuleID(module: ModuleDescriptor): NodeSeq = { val mrid = moduleDescriptor(module) val a: NodeSeq = - ({ mrid.getOrganisation } - { mrid.getName } - { packaging(module) }) + ({mrid.getOrganisation} + {mrid.getName} + {packaging(module)}) val b: NodeSeq = ((description(module.getDescription) ++ homePage(module.getHomePage) ++ @@ -168,32 +168,32 @@ class MakePom(val log: Logger) { def makeStartYear(moduleInfo: ModuleInfo): NodeSeq = moduleInfo.startYear match { - case Some(y) => { y } + case Some(y) => {y} case _ => NodeSeq.Empty } def makeOrganization(moduleInfo: ModuleInfo): NodeSeq = { - { moduleInfo.organizationName } + {moduleInfo.organizationName} { - moduleInfo.organizationHomepage match { - case Some(h)=> { h } - case _ => NodeSeq.Empty - } + moduleInfo.organizationHomepage match { + case Some(h) => {h} + case _ => NodeSeq.Empty } + } } def makeScmInfo(moduleInfo: ModuleInfo): NodeSeq = { moduleInfo.scmInfo match { case Some(s) => - { s.browseUrl } - { s.connection } + {s.browseUrl} + {s.connection} { - s.devConnection match { - case Some(d)=> { d } - case _=> NodeSeq.Empty - } + s.devConnection match { + case Some(d) => {d} + case _ => NodeSeq.Empty } + } case _ => NodeSeq.Empty } @@ -202,20 +202,20 @@ class MakePom(val log: Logger) { if (moduleInfo.developers.nonEmpty) { { - moduleInfo.developers.map { developer: Developer => - - { developer.id } - { developer.name } - { developer.url } + moduleInfo.developers.map { developer: Developer => + + {developer.id} + {developer.name} + {developer.url} { - developer.email match { - case "" | null => NodeSeq.Empty - case e => { e } - } - } - + developer.email match { + case "" | null => NodeSeq.Empty + case e => {e} + } } + } + } } else NodeSeq.Empty } @@ -232,7 +232,8 @@ class MakePom(val log: Logger) { if (k == PomExtraDependencyAttributes.ExtraAttributesKey) xmlSpacePreserve else scala.xml.Null { - for ((key, value) <- extra) yield ({ value }).copy(label = key, attributes = _extraAttributes(key)) + for ((key, value) <- extra) + yield ({value}).copy(label = key, attributes = _extraAttributes(key)) } } @@ -244,18 +245,34 @@ class MakePom(val log: Logger) { def xmlSpacePreserve = new PrefixedAttribute("xml", "space", "preserve", scala.xml.Null) def description(d: String) = - if ((d eq null) || d.isEmpty) NodeSeq.Empty else { d } + if ((d eq null) || d.isEmpty) NodeSeq.Empty + else + { + d + } def licenses(ls: Array[License]) = - if (ls == null || ls.isEmpty) NodeSeq.Empty else { ls.map(license) } + if (ls == null || ls.isEmpty) NodeSeq.Empty + else + { + ls.map(license) + } def license(l: License) = - { l.getName } - { l.getUrl } + {l.getName} + {l.getUrl} repo - def homePage(homePage: String) = if (homePage eq null) NodeSeq.Empty else { homePage } + def homePage(homePage: String) = + if (homePage eq null) NodeSeq.Empty + else + { + homePage + } def revision(version: String) = - if (version ne null) { version } else NodeSeq.Empty + if (version ne null) { + version + } + else NodeSeq.Empty def packaging(module: ModuleDescriptor) = module.getAllArtifacts match { case Array() => "pom" @@ -286,7 +303,9 @@ class MakePom(val log: Logger) { NodeSeq.Empty else - { dependencies.map(makeDependency(_, includeTypes, excludes)) } + { + dependencies.map(makeDependency(_, includeTypes, excludes)) + } @deprecated("Use `makeDependency` variant which takes excludes", "0.13.9") @@ -360,14 +379,14 @@ class MakePom(val log: Logger) { ): Elem = { val mrid = dependency.getDependencyRevisionId - { mrid.getOrganisation } - { mrid.getName } - { makeDependencyVersion(mrid.getRevision) } - { scopeElem(scope) } - { optionalElem(optional) } - { classifierElem(classifier) } - { typeElem(tpe) } - { exclusions(dependency, excludes) } + {mrid.getOrganisation} + {mrid.getName} + {makeDependencyVersion(mrid.getRevision)} + {scopeElem(scope)} + {optionalElem(optional)} + {classifierElem(classifier)} + {typeElem(tpe)} + {exclusions(dependency, excludes)} } @@ -385,7 +404,7 @@ class MakePom(val log: Logger) { } def typeElem(tpe: Option[String]): NodeSeq = tpe match { - case Some(t) => { t } + case Some(t) => {t} case None => NodeSeq.Empty } @@ -393,7 +412,7 @@ class MakePom(val log: Logger) { Option(artifact.getExtraAttribute("classifier")) def classifierElem(classifier: Option[String]): NodeSeq = classifier match { - case Some(c) => { c } + case Some(c) => {c} case None => NodeSeq.Empty } @@ -404,7 +423,7 @@ class MakePom(val log: Logger) { } def scopeElem(scope: Option[String]): NodeSeq = scope match { case None | Some(Configurations.Compile.name) => NodeSeq.Empty - case Some(s) => { s } + case Some(s) => {s} } def optionalElem(opt: Boolean) = if (opt) true else NodeSeq.Empty def moduleDescriptor(module: ModuleDescriptor) = module.getModuleRevisionId @@ -426,7 +445,9 @@ class MakePom(val log: Logger) { val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) - if (excls.nonEmpty) { excls } + if (excls.nonEmpty) { + excls + } else NodeSeq.Empty } def makeExclusion(exclRule: ExcludeRule): Either[String, NodeSeq] = { @@ -440,8 +461,8 @@ class MakePom(val log: Logger) { else Right( - { g } - { a } + {g} + {a} ) } @@ -466,7 +487,10 @@ class MakePom(val log: Logger) { } val repositoryElements = mavenRepositories.filter(filterRepositories).map(mavenRepository) if (repositoryElements.isEmpty) repositoryElements - else { repositoryElements } + else + { + repositoryElements + } } def allResolvers(settings: IvySettings): Seq[DependencyResolver] = flatten(castResolvers(settings.getResolvers)).distinct @@ -487,10 +511,10 @@ class MakePom(val log: Logger) { mavenRepository(toID(repo.name), repo.name, repo.root) def mavenRepository(id: String, name: String, root: String): XNode = - { id } - { name } - { root } - { "default" } + {id} + {name} + {root} + {"default"} /** diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 14635136c..d9cadfd81 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -51,12 +51,12 @@ private[sbt] class CachedResolutionResolveCache { concurrent.TrieMap() // Used for subproject val projectReportCache - : concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = + : concurrent.Map[(ModuleRevisionId, LogicalClock), Either[ResolveException, UpdateReport]] = concurrent.TrieMap() val resolveReportCache: concurrent.Map[ModuleRevisionId, ResolveReport] = concurrent.TrieMap() val resolvePropertiesCache: concurrent.Map[ModuleRevisionId, String] = concurrent.TrieMap() val conflictCache - : concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = + : concurrent.Map[(ModuleID, ModuleID), (Vector[ModuleID], Vector[ModuleID], String)] = concurrent.TrieMap() val maxConflictCacheSize: Int = 1024 val maxUpdateReportCacheSize: Int = 1024 @@ -188,11 +188,13 @@ private[sbt] class CachedResolutionResolveCache { val (pathOrg, pathName, pathRevision, pathScalaVersion, pathSbtVersion) = md match { case x: ArtificialModuleDescriptor => val tmrid = x.targetModuleRevisionId - (tmrid.getOrganisation, - tmrid.getName, - tmrid.getRevision + "_" + mrid.getName, - scalaVersion(tmrid), - sbtVersion(tmrid)) + ( + tmrid.getOrganisation, + tmrid.getName, + tmrid.getRevision + "_" + mrid.getName, + scalaVersion(tmrid), + sbtVersion(tmrid) + ) case _ => (mrid.getOrganisation, mrid.getName, mrid.getRevision, scalaVersion(mrid), sbtVersion(mrid)) } @@ -328,7 +330,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val ivy = makeInstance ivy.pushContext() ivy.getLoggerEngine.pushLogger(log) - try { f(ivy) } finally { + try { + f(ivy) + } finally { ivy.getLoggerEngine.popLogger() ivy.popContext() } @@ -336,7 +340,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { def withDefaultLogger[A](log: MessageLogger)(f: => A): A = { val originalLogger = Message.getDefaultLogger Message.setDefaultLogger(log) - try { f } finally { Message.setDefaultLogger(originalLogger) } + try { + f + } finally { + Message.setDefaultLogger(originalLogger) + } } /** @@ -488,8 +496,10 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { case (failed, paths) => if (paths.isEmpty) (failed, paths) else - (failed, - List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail) + ( + failed, + List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail + ) } } new ResolveException(messages, failed, ListMap(failedPaths: _*)) @@ -577,8 +587,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { ((organization, name), xs) }: _*) // this returns a List of Lists of (org, name). should be deterministic - def detectLoops(allModules: Map[(String, String), Vector[OrganizationArtifactReport]]) - : List[List[(String, String)]] = { + def detectLoops( + allModules: Map[(String, String), Vector[OrganizationArtifactReport]] + ): List[List[(String, String)]] = { val loopSets: mutable.Set[Set[(String, String)]] = mutable.Set.empty val loopLists: mutable.ListBuffer[List[(String, String)]] = mutable.ListBuffer.empty def testLoop( @@ -949,8 +960,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val configurations0: Vector[ConfigurationReport] = ur.configurations.toVector // This is how md looks from md0 via dd's mapping. val remappedConfigs0: Map[String, Vector[String]] = Map(rootModuleConfs map { conf0 => - val remapped - : Vector[String] = dd.getDependencyConfigurations(conf0.getName).toVector flatMap { conf => + val remapped: Vector[String] = dd + .getDependencyConfigurations(conf0.getName) + .toVector flatMap { conf => node.getRealConfs(conf).toVector } conf0.getName -> remapped diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index f90aa133f..72c7c58b4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -52,12 +52,16 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { if (checkStatusCode(url, response)) { val bodyCharset = BasicURLHandler.getCharSetFromContentType( - Option(response.body().contentType()).map(_.toString).orNull) + Option(response.body().contentType()).map(_.toString).orNull + ) Some( - new SbtUrlInfo(true, - response.body().contentLength(), - lastModifiedTimestamp(response), - bodyCharset)) + new SbtUrlInfo( + true, + response.body().contentLength(), + lastModifiedTimestamp(response), + bodyCharset + ) + ) } else None // // Commented out for now - can potentially be used for non HTTP urls @@ -75,7 +79,8 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { Message.warn("Host " + e.getMessage + " not found. url=" + url) Message.info( "You probably access the destination server through " - + "a proxy server that is not well configured.") + + "a proxy server that is not well configured." + ) None case e: IOException => Message.error("Server access Error: " + e.getMessage + " url=" + url) @@ -106,7 +111,8 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { if (!checkStatusCode(url, response)) { throw new IOException( "The HTTP response code for " + url + " did not indicate a success." - + " See log for more detail.") + + " See log for more detail." + ) } response } catch { @@ -145,7 +151,8 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { IO.delete(dest) throw new IOException( "Downloaded file size doesn't match expected Content Length for " + url - + ". Please retry.") + + ". Please retry." + ) } val lastModified = lastModifiedTimestamp(response) @@ -198,11 +205,12 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { object GigahorseUrlHandler { // This is requires to access the constructor of URLInfo. - private[sbt] class SbtUrlInfo(available: Boolean, - contentLength: Long, - lastModified: Long, - bodyCharset: String) - extends URLInfo(available, contentLength, lastModified, bodyCharset) { + private[sbt] class SbtUrlInfo( + available: Boolean, + contentLength: Long, + lastModified: Long, + bodyCharset: String + ) extends URLInfo(available, contentLength, lastModified, bodyCharset) { def this(available: Boolean, contentLength: Long, lastModified: Long) = { this(available, contentLength, lastModified, null) } @@ -220,7 +228,8 @@ object GigahorseUrlHandler { Message.warn("Your proxy requires authentication.") } else if (status == 401) { Message.warn( - "CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password.") + "CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password." + ) } else if (String.valueOf(status).startsWith("4")) { Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) } else if (String.valueOf(status).startsWith("5")) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index d5107f2aa..cac26e395 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -14,9 +14,11 @@ import org.apache.ivy.util.filter.Filter import scala.concurrent.duration.Duration import scala.concurrent.{ Await, ExecutionContext, Future } -private[ivyint] case class DownloadResult(dep: IvyNode, - report: DownloadReport, - totalSizeDownloaded: Long) +private[ivyint] case class DownloadResult( + dep: IvyNode, + report: DownloadReport, + totalSizeDownloaded: Long +) object ParallelResolveEngine { private lazy val resolveExecutionContext: ExecutionContext = { @@ -28,14 +30,17 @@ object ParallelResolveEngine { } /** Define an ivy [[ResolveEngine]] that resolves dependencies in parallel. */ -private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, - eventManager: EventManager, - sortEngine: SortEngine) - extends ResolveEngine(settings, eventManager, sortEngine) { +private[sbt] class ParallelResolveEngine( + settings: ResolveEngineSettings, + eventManager: EventManager, + sortEngine: SortEngine +) extends ResolveEngine(settings, eventManager, sortEngine) { - override def downloadArtifacts(report: ResolveReport, - artifactFilter: Filter, - options: DownloadOptions): Unit = { + override def downloadArtifacts( + report: ResolveReport, + artifactFilter: Filter, + options: DownloadOptions + ): Unit = { import scala.collection.JavaConverters._ val start = System.currentTimeMillis report.getArtifacts match { @@ -82,9 +87,11 @@ private[sbt] class ParallelResolveEngine(settings: ResolveEngineSettings, * * Return the report and the total downloaded size. */ - private def downloadNodeArtifacts(dependency: IvyNode, - artifactFilter: Filter, - options: DownloadOptions): DownloadResult = { + private def downloadNodeArtifacts( + dependency: IvyNode, + artifactFilter: Filter, + options: DownloadOptions + ): DownloadResult = { val resolver = dependency.getModuleRevision.getArtifactResolver val selectedArtifacts = dependency.getSelectedArtifacts(artifactFilter) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 517c26682..2314838ef 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -94,9 +94,11 @@ private[sbt] case class SbtChainResolver( /** Implements the custom sbt chain resolution with support for snapshots and caching. */ private object CustomSbtResolution { - def getCached(dd: DependencyDescriptor, - data: ResolveData, - resolved0: Option[ResolvedModuleRevision]): Option[ResolvedModuleRevision] = { + def getCached( + dd: DependencyDescriptor, + data: ResolveData, + resolved0: Option[ResolvedModuleRevision] + ): Option[ResolvedModuleRevision] = { resolved0.orElse { val resolverName = getName Message.verbose(s"$resolverName: Checking cache for: $dd") @@ -144,7 +146,8 @@ private[sbt] case class SbtChainResolver( var currentlyResolved = resolved0 def performResolution( - resolver: DependencyResolver): Option[(ResolvedModuleRevision, DependencyResolver)] = { + resolver: DependencyResolver + ): Option[(ResolvedModuleRevision, DependencyResolver)] = { // Resolve all resolvers when the module is changing val previouslyResolved = currentlyResolved if (useLatest) data.setCurrentResolvedModuleRevision(null) @@ -152,8 +155,9 @@ private[sbt] case class SbtChainResolver( currentlyResolved = Option(resolver.getDependency(descriptor, data)) if (currentlyResolved eq previouslyResolved) None else if (useLatest) { - currentlyResolved.map(x => - (reparseModuleDescriptor(descriptor, data, resolver, x), resolver)) + currentlyResolved.map( + x => (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) + ) } else currentlyResolved.map(x => (forcedRevision(x), resolver)) } @@ -179,9 +183,11 @@ private[sbt] case class SbtChainResolver( } private final val prefix = "Undefined resolution order" - def resolveLatest(foundRevisions: Seq[(ResolvedModuleRevision, DependencyResolver)], - descriptor: DependencyDescriptor, - data: ResolveData): Option[ResolvedModuleRevision] = { + def resolveLatest( + foundRevisions: Seq[(ResolvedModuleRevision, DependencyResolver)], + descriptor: DependencyDescriptor, + data: ResolveData + ): Option[ResolvedModuleRevision] = { val sortedRevisions = foundRevisions.sortBy { case (rmr, resolver) => @@ -220,13 +226,15 @@ private[sbt] case class SbtChainResolver( if (resolvedModule.getId.getRevision.contains("SNAPSHOT")) { Message.warn( - "Resolving a snapshot version. It's going to be slow unless you use `updateOptions := updateOptions.value.withLatestSnapshots(false)` options.") + "Resolving a snapshot version. It's going to be slow unless you use `updateOptions := updateOptions.value.withLatestSnapshots(false)` options." + ) val resolvers = sortedRevisions.map(_._2.getName) sortedRevisions.foreach(h => { val (module, resolver) = h Message.info( s"Out of ${sortedRevisions.size} candidates we found for ${module.getId} in ${resolvers - .mkString(" and ")}, we are choosing ${resolver}.") + .mkString(" and ")}, we are choosing ${resolver}." + ) }) } else { Message.warn(s"Choosing $resolver for ${resolvedModule.getId}") diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index 1b93bacf7..bc72f4bc2 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -14,10 +14,12 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) new Module(moduleSetting) } - override def update(module: ModuleDescriptor, - configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, - log: Logger): Either[UnresolvedWarning, UpdateReport] = + override def update( + module: ModuleDescriptor, + configuration: UpdateConfiguration, + uwconfig: UnresolvedWarningConfiguration, + log: Logger + ): Either[UnresolvedWarning, UpdateReport] = IvyActions.updateEither(toModule(module), configuration, uwconfig, log) private[sbt] def toModule(module: ModuleDescriptor): Module = diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index 643ef7c32..dc15ba7a9 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -14,14 +14,18 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface new Module(moduleSetting) } - override def makePomFile(module: ModuleDescriptor, - configuration: MakePomConfiguration, - log: Logger): File = + override def makePomFile( + module: ModuleDescriptor, + configuration: MakePomConfiguration, + log: Logger + ): File = IvyActions.makePomFile(toModule(module), configuration, log) - override def publish(module: ModuleDescriptor, - configuration: PublishConfiguration, - log: Logger): Unit = + override def publish( + module: ModuleDescriptor, + configuration: PublishConfiguration, + log: Logger + ): Unit = IvyActions.publish(toModule(module), configuration, log) private[sbt] def toModule(module: ModuleDescriptor): Module = diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala index db0e83789..fc71dee26 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala @@ -27,7 +27,7 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re uo.cachedResolution, uo.gigahorse, uo.moduleResolvers - ), + ), (xs: (String, Boolean, Boolean, Boolean, Boolean, Map[ModuleID, Resolver])) => new UpdateOptions( levels(xs._1), @@ -37,7 +37,7 @@ trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with Re xs._5, PartialFunction.empty, xs._6 - ) + ) ) private val levels: Map[String, CircularDependencyLevel] = Map( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala index f53454c5f..53ad0ba09 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseCachedResolutionSpec.scala @@ -4,9 +4,11 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ trait BaseCachedResolutionSpec extends BaseIvySpecification { - override def module(moduleId: ModuleID, - deps: Vector[ModuleID], - scalaFullVersion: Option[String]): ModuleDescriptor = { + override def module( + moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String] + ): ModuleDescriptor = { val uo: UpdateOptions = UpdateOptions() .withCachedResolution(true) module(moduleId, deps, scalaFullVersion, uo, true) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index f6add3e61..304412069 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -24,17 +24,21 @@ trait BaseIvySpecification extends AbstractEngineSpec { def configurations = Vector(Compile, Test, Runtime) - def module(moduleId: ModuleID, - deps: Vector[ModuleID], - scalaFullVersion: Option[String]): ModuleDescriptor = { + def module( + moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String] + ): ModuleDescriptor = { module(moduleId, deps, scalaFullVersion, UpdateOptions(), true) } - def module(moduleId: ModuleID, - deps: Vector[ModuleID], - scalaFullVersion: Option[String], - uo: UpdateOptions = UpdateOptions(), - overrideScalaVersion: Boolean = true): IvySbt#Module = { + def module( + moduleId: ModuleID, + deps: Vector[ModuleID], + scalaFullVersion: Option[String], + uo: UpdateOptions = UpdateOptions(), + overrideScalaVersion: Boolean = true + ): IvySbt#Module = { val scalaModuleInfo = scalaFullVersion map { fv => ScalaModuleInfo( scalaFullVersion = fv, @@ -71,8 +75,10 @@ trait BaseIvySpecification extends AbstractEngineSpec { .withUpdateOptions(uo) } - def makeUpdateConfiguration(offline: Boolean, - metadataDirectory: Option[File]): UpdateConfiguration = { + def makeUpdateConfiguration( + offline: Boolean, + metadataDirectory: Option[File] + ): UpdateConfiguration = { val retrieveConfig = RetrieveConfiguration() .withRetrieveDirectory(currentManaged) .withOutputPattern(Resolver.defaultRetrievePattern) @@ -108,8 +114,10 @@ trait BaseIvySpecification extends AbstractEngineSpec { def ivyUpdate(module: ModuleDescriptor): UpdateReport = update(module) - def mkPublishConfiguration(resolver: Resolver, - artifacts: Map[Artifact, File]): PublishConfiguration = { + def mkPublishConfiguration( + resolver: Resolver, + artifacts: Map[Artifact, File] + ): PublishConfiguration = { PublishConfiguration() .withResolverName(resolver.name) .withArtifacts(artifacts.toVector) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index 4cc452755..2a9f3f675 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -67,7 +67,9 @@ class ComponentManagerTest extends UnitSpec { withManagerHome(ivyHome) { usingManager => checksum(usingManager.file(TestID)(Fail)) shouldBe hash } - } finally { definingManager.clearCache(TestID) } + } finally { + definingManager.clearCache(TestID) + } } } } @@ -82,7 +84,8 @@ class ComponentManagerTest extends UnitSpec { private def createFile[T](manager: ComponentManager, id: String, name: String)(f: File => T): T = createFiles(manager, id, name)(files => f(files.toList.head)) private def createFiles[T](manager: ComponentManager, id: String, names: String*)( - f: Seq[File] => T): T = + f: Seq[File] => T + ): T = withTemporaryDirectory { dir => val files = names.map(name => new File(dir, name)) files.foreach(writeRandomContent) @@ -113,7 +116,8 @@ class ComponentManagerTest extends UnitSpec { val location = componentLocation(id) if (location.exists) throw new RuntimeException( - s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}") + s"Cannot redefine component. ID: $id, files: ${files.mkString(",")}" + ) else { IO.copy(files.map { f => f -> new java.io.File(location, f.getName) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index f5c6379b8..586b04531 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -51,14 +51,18 @@ class DMSerializationSpec extends UnitSpec { } lazy val updateReportExample = - UpdateReport(new File("./foo"), - Vector(configurationReportExample), - UpdateStats(0, 0, 0, false), - Map(new File("./foo") -> 0)) + UpdateReport( + new File("./foo"), + Vector(configurationReportExample), + UpdateStats(0, 0, 0, false), + Map(new File("./foo") -> 0) + ) lazy val configurationReportExample = - ConfigurationReport(ConfigRef("compile"), - Vector(moduleReportExample), - Vector(organizationArtifactReportExample)) + ConfigurationReport( + ConfigRef("compile"), + Vector(moduleReportExample), + Vector(organizationArtifactReportExample) + ) lazy val organizationArtifactReportExample = OrganizationArtifactReport("org", "name", Vector(moduleReportExample)) lazy val moduleReportExample = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 106a0e87f..3a90fc05a 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -62,7 +62,8 @@ class EvictionWarningSpec extends BaseIvySpecification { val m2 = "org.scala-sbt" % "util-logging_2.12" % "1.1.0" assert( EvictionWarningOptions - .defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.12.4"))))) + .defaultGuess((m1, Option(m2), Option(dummyScalaModuleInfo("2.12.4")))) + ) } def akkaActor214 = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index c6c18c6cf..c6620bee7 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -49,7 +49,9 @@ class FrozenModeSpec extends BaseIvySpecification { val toExplicitResolve = module(defaultModuleId, explicitStoml, None, normalOptions) val frozenResolution = update(toExplicitResolve, frozenConf) assert(frozenResolution.isRight) - assert(frozenResolution.right.get.allModules.size == numberResolved, - s"The number of explicit modules in frozen mode should be equal than $numberResolved") + assert( + frozenResolution.right.get.allModules.size == numberResolved, + s"The number of explicit modules in frozen mode should be equal than $numberResolved" + ) } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 2117e8c89..468b9fef6 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -61,19 +61,23 @@ class IvyRepoSpec extends BaseIvySpecification { val clMod = { val externalModules = Vector(dep) // Note: need to extract ourModuleID so we can plug it in here, can't fish it back out of the IvySbt#Module (`m`) - GetClassifiersModule(ourModuleID, - scalaModuleInfo, - externalModules, - Vector(Configurations.Compile), - attemptedClassifiers) + GetClassifiersModule( + ourModuleID, + scalaModuleInfo, + externalModules, + Vector(Configurations.Compile), + attemptedClassifiers + ) } val artifactFilter = getArtifactTypeFilter(c.artifactFilter) - val gcm = GetClassifiersConfiguration(clMod, - Vector.empty, - c.withArtifactFilter(artifactFilter.invert), - srcTypes, - docTypes) + val gcm = GetClassifiersConfiguration( + clMod, + Vector.empty, + c.withArtifactFilter(artifactFilter.invert), + srcTypes, + docTypes + ) val report2 = lmEngine() diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index cbc5765c0..3dcfff33f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -25,51 +25,81 @@ class ScalaOverrideTest extends UnitSpec { } """OverrideScalaMediator - """ should "Override compiler version" in check(Organization, "2.11.8")(Organization, - CompilerID, - "2.11.9") - it should "Override library version" in check(Organization, "2.11.8")(Organization, - LibraryID, - "2.11.8") - it should "Override reflect version" in check(Organization, "2.11.8")(Organization, - ReflectID, - "2.11.7") - it should "Override actors version" in check(Organization, "2.11.8")(Organization, - ActorsID, - "2.11.6") - it should "Override scalap version" in check(Organization, "2.11.8")(Organization, - ScalapID, - "2.11.5") + """ should "Override compiler version" in check(Organization, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + it should "Override library version" in check(Organization, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + it should "Override reflect version" in check(Organization, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + it should "Override actors version" in check(Organization, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + it should "Override scalap version" in check(Organization, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) - it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")(Organization, - CompilerID, - "2.11.9") - it should "Override default library organization" in check(OtherOrgID, "2.11.8")(Organization, - LibraryID, - "2.11.8") - it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")(Organization, - ReflectID, - "2.11.7") - it should "Override default actors organization" in check(OtherOrgID, "2.11.8")(Organization, - ActorsID, - "2.11.6") - it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")(Organization, - ScalapID, - "2.11.5") + it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + it should "Override default library organization" in check(OtherOrgID, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + it should "Override default actors organization" in check(OtherOrgID, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) - it should "Override custom compiler organization" in check(Organization, "2.11.8")(OtherOrgID, - CompilerID, - "2.11.9") - it should "Override custom library organization" in check(Organization, "2.11.8")(OtherOrgID, - LibraryID, - "2.11.8") - it should "Override custom reflect organization" in check(Organization, "2.11.8")(OtherOrgID, - ReflectID, - "2.11.7") - it should "Override custom actors organization" in check(Organization, "2.11.8")(OtherOrgID, - ActorsID, - "2.11.6") - it should "Override custom scalap organization" in check(Organization, "2.11.8")(OtherOrgID, - ScalapID, - "2.11.5") + it should "Override custom compiler organization" in check(Organization, "2.11.8")( + OtherOrgID, + CompilerID, + "2.11.9" + ) + it should "Override custom library organization" in check(Organization, "2.11.8")( + OtherOrgID, + LibraryID, + "2.11.8" + ) + it should "Override custom reflect organization" in check(Organization, "2.11.8")( + OtherOrgID, + ReflectID, + "2.11.7" + ) + it should "Override custom actors organization" in check(Organization, "2.11.8")( + OtherOrgID, + ActorsID, + "2.11.6" + ) + it should "Override custom scalap organization" in check(Organization, "2.11.8")( + OtherOrgID, + ScalapID, + "2.11.5" + ) } From 4e46acde12ba3ffddf8b274455fca0f0f9c58d32 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Thu, 9 May 2019 11:41:15 +0200 Subject: [PATCH 0831/1030] Add toString for DirectCredentials To make 'show credentials' more useful --- .../main/scala/sbt/librarymanagement/ivy/Credentials.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 26ccc57f7..7ebc4521d 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -76,11 +76,13 @@ object Credentials { sealed trait Credentials final class FileCredentials(val path: File) extends Credentials { - override def toString = "FileCredentials('" + path + "')" + override def toString = s"""FileCredentials("$path")""" } final class DirectCredentials( val realm: String, val host: String, val userName: String, val passwd: String -) extends Credentials +) extends Credentials { + override def toString = s"""DirectCredentials("$realm", "$host", "$userName", ****)""" +} From 511dafb0e8831b94b79752fbb21c59198f95bcf9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 May 2019 17:48:00 -0400 Subject: [PATCH 0832/1030] sbt 1.3.0-M3 --- .travis.yml | 4 +++- project/build.properties | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 714aaabaf..bf13ac1a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,9 @@ install: - unset _JAVA_OPTIONS - java -Xmx32m -version # detect sbt version from project/build.properties - - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" + # - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" + # use 1.2.8 until 1.3.0 installer is out + - export TRAVIS_SBT=1.2.8 - sdk install sbt $TRAVIS_SBT # override Travis CI's SBT_OPTS - unset SBT_OPTS diff --git a/project/build.properties b/project/build.properties index c0bab0494..c59667ce9 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.2.8 +sbt.version=1.3.0-M3 From 2353be9eb688a3a0beee9e6f08852746695a23d9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 9 May 2019 23:54:01 -0400 Subject: [PATCH 0833/1030] fixpreloaded.sh Ref https://github.com/sbt/sbt/issues/4661 --- .travis.yml | 1 + bin/fixpreloaded.sh | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100755 bin/fixpreloaded.sh diff --git a/.travis.yml b/.travis.yml index bf13ac1a5..ea6789364 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,6 +30,7 @@ before_install: install: - sdk install java $TRAVIS_JDK + - bin/fixpreloaded.sh - unset _JAVA_OPTIONS - java -Xmx32m -version # detect sbt version from project/build.properties diff --git a/bin/fixpreloaded.sh b/bin/fixpreloaded.sh new file mode 100755 index 000000000..ac57c3596 --- /dev/null +++ b/bin/fixpreloaded.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.4 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.5 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/org.scala-lang.modules/scala-xml_2.12/1.0.6 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/com.typesafe/config/1.2.0 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/com.typesafe/ssl-config-core_2.12/0.2.2 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/com.google.protobuf/protobuf-java/3.3.1 +rm -rf $HOME/.sdkman/candidates/sbt/current/lib/local-preloaded/org.scala-lang/scala-compiler/2.12.6 + +rm -rf $HOME/.sbt/preloaded/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.4 +rm -rf $HOME/.sbt/preloaded/org.scala-lang.modules/scala-parser-combinators_2.12/1.0.5 +rm -rf $HOME/.sbt/preloaded/org.scala-lang.modules/scala-xml_2.12/1.0.6 +rm -rf $HOME/.sbt/preloaded/com.typesafe/config/1.2.0 +rm -rf $HOME/.sbt/preloaded/com.typesafe/ssl-config-core_2.12/0.2.2 +rm -rf $HOME/.sbt/preloaded/com.google.protobuf/protobuf-java/3.3.1 +rm -rf $HOME/.sbt/preloaded/org.scala-lang/scala-compiler/2.12.6 From 25ff7d2dd5d33afbedaf62d6f92a75dab4b8fa6c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 May 2019 00:11:39 -0400 Subject: [PATCH 0834/1030] ClassLoaderLayeringStrategy.Flat --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index 4b71318ee..b5f6d6d4c 100644 --- a/build.sbt +++ b/build.sbt @@ -7,6 +7,8 @@ val _ = { sys.props += ("line.separator" -> "\n") } +ThisBuild / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat + def commonSettings: Seq[Setting[_]] = Def.settings( scalaVersion := scala212, // publishArtifact in packageDoc := false, From acc1fd6b964eb6a43454c75672ee945861e6435e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 11 May 2019 19:42:44 -0400 Subject: [PATCH 0835/1030] Remove lm-coursier out of this repo Ref https://github.com/coursier/sbt-coursier/pull/7 --- .../coursier/CoursierConfiguration.scala | 57 --- .../CoursierConfigurationFormats.scala | 37 -- coursier/src/main/contraband/lm-coursier.json | 49 --- .../src/main/scala/coursier/FromSbt.scala | 283 ------------- .../src/main/scala/coursier/SbtBootJars.scala | 18 - coursier/src/main/scala/coursier/ToSbt.scala | 275 ------------- .../CoursierDependencyResolution.scala | 382 ------------------ .../CoursierLibraryManagementCodec.scala | 12 - .../coursier/Resolvers.scala | 51 --- .../coursier/BaseCoursierSpecification.scala | 40 -- .../coursier/ResolutionSpec.scala | 144 ------- .../librarymanagement/coursier/UnitSpec.scala | 5 - 12 files changed, 1353 deletions(-) delete mode 100644 coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala delete mode 100644 coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala delete mode 100644 coursier/src/main/contraband/lm-coursier.json delete mode 100644 coursier/src/main/scala/coursier/FromSbt.scala delete mode 100644 coursier/src/main/scala/coursier/SbtBootJars.scala delete mode 100644 coursier/src/main/scala/coursier/ToSbt.scala delete mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala delete mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala delete mode 100644 coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala delete mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala delete mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala delete mode 100644 coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala deleted file mode 100644 index 1864c4440..000000000 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfiguration.scala +++ /dev/null @@ -1,57 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement.coursier -final class CoursierConfiguration private ( - val log: Option[xsbti.Logger], - val resolvers: Vector[sbt.librarymanagement.Resolver], - val otherResolvers: Vector[sbt.librarymanagement.Resolver], - val reorderResolvers: Boolean, - val parallelDownloads: Int, - val maxIterations: Int) extends Serializable { - - private def this() = this(None, sbt.librarymanagement.Resolver.defaults, Vector.empty, true, 6, 100) - - override def equals(o: Any): Boolean = o match { - case x: CoursierConfiguration => (this.log == x.log) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.reorderResolvers == x.reorderResolvers) && (this.parallelDownloads == x.parallelDownloads) && (this.maxIterations == x.maxIterations) - case _ => false - } - override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.coursier.CoursierConfiguration".##) + log.##) + resolvers.##) + otherResolvers.##) + reorderResolvers.##) + parallelDownloads.##) + maxIterations.##) - } - override def toString: String = { - "CoursierConfiguration(" + log + ", " + resolvers + ", " + otherResolvers + ", " + reorderResolvers + ", " + parallelDownloads + ", " + maxIterations + ")" - } - private[this] def copy(log: Option[xsbti.Logger] = log, resolvers: Vector[sbt.librarymanagement.Resolver] = resolvers, otherResolvers: Vector[sbt.librarymanagement.Resolver] = otherResolvers, reorderResolvers: Boolean = reorderResolvers, parallelDownloads: Int = parallelDownloads, maxIterations: Int = maxIterations): CoursierConfiguration = { - new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) - } - def withLog(log: Option[xsbti.Logger]): CoursierConfiguration = { - copy(log = log) - } - def withLog(log: xsbti.Logger): CoursierConfiguration = { - copy(log = Option(log)) - } - def withResolvers(resolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { - copy(resolvers = resolvers) - } - def withOtherResolvers(otherResolvers: Vector[sbt.librarymanagement.Resolver]): CoursierConfiguration = { - copy(otherResolvers = otherResolvers) - } - def withReorderResolvers(reorderResolvers: Boolean): CoursierConfiguration = { - copy(reorderResolvers = reorderResolvers) - } - def withParallelDownloads(parallelDownloads: Int): CoursierConfiguration = { - copy(parallelDownloads = parallelDownloads) - } - def withMaxIterations(maxIterations: Int): CoursierConfiguration = { - copy(maxIterations = maxIterations) - } -} -object CoursierConfiguration { - - def apply(): CoursierConfiguration = new CoursierConfiguration() - def apply(log: Option[xsbti.Logger], resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) - def apply(log: xsbti.Logger, resolvers: Vector[sbt.librarymanagement.Resolver], otherResolvers: Vector[sbt.librarymanagement.Resolver], reorderResolvers: Boolean, parallelDownloads: Int, maxIterations: Int): CoursierConfiguration = new CoursierConfiguration(Option(log), resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) -} diff --git a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala b/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala deleted file mode 100644 index ff8713f87..000000000 --- a/coursier/src/main/contraband-scala/sbt/librarymanagement/coursier/CoursierConfigurationFormats.scala +++ /dev/null @@ -1,37 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement.coursier -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait CoursierConfigurationFormats { self: sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => -implicit lazy val CoursierConfigurationFormat: JsonFormat[sbt.librarymanagement.coursier.CoursierConfiguration] = new JsonFormat[sbt.librarymanagement.coursier.CoursierConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.coursier.CoursierConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - val log = unbuilder.readField[Option[xsbti.Logger]]("log") - val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") - val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") - val reorderResolvers = unbuilder.readField[Boolean]("reorderResolvers") - val parallelDownloads = unbuilder.readField[Int]("parallelDownloads") - val maxIterations = unbuilder.readField[Int]("maxIterations") - unbuilder.endObject() - sbt.librarymanagement.coursier.CoursierConfiguration(log, resolvers, otherResolvers, reorderResolvers, parallelDownloads, maxIterations) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.coursier.CoursierConfiguration, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("log", obj.log) - builder.addField("resolvers", obj.resolvers) - builder.addField("otherResolvers", obj.otherResolvers) - builder.addField("reorderResolvers", obj.reorderResolvers) - builder.addField("parallelDownloads", obj.parallelDownloads) - builder.addField("maxIterations", obj.maxIterations) - builder.endObject() - } -} -} diff --git a/coursier/src/main/contraband/lm-coursier.json b/coursier/src/main/contraband/lm-coursier.json deleted file mode 100644 index 927175607..000000000 --- a/coursier/src/main/contraband/lm-coursier.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "codecNamespace": "sbt.librarymanagement.coursier", - "types": [ - { - "name": "CoursierConfiguration", - "namespace": "sbt.librarymanagement.coursier", - "target": "Scala", - "type": "record", - "fields": [ - { - "name": "log", - "type": "xsbti.Logger?", - "default": "None", - "since": "0.0.1" - }, - { - "name": "resolvers", - "type": "sbt.librarymanagement.Resolver*", - "default": "sbt.librarymanagement.Resolver.defaults", - "since": "0.0.1" - }, - { - "name": "otherResolvers", - "type": "sbt.librarymanagement.Resolver*", - "default": "Vector.empty", - "since": "0.0.1" - }, - { - "name": "reorderResolvers", - "type": "Boolean", - "default": "true", - "since": "0.0.1" - }, - { - "name": "parallelDownloads", - "type": "Int", - "default": "6", - "since": "0.0.1" - }, - { - "name": "maxIterations", - "type": "Int", - "default": "100", - "since": "0.0.1" - } - ] - } - ] -} diff --git a/coursier/src/main/scala/coursier/FromSbt.scala b/coursier/src/main/scala/coursier/FromSbt.scala deleted file mode 100644 index 6539e1d97..000000000 --- a/coursier/src/main/scala/coursier/FromSbt.scala +++ /dev/null @@ -1,283 +0,0 @@ -package coursier - -import coursier.ivy.IvyRepository -import coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } -import java.net.{ MalformedURLException, URL } - -import coursier.core.Authentication -import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties -import sbt.librarymanagement._ -import sbt.librarymanagement.Resolver -import sbt.util.Logger - -object FromSbt { - - def sbtModuleIdName( - moduleId: ModuleID, - scalaVersion: => String, - scalaBinaryVersion: => String - ): String = - sbtCrossVersionName(moduleId.name, moduleId.crossVersion, scalaVersion, scalaBinaryVersion) - - def sbtCrossVersionName( - name: String, - crossVersion: CrossVersion, - scalaVersion: => String, - scalaBinaryVersion: => String - ): String = - CrossVersion(crossVersion, scalaVersion, scalaBinaryVersion) - .fold(name)(_(name)) - - def attributes(attr: Map[String, String]): Map[String, String] = - attr - .map { - case (k, v) => - k.stripPrefix("e:") -> v - } - .filter { - case (k, _) => - !k.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX) - } - - def moduleVersion( - module: ModuleID, - scalaVersion: String, - scalaBinaryVersion: String - ): (Module, String) = { - - val fullName = sbtModuleIdName(module, scalaVersion, scalaBinaryVersion) - - val module0 = - Module(module.organization, fullName, FromSbt.attributes(module.extraDependencyAttributes)) - val version = module.revision - - (module0, version) - } - - def dependencies( - module: ModuleID, - scalaVersion: String, - scalaBinaryVersion: String - ): Seq[(String, Dependency)] = { - - // TODO Warn about unsupported properties in `module` - - val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) - - val dep = Dependency( - module0, - version, - exclusions = module.exclusions.map { rule => - // FIXME Other `rule` fields are ignored here - (rule.organization, rule.name) - }.toSet, - transitive = module.isTransitive - ) - - val mapping = module.configurations.getOrElse("compile") - val allMappings = ivyXmlMappings(mapping) - - val attributes = - if (module.explicitArtifacts.isEmpty) - Seq(Attributes("", "")) - else - module.explicitArtifacts.map { a => - Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse("")) - } - - for { - (from, to) <- allMappings - attr <- attributes - } yield from -> dep.copy(configuration = to, attributes = attr) - } - - def fallbackDependencies( - allDependencies: Seq[ModuleID], - scalaVersion: String, - scalaBinaryVersion: String - ): Seq[(Module, String, URL, Boolean)] = - for { - module <- allDependencies - artifact <- module.explicitArtifacts - url <- artifact.url.toSeq - } yield { - val (module0, version) = moduleVersion(module, scalaVersion, scalaBinaryVersion) - (module0, version, url, module.isChanging) - } - - def sbtClassifiersProject( - cm: GetClassifiersModule, - scalaVersion: String, - scalaBinaryVersion: String - ) = { - - val p = FromSbt.project( - cm.id, - cm.dependencies, - cm.configurations.map(cfg => cfg.name -> cfg.extendsConfigs.map(_.name)).toMap, - scalaVersion, - scalaBinaryVersion - ) - - // for w/e reasons, the dependencies sometimes don't land in the right config above - // this is a loose attempt at fixing that - cm.configurations match { - case Seq(cfg) => - p.copy( - dependencies = p.dependencies.map { - case (_, d) => (cfg.name, d) - } - ) - case _ => - p - } - } - - def project( - projectID: ModuleID, - allDependencies: Seq[ModuleID], - ivyConfigurations: Map[String, Seq[String]], - scalaVersion: String, - scalaBinaryVersion: String - ): Project = { - - val deps = allDependencies.flatMap(dependencies(_, scalaVersion, scalaBinaryVersion)) - - Project( - Module( - projectID.organization, - sbtModuleIdName(projectID, scalaVersion, scalaBinaryVersion), - FromSbt.attributes(projectID.extraDependencyAttributes) - ), - projectID.revision, - deps, - ivyConfigurations, - None, - Nil, - Nil, - Nil, - None, - None, - None, - None, - Nil, - Info.empty - ) - } - - private def mavenCompatibleBaseOpt(patterns: Patterns): Option[String] = - if (patterns.isMavenCompatible) { - val baseIvyPattern = patterns.ivyPatterns.head.takeWhile(c => c != '[' && c != '(') - val baseArtifactPattern = patterns.ivyPatterns.head.takeWhile(c => c != '[' && c != '(') - - if (baseIvyPattern == baseArtifactPattern) - Some(baseIvyPattern) - else - None - } else - None - - private def mavenRepositoryOpt( - root: String, - log: Logger, - authentication: Option[Authentication] - ): Option[MavenRepository] = - try { - Cache.url(root) // ensure root is a URL whose protocol can be handled here - val root0 = if (root.endsWith("/")) root else root + "/" - Some( - MavenRepository( - root0, - authentication = authentication - ) - ) - } catch { - case e: MalformedURLException => - log.warn( - "Error parsing Maven repository base " + - root + - Option(e.getMessage).fold("")(" (" + _ + ")") + - ", ignoring it" - ) - - None - } - - def repository( - resolver: Resolver, - ivyProperties: Map[String, String], - log: Logger, - authentication: Option[Authentication] - ): Option[Repository] = - resolver match { - case r: sbt.librarymanagement.MavenRepository => - mavenRepositoryOpt(r.root, log, authentication) - - case r: FileRepository - if r.patterns.ivyPatterns.lengthCompare(1) == 0 && - r.patterns.artifactPatterns.lengthCompare(1) == 0 => - val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns) - - mavenCompatibleBaseOpt0 match { - case None => - val repo = IvyRepository.parse( - "file://" + r.patterns.artifactPatterns.head, - metadataPatternOpt = Some("file://" + r.patterns.ivyPatterns.head), - changing = Some(true), - properties = ivyProperties, - dropInfoAttributes = true, - authentication = authentication - ) match { - case Left(err) => - sys.error( - s"Cannot parse Ivy patterns ${r.patterns.artifactPatterns.head} and ${r.patterns.ivyPatterns.head}: $err" - ) - case Right(repo) => - repo - } - - Some(repo) - - case Some(mavenCompatibleBase) => - mavenRepositoryOpt("file://" + mavenCompatibleBase, log, authentication) - } - - case r: URLRepository - if r.patterns.ivyPatterns.lengthCompare(1) == 0 && - r.patterns.artifactPatterns.lengthCompare(1) == 0 => - val mavenCompatibleBaseOpt0 = mavenCompatibleBaseOpt(r.patterns) - - mavenCompatibleBaseOpt0 match { - case None => - val repo = IvyRepository.parse( - r.patterns.artifactPatterns.head, - metadataPatternOpt = Some(r.patterns.ivyPatterns.head), - changing = None, - properties = ivyProperties, - dropInfoAttributes = true, - authentication = authentication - ) match { - case Left(err) => - sys.error( - s"Cannot parse Ivy patterns ${r.patterns.artifactPatterns.head} and ${r.patterns.ivyPatterns.head}: $err" - ) - case Right(repo) => - repo - } - - Some(repo) - - case Some(mavenCompatibleBase) => - mavenRepositoryOpt(mavenCompatibleBase, log, authentication) - } - - case raw: RawRepository - if raw.name == "inter-project" => // sbt.RawRepository.equals just compares names anyway - None - - case other => - log.warn(s"Unrecognized repository ${other.name}, ignoring it") - None - } - -} diff --git a/coursier/src/main/scala/coursier/SbtBootJars.scala b/coursier/src/main/scala/coursier/SbtBootJars.scala deleted file mode 100644 index 1d9df09cd..000000000 --- a/coursier/src/main/scala/coursier/SbtBootJars.scala +++ /dev/null @@ -1,18 +0,0 @@ -package coursier - -import java.io.File - -object SbtBootJars { - def apply( - scalaOrg: String, - scalaVersion: String, - jars: Seq[File] - ): Map[(Module, String), File] = - jars.collect { - case jar if jar.getName.endsWith(".jar") => - val name = jar.getName.stripSuffix(".jar") - val mod = Module(scalaOrg, name) - - (mod, scalaVersion) -> jar - }.toMap -} diff --git a/coursier/src/main/scala/coursier/ToSbt.scala b/coursier/src/main/scala/coursier/ToSbt.scala deleted file mode 100644 index 5af3bfc75..000000000 --- a/coursier/src/main/scala/coursier/ToSbt.scala +++ /dev/null @@ -1,275 +0,0 @@ -package coursier - -import java.io.File -import java.net.URL -import java.util.GregorianCalendar -import java.util.concurrent.ConcurrentHashMap - -import coursier.maven.MavenSource -import sbt.librarymanagement._ -import sbt.util.Logger - -object ToSbt { - - private def caching[K, V](f: K => V): K => V = { - - val cache = new ConcurrentHashMap[K, V] - - key => - val previousValueOpt = Option(cache.get(key)) - - previousValueOpt.getOrElse { - val value = f(key) - val concurrentValueOpt = Option(cache.putIfAbsent(key, value)) - concurrentValueOpt.getOrElse(value) - } - } - - val moduleId = caching[(Dependency, Map[String, String]), ModuleID] { - case (dependency, extraProperties) => - sbt.librarymanagement - .ModuleID( - dependency.module.organization, - dependency.module.name, - dependency.version - ) - .withConfigurations( - Some(dependency.configuration) - ) - .withExtraAttributes( - dependency.module.attributes ++ extraProperties - ) - .withExclusions( - dependency.exclusions.toVector - .map { - case (org, name) => - sbt.librarymanagement - .InclExclRule() - .withOrganization(org) - .withName(name) - } - ) - .withIsTransitive( - dependency.transitive - ) - } - - val artifact = caching[(Module, Map[String, String], Artifact), sbt.librarymanagement.Artifact] { - case (module, extraProperties, artifact) => - sbt.librarymanagement - .Artifact(module.name) - // FIXME Get these two from publications - .withType(artifact.attributes.`type`) - .withExtension(MavenSource.typeExtension(artifact.attributes.`type`)) - .withClassifier( - Some(artifact.attributes.classifier) - .filter(_.nonEmpty) - .orElse(MavenSource.typeDefaultClassifierOpt(artifact.attributes.`type`)) - ) - // .withConfigurations(Vector()) - .withUrl(Some(new URL(artifact.url))) - .withExtraAttributes(module.attributes ++ extraProperties) - } - - val moduleReport = - caching[(Dependency, Seq[(Dependency, Project)], Project, Seq[(Artifact, Option[File])]), - ModuleReport] { - case (dependency, dependees, project, artifacts) => - val sbtArtifacts = artifacts.collect { - case (artifact, Some(file)) => - (ToSbt.artifact((dependency.module, project.properties.toMap, artifact)), file) - } - val sbtMissingArtifacts = artifacts.collect { - case (artifact, None) => - ToSbt.artifact((dependency.module, project.properties.toMap, artifact)) - } - - val publicationDate = project.info.publication.map { dt => - new GregorianCalendar(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) - } - - val callers = dependees.map { - case (dependee, dependeeProj) => - Caller( - ToSbt.moduleId((dependee, dependeeProj.properties.toMap)), - dependeeProj.configurations.keys.toVector.map(ConfigRef(_)), - dependee.module.attributes ++ dependeeProj.properties, - // FIXME Set better values here - isForceDependency = false, - isChangingDependency = false, - isTransitiveDependency = false, - isDirectlyForceDependency = false - ) - } - - ModuleReport( - ToSbt.moduleId((dependency, project.properties.toMap)), - sbtArtifacts.toVector, - sbtMissingArtifacts.toVector - ) - // .withStatus(None) - .withPublicationDate(publicationDate) - // .withResolver(None) - // .withArtifactResolver(None) - // .withEvicted(false) - // .withEvictedData(None) - // .withEvictedReason(None) - // .withProblem(None) - .withHomepage(Some(project.info.homePage).filter(_.nonEmpty)) - .withExtraAttributes(dependency.module.attributes ++ project.properties) - // .withIsDefault(None) - // .withBranch(None) - .withConfigurations(project.configurations.keys.toVector.map(ConfigRef(_))) - .withLicenses(project.info.licenses.toVector) - .withCallers(callers.toVector) - } - - private def grouped[K, V](map: Seq[(K, V)]): Map[K, Seq[V]] = - map.groupBy { case (k, _) => k }.map { - case (k, l) => - k -> l.map { case (_, v) => v } - } - - def moduleReports( - res: Resolution, - classifiersOpt: Option[Seq[String]], - artifactFileOpt: (Module, String, Artifact) => Option[File], - log: Logger, - keepPomArtifact: Boolean = false, - includeSignatures: Boolean = false - ) = { - val depArtifacts1 = - classifiersOpt match { - case None => res.dependencyArtifacts(withOptional = true) - case Some(cl) => res.dependencyClassifiersArtifacts(cl) - } - - val depArtifacts0 = - if (keepPomArtifact) - depArtifacts1 - else - depArtifacts1.filter { - case (_, a) => a.attributes != Attributes("pom", "") - } - - val depArtifacts = - if (includeSignatures) { - - val notFound = depArtifacts0.filter(!_._2.extra.contains("sig")) - - if (notFound.isEmpty) - depArtifacts0.flatMap { - case (dep, a) => - Seq(dep -> a) ++ a.extra.get("sig").toSeq.map(dep -> _) - } else { - for ((_, a) <- notFound) - log.error(s"No signature found for ${a.url}") - sys.error(s"${notFound.length} signature(s) not found") - } - } else - depArtifacts0 - - val groupedDepArtifacts = grouped(depArtifacts) - - val versions = res.dependencies.toVector.map { dep => - dep.module -> dep.version - }.toMap - - def clean(dep: Dependency): Dependency = - dep.copy(configuration = "", exclusions = Set.empty, optional = false) - - val reverseDependencies = res.reverseDependencies.toVector - .map { - case (k, v) => - clean(k) -> v.map(clean) - } - .groupBy { case (k, _) => k } - .mapValues { v => - v.flatMap { - case (_, l) => l - } - } - .toVector - .toMap - - groupedDepArtifacts.map { - case (dep, artifacts) => - val (_, proj) = res.projectCache(dep.moduleVersion) - - // FIXME Likely flaky... - val dependees = reverseDependencies - .getOrElse(clean(dep.copy(version = "")), Vector.empty) - .map { dependee0 => - val version = versions(dependee0.module) - val dependee = dependee0.copy(version = version) - val (_, dependeeProj) = res.projectCache(dependee.moduleVersion) - (dependee, dependeeProj) - } - - ToSbt.moduleReport( - ( - dep, - dependees, - proj, - artifacts.map(a => a -> artifactFileOpt(proj.module, proj.version, a)) - )) - } - } - - def updateReport( - configDependencies: Map[String, Seq[Dependency]], - resolutions: Map[String, Resolution], - configs: Map[String, Set[String]], - classifiersOpt: Option[Seq[String]], - artifactFileOpt: (Module, String, Artifact) => Option[File], - log: Logger, - keepPomArtifact: Boolean = false, - includeSignatures: Boolean = false - ): UpdateReport = { - - val configReports = configs.map { - case (config, extends0) => - val configDeps = extends0.flatMap(configDependencies.getOrElse(_, Nil)) - val subRes = resolutions(config).subset(configDeps) - - val reports = ToSbt.moduleReports( - subRes, - classifiersOpt, - artifactFileOpt, - log, - keepPomArtifact = keepPomArtifact, - includeSignatures = includeSignatures - ) - - val reports0 = - if (subRes.rootDependencies.size == 1) { - // quick hack ensuring the module for the only root dependency - // appears first in the update report, see https://github.com/coursier/coursier/issues/650 - val dep = subRes.rootDependencies.head - val (_, proj) = subRes.projectCache(dep.moduleVersion) - val mod = ToSbt.moduleId((dep, proj.properties.toMap)) - val (main, other) = reports.partition { r => - r.module.organization == mod.organization && - r.module.name == mod.name && - r.module.crossVersion == mod.crossVersion - } - main.toVector ++ other.toVector - } else - reports.toVector - - ConfigurationReport( - ConfigRef(config), - reports0, - Vector() - ) - } - - UpdateReport( - File.createTempFile("fake-update-report", "json"), - configReports.toVector, - UpdateStats(-1L, -1L, -1L, cached = false), - Map.empty - ) - } - -} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala deleted file mode 100644 index 3734fbce8..000000000 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierDependencyResolution.scala +++ /dev/null @@ -1,382 +0,0 @@ -package sbt.librarymanagement.coursier - -import java.io.{ File, OutputStreamWriter } -import java.util.concurrent.Executors - -import scala.util.{ Failure, Success } -import scala.concurrent.ExecutionContext -import coursier.{ Artifact, Resolution, _ } -import coursier.util.{ Gather, Task } -import sbt.internal.librarymanagement.IvySbt -import sbt.librarymanagement.Configurations.{ CompilerPlugin, Component, ScalaTool } -import sbt.librarymanagement._ -import sbt.util.Logger -import sjsonnew.JsonFormat -import sjsonnew.support.murmurhash.Hasher - -case class CoursierModuleDescriptor( - directDependencies: Vector[ModuleID], - scalaModuleInfo: Option[ScalaModuleInfo], - moduleSettings: ModuleSettings, - configurations: Seq[String], - extraInputHash: Long -) extends ModuleDescriptor - -case class CoursierModuleSettings() extends ModuleSettings - -private[sbt] class CoursierDependencyResolution(coursierConfiguration: CoursierConfiguration) - extends DependencyResolutionInterface { - - // keep the pool alive while the class is loaded - private lazy val pool = - ExecutionContext.fromExecutor( - Executors.newFixedThreadPool(coursierConfiguration.parallelDownloads) - ) - - private[coursier] val reorderedResolvers = { - val resolvers0 = - coursierConfiguration.resolvers ++ coursierConfiguration.otherResolvers - - if (coursierConfiguration.reorderResolvers) { - Resolvers.reorder(resolvers0) - } else resolvers0 - } - - private[sbt] object AltLibraryManagementCodec extends CoursierLibraryManagementCodec { - type CoursierHL = ( - Vector[Resolver], - Vector[Resolver], - Boolean, - Int, - Int - ) - - def coursierToHL(c: CoursierConfiguration): CoursierHL = - ( - c.resolvers, - c.otherResolvers, - c.reorderResolvers, - c.parallelDownloads, - c.maxIterations - ) - // Redefine to use a subset of properties, that are serialisable - override implicit lazy val CoursierConfigurationFormat: JsonFormat[CoursierConfiguration] = { - def hlToCoursier(c: CoursierHL): CoursierConfiguration = { - val ( - resolvers, - otherResolvers, - reorderResolvers, - parallelDownloads, - maxIterations - ) = c - CoursierConfiguration() - .withResolvers(resolvers) - .withOtherResolvers(otherResolvers) - .withReorderResolvers(reorderResolvers) - .withParallelDownloads(parallelDownloads) - .withMaxIterations(maxIterations) - } - projectFormat[CoursierConfiguration, CoursierHL](coursierToHL, hlToCoursier) - } - } - - def extraInputHash: Long = { - import AltLibraryManagementCodec._ - Hasher.hash(coursierConfiguration) match { - case Success(keyHash) => keyHash.toLong - case Failure(_) => 0L - } - } - - /** - * Builds a ModuleDescriptor that describes a subproject with dependencies. - * - * @param moduleSetting It contains the information about the module including the dependencies. - * @return A `ModuleDescriptor` describing a subproject and its dependencies. - */ - override def moduleDescriptor( - moduleSetting: ModuleDescriptorConfiguration): CoursierModuleDescriptor = { - CoursierModuleDescriptor( - moduleSetting.dependencies, - moduleSetting.scalaModuleInfo, - CoursierModuleSettings(), - moduleSetting.configurations.map(_.name), - extraInputHash - ) - } - - val ivyHome = sys.props.getOrElse( - "ivy.home", - new File(sys.props("user.home")).toURI.getPath + ".ivy2" - ) - - val sbtIvyHome = sys.props.getOrElse( - "sbt.ivy.home", - ivyHome - ) - - val ivyProperties = Map( - "ivy.home" -> ivyHome, - "sbt.ivy.home" -> sbtIvyHome - ) ++ sys.props - - /** - * Resolves the given module's dependencies performing a retrieval. - * - * @param module The module to be resolved. - * @param configuration The update configuration. - * @param uwconfig The configuration to handle unresolved warnings. - * @param log The logger. - * @return The result, either an unresolved warning or an update report. Note that this - * update report will or will not be successful depending on the `missingOk` option. - */ - override def update(module: ModuleDescriptor, - configuration: UpdateConfiguration, - uwconfig: UnresolvedWarningConfiguration, - log: Logger): Either[UnresolvedWarning, UpdateReport] = { - - // not sure what DependencyResolutionInterface.moduleDescriptor is for, we're handled ivy stuff anyway... - val module0 = module match { - case c: CoursierModuleDescriptor => c - // This shouldn't happen at best of my understanding - case i: IvySbt#Module => - moduleDescriptor( - i.moduleSettings match { - case c: ModuleDescriptorConfiguration => c - case other => sys.error(s"unrecognized module settings: $other") - } - ) - case _ => - sys.error(s"unrecognized ModuleDescriptor type: $module") - } - - if (reorderedResolvers.isEmpty) { - log.error( - "Dependency resolution is configured with an empty list of resolvers. This is unlikely to work.") - } - - val dependencies = module.directDependencies.map(toCoursierDependency).flatten.toSet - val start = Resolution(dependencies.map(_._1)) - val authentication = None // TODO: get correct value - val ivyConfiguration = ivyProperties // TODO: is it enough? - - val repositories = - reorderedResolvers.flatMap(r => FromSbt.repository(r, ivyConfiguration, log, authentication)) ++ Seq( - Cache.ivy2Local, - Cache.ivy2Cache - ) - - implicit val ec = pool - - val coursierLogger = createLogger() - try { - val fetch = Fetch.from( - repositories, - Cache.fetch[Task](logger = Some(coursierLogger)) - ) - val resolution = start.process - .run(fetch, coursierConfiguration.maxIterations) - .unsafeRun() - - def updateReport() = { - val localArtifacts: Map[Artifact, Either[FileError, File]] = Gather[Task] - .gather( - resolution.artifacts.map { a => - Cache - .file[Task](a, logger = Some(coursierLogger)) - .run - .map((a, _)) - } - ) - .unsafeRun() - .toMap - - toUpdateReport(resolution, - (module0.configurations ++ dependencies.map(_._2)).distinct, - localArtifacts, - log) - } - - if (resolution.isDone && - resolution.errors.isEmpty && - resolution.conflicts.isEmpty) { - updateReport() - } else if (resolution.isDone && - (!resolution.errors.isEmpty && configuration.missingOk) - && resolution.conflicts.isEmpty) { - log.warn(s"""Failed to download artifacts: ${resolution.errors - .map(_._2) - .flatten - .mkString(", ")}""") - updateReport() - } else { - toSbtError(log, uwconfig, resolution) - } - } finally { - coursierLogger.stop() - } - } - - // utilities - private def createLogger() = { - val t = new TermDisplay(new OutputStreamWriter(System.out)) - t.init() - t - } - - private def toCoursierDependency(moduleID: ModuleID) = { - val attributes = - if (moduleID.explicitArtifacts.isEmpty) - Seq(Attributes("", "")) - else - moduleID.explicitArtifacts.map { a => - Attributes(`type` = a.`type`, classifier = a.classifier.getOrElse("")) - } - - val extraAttrs = FromSbt.attributes(moduleID.extraDependencyAttributes) - - val mapping = moduleID.configurations.getOrElse("compile") - - import _root_.coursier.ivy.IvyXml.{ mappings => ivyXmlMappings } - val allMappings = ivyXmlMappings(mapping) - - for { - (from, to) <- allMappings - attr <- attributes - } yield { - Dependency( - Module(moduleID.organization, moduleID.name, extraAttrs), - moduleID.revision, - configuration = to, - attributes = attr, - exclusions = moduleID.exclusions.map { rule => - (rule.organization, rule.name) - }.toSet, - transitive = moduleID.isTransitive - ) -> from - } - } - - private def toUpdateReport(resolution: Resolution, - configurations: Seq[String], - artifactFilesOrErrors0: Map[Artifact, Either[FileError, File]], - log: Logger): Either[UnresolvedWarning, UpdateReport] = { - - val artifactFiles = artifactFilesOrErrors0.collect { - case (artifact, Right(file)) => - artifact -> file - } - - val artifactErrors = artifactFilesOrErrors0.toVector - .collect { - case (a, Left(err)) if !a.isOptional || !err.notFound => - a -> err - } - - val erroredArtifacts = artifactFilesOrErrors0.collect { - case (a, Left(_)) => a - }.toSet - - val depsByConfig = { - val deps = resolution.dependencies.toVector - configurations - .map((_, deps)) - .toMap - } - - val configurations0 = extractConfigurationTree(configurations) - - val configResolutions = - (depsByConfig.keys ++ configurations0.keys).map(k => (k, resolution)).toMap - - val sbtBootJarOverrides = Map.empty[(Module, String), File] - val classifiers = None // TODO: get correct values - - if (artifactErrors.isEmpty) { - Right( - ToSbt.updateReport( - depsByConfig, - configResolutions, - configurations0, - classifiers, - artifactFileOpt( - sbtBootJarOverrides, - artifactFiles, - erroredArtifacts, - log, - _, - _, - _ - ), - log - )) - } else { - throw new RuntimeException(s"Could not save downloaded dependencies: $erroredArtifacts") - } - - } - - type ConfigurationName = String - type ConfigurationDependencyTree = Map[ConfigurationName, Set[ConfigurationName]] - - // Key is the name of the configuration (i.e. `compile`) and the values are the name itself plus the - // names of the configurations that this one depends on. - private def extractConfigurationTree(available: Seq[String]): ConfigurationDependencyTree = { - (Configurations.default ++ - Configurations.defaultInternal ++ - Seq(ScalaTool, CompilerPlugin, Component)) - .filter(c => available.contains(c.name)) - .map(c => (c.name, c.extendsConfigs.map(_.name) :+ c.name)) - .toMap - .mapValues(_.toSet) - } - - private def artifactFileOpt( - sbtBootJarOverrides: Map[(Module, String), File], - artifactFiles: Map[Artifact, File], - erroredArtifacts: Set[Artifact], - log: Logger, - module: Module, - version: String, - artifact: Artifact - ) = { - - val artifact0 = artifact - .copy(attributes = Attributes()) // temporary hack :-( - - // Under some conditions, SBT puts the scala JARs of its own classpath - // in the application classpath. Ensuring we return SBT's jars rather than - // JARs from the coursier cache, so that a same JAR doesn't land twice in the - // application classpath (once via SBT jars, once via coursier cache). - val fromBootJars = - if (artifact.classifier.isEmpty && artifact.`type` == "jar") - sbtBootJarOverrides.get((module, version)) - else - None - - val res = fromBootJars.orElse(artifactFiles.get(artifact0)) - if (res.isEmpty && !erroredArtifacts(artifact0)) - log.error(s"${artifact.url} not downloaded (should not happen)") - - res - } - - private def toSbtError(log: Logger, - uwconfig: UnresolvedWarningConfiguration, - resolution: Resolution) = { - val failedResolution = resolution.errors.map { - case ((failedModule, failedVersion), _) => - ModuleID(failedModule.organization, failedModule.name, failedVersion) - } - val msgs = resolution.errors.flatMap(_._2) - log.debug(s"Failed resolution: $msgs") - log.debug(s"Missing artifacts: $failedResolution") - val ex = new ResolveException(msgs, failedResolution) - Left(UnresolvedWarning(ex, uwconfig)) - } -} - -object CoursierDependencyResolution { - def apply(configuration: CoursierConfiguration) = - DependencyResolution(new CoursierDependencyResolution(configuration)) -} diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala deleted file mode 100644 index 5bb0f26ba..000000000 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/CoursierLibraryManagementCodec.scala +++ /dev/null @@ -1,12 +0,0 @@ -package sbt.librarymanagement -package coursier - -trait CoursierLibraryManagementCodec - extends sjsonnew.BasicJsonProtocol - with LibraryManagementCodec - // with sbt.internal.librarymanagement.formats.GlobalLockFormat - with sbt.internal.librarymanagement.formats.LoggerFormat - with sbt.librarymanagement.ResolverFormats - with CoursierConfigurationFormats - -object CoursierLibraryManagementCodec extends CoursierLibraryManagementCodec diff --git a/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala b/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala deleted file mode 100644 index ac656ac8a..000000000 --- a/coursier/src/main/scala/sbt/librarymanagement/coursier/Resolvers.scala +++ /dev/null @@ -1,51 +0,0 @@ -package sbt.librarymanagement.coursier - -import sbt.librarymanagement.{ MavenRepository, Resolver, URLRepository } - -object Resolvers { - - private val slowReposBase = Seq( - "https://repo.typesafe.com/", - "https://repo.scala-sbt.org/", - "http://repo.typesafe.com/", - "http://repo.scala-sbt.org/" - ) - - private val fastReposBase = Seq( - "http://repo1.maven.org/", - "https://repo1.maven.org/" - ) - - private def url(res: Resolver): Option[String] = - res match { - case m: MavenRepository => - Some(m.root) - case u: URLRepository => - u.patterns.artifactPatterns.headOption - .orElse(u.patterns.ivyPatterns.headOption) - case _ => - None - } - - private def filterResolvers(bases: Seq[String], - resolvers: Seq[(Resolver, Option[String])]): Seq[Resolver] = - resolvers - .filter(tuple => tuple._2.exists(url => bases.exists(base => url.startsWith(base)))) - .map(_._1) - - def reorder(resolvers: Seq[Resolver]): Seq[Resolver] = { - - val byUrl = resolvers.map(r => (r, url(r))) - - val fast = filterResolvers(fastReposBase, byUrl) - val slow = filterResolvers(slowReposBase, byUrl) - val rest = resolvers.diff(fast).diff(slow) - - val reordered = fast ++ rest ++ slow - assert(reordered.size == resolvers.size, - "Reordered resolvers should be the same size as the unordered ones.") - - reordered - } - -} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala deleted file mode 100644 index 20545bcf3..000000000 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/BaseCoursierSpecification.scala +++ /dev/null @@ -1,40 +0,0 @@ -package sbt.librarymanagement.coursier - -import sbt.internal.librarymanagement.cross.CrossVersionUtil -import sbt.internal.util.ConsoleLogger -import sbt.librarymanagement.Configurations._ -import sbt.librarymanagement._ - -trait BaseCoursierSpecification extends UnitSpec { - lazy val log = ConsoleLogger() - val lmEngine: CoursierDependencyResolution - - def configurations = Vector(Compile, Test, Runtime) - def module(moduleId: ModuleID, - deps: Vector[ModuleID], - scalaFullVersion: Option[String], - overrideScalaVersion: Boolean = true): ModuleDescriptor = { - val scalaModuleInfo = scalaFullVersion map { fv => - ScalaModuleInfo( - scalaFullVersion = fv, - scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(fv), - configurations = configurations, - checkExplicit = true, - filterImplicit = false, - overrideScalaVersion = overrideScalaVersion - ) - } - - val moduleSetting = ModuleDescriptorConfiguration(moduleId, ModuleInfo("foo")) - .withDependencies(deps) - .withConfigurations(configurations) - .withScalaModuleInfo(scalaModuleInfo) - lmEngine.moduleDescriptor(moduleSetting) - } - - def resolvers: Vector[Resolver] - - def configuration(res: Vector[Resolver] = resolvers) = - CoursierConfiguration().withResolvers(res) - -} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala deleted file mode 100644 index a118ccc10..000000000 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/ResolutionSpec.scala +++ /dev/null @@ -1,144 +0,0 @@ -package sbt.librarymanagement.coursier - -import sbt.librarymanagement.Configurations.Component -import sbt.librarymanagement.Resolver.{ - DefaultMavenRepository, - JCenterRepository, - JavaNet2Repository -} -import sbt.librarymanagement.syntax._ -import sbt.librarymanagement.{ Resolver, UnresolvedWarningConfiguration, UpdateConfiguration } - -class ResolutionSpec extends BaseCoursierSpecification { - override def resolvers = Vector( - DefaultMavenRepository, - JavaNet2Repository, - JCenterRepository, - Resolver.sbtPluginRepo("releases") - ) - - val lmEngine = new CoursierDependencyResolution(configuration()) - - private final val stubModule = "com.example" % "foo" % "0.1.0" % "compile" - - "Coursier dependency resolution" should "resolve very simple module" in { - val dependencies = Vector( - "com.typesafe.scala-logging" % "scala-logging_2.12" % "3.7.2" % "compile", - "org.scalatest" % "scalatest_2.12" % "3.0.4" % "test" - ).map(_.withIsTransitive(false)) - - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - resolution should be('right) - val r = resolution.right.get - r.configurations.map(_.configuration) should have size 3 - - val compileConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get - compileConfig.modules should have size 2 - - val runtimeConfig = r.configurations.find(_.configuration == Runtime.toConfigRef).get - runtimeConfig.modules should have size 2 - - val testConfig = r.configurations.find(_.configuration == Test.toConfigRef).get - testConfig.modules should have size 2 - } - - it should "resolve compiler bridge" in { - val dependencies = - Vector(("org.scala-sbt" % "compiler-interface" % "1.0.4" % "component").sources()) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - val r = resolution.right.get - - val componentConfig = r.configurations.find(_.configuration == Component.toConfigRef).get - componentConfig.modules should have size 2 - componentConfig.modules.head.artifacts should have size 1 - componentConfig.modules.head.artifacts.head._1.classifier should contain("sources") - } - - it should "resolve sbt jars" in { - val dependencies = - Vector(("org.scala-sbt" % "sbt" % "1.1.0" % "provided")) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - val r = resolution.right.get - - val modules = r.configurations.flatMap(_.modules) - modules.map(_.module.name) should contain("main_2.12") - } - - it should "resolve with default resolvers" in { - val dependencies = - Vector(("org.scala-sbt" % "compiler-interface" % "1.0.4" % "component").sources()) - val lmEngine = - CoursierDependencyResolution.apply( - configuration(Resolver.combineDefaultResolvers(Vector.empty)) - ) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - resolution should be('right) - } - - it should "resolve plugin" in { - val pluginAttributes = Map("scalaVersion" -> "2.12", "sbtVersion" -> "1.0") - val dependencies = - Vector(("org.xerial.sbt" % "sbt-sonatype" % "2.0").withExtraAttributes(pluginAttributes)) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - val r = resolution.right.get - - val componentConfig = r.configurations.find(_.configuration == Compile.toConfigRef).get - componentConfig.modules.map(_.module.name) should have size 5 - } - - it should "strip e: prefix from plugin attributes" in { - val pluginAttributes = Map("e:scalaVersion" -> "2.12", "e:sbtVersion" -> "1.0") - val dependencies = - Vector(("org.xerial.sbt" % "sbt-sonatype" % "2.0").withExtraAttributes(pluginAttributes)) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - resolution should be('right) - } - - it should "resolve plugins hosted on repo.typesafe.com" in { - val pluginAttributes = Map("e:scalaVersion" -> "2.12", "e:sbtVersion" -> "1.0") - val dependencies = - Vector(("com.typesafe.sbt" % "sbt-git" % "0.9.3").withExtraAttributes(pluginAttributes)) - val coursierModule = module(stubModule, dependencies, Some("2.12.4")) - val resolution = - lmEngine.update(coursierModule, UpdateConfiguration(), UnresolvedWarningConfiguration(), log) - - resolution should be('right) - } - - it should "reorder fast and slow resolvers" in { - val resolvers = Vector( - JavaNet2Repository, - Resolver.sbtPluginRepo("releases"), - DefaultMavenRepository - ) - val engine = new CoursierDependencyResolution(configuration(resolvers)) - engine.reorderedResolvers.head.name should be("public") - engine.reorderedResolvers.last.name should be("sbt-plugin-releases") - engine.reorderedResolvers should have size 3 - } - - it should "reorder default resolvers" in { - val resolvers = Resolver.combineDefaultResolvers(Vector.empty) - val engine = new CoursierDependencyResolution(configuration(resolvers)) - engine.reorderedResolvers should not be 'empty - engine.reorderedResolvers.head.name should be("public") - } -} diff --git a/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala b/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala deleted file mode 100644 index e6d7f8e75..000000000 --- a/coursier/src/test/scala/sbt/librarymanagement/coursier/UnitSpec.scala +++ /dev/null @@ -1,5 +0,0 @@ -package sbt.librarymanagement.coursier - -import org.scalatest.{ FlatSpec, Matchers } - -abstract class UnitSpec extends FlatSpec with Matchers From 3a0ce653628d448538a2d3a506d1b87c34b5a886 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 11 May 2019 19:49:04 -0400 Subject: [PATCH 0836/1030] IO 1.3.0-M10, and nightly version Fixes #305 --- build.sbt | 19 ++++++++++++------- project/Dependencies.scala | 18 ++++++------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/build.sbt b/build.sbt index b5f6d6d4c..911420b09 100644 --- a/build.sbt +++ b/build.sbt @@ -7,6 +7,17 @@ val _ = { sys.props += ("line.separator" -> "\n") } +ThisBuild / git.baseVersion := "1.3.0" +ThisBuild / version := { + val old = (ThisBuild / version).value + nightlyVersion match { + case Some(v) => v + case _ => + if (old contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" + else old + } +} + ThisBuild / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat def commonSettings: Seq[Setting[_]] = Def.settings( @@ -61,12 +72,6 @@ lazy val lmRoot = (project in file(".")) Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) }, bintrayPackage := "librarymanagement", - git.baseVersion := "1.3.0", - version := { - val v = version.value - if (v contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" - else v - } )), commonSettings, name := "LM Root", @@ -93,7 +98,7 @@ lazy val lmCore = (project in file("core")) scalaTest % Test, scalaCheck % Test ), - libraryDependencies ++= scalaXml.value, + libraryDependencies += scalaXml, resourceGenerators in Compile += Def .task( Util.generateVersionFile( diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e34ad5617..b34c8edf0 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,8 +5,10 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.8" - private val ioVersion = "1.3.0-M7" - private val utilVersion = "1.3.0-M5" + def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") + + private val ioVersion = nightlyVersion.getOrElse("1.3.0-M10") + private val utilVersion = nightlyVersion.getOrElse("1.3.0-M5") private val coursierVersion = "1.1.0-M7" private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -50,8 +52,8 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = scala211Module("scala-xml", "1.0.5") - val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5" + val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" + val scalaTest = "org.scalatest" %% "scalatest" % "3.0.6-SNAP5" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value @@ -61,12 +63,4 @@ object Dependencies { } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.4.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" - - private def scala211Module(name: String, moduleVersion: String) = - Def.setting { - scalaVersion.value match { - case sv if (sv startsWith "2.9.") || (sv startsWith "2.10.") => Nil - case _ => ("org.scala-lang.modules" %% name % moduleVersion) :: Nil - } - } } From b78f03b0d3cd9e72e12528981b64c795c3dca863 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 11 May 2019 21:25:23 -0400 Subject: [PATCH 0837/1030] comment out scriptedIvy --- .travis.yml | 1 - build.sbt | 15 ++++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea6789364..4ce21ae57 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,7 +48,6 @@ script: sbt -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies test - scriptedIvy packagedArtifacts # ensure that all artifacts for publish package without failure before_cache: diff --git a/build.sbt b/build.sbt index 911420b09..f47cccaf3 100644 --- a/build.sbt +++ b/build.sbt @@ -285,13 +285,14 @@ lazy val lmScriptedTest = (project in file("scripted-test")) scriptedBufferLog := false ).enablePlugins(SbtScriptedIT) -addCommandAlias("scriptedIvy", Seq( - "lmCore/publishLocal", - "lmIvy/publishLocal", - "lmScriptedTest/clean", - """set ThisBuild / scriptedTestLMImpl := "ivy"""", - """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=ivy" """, - "lmScriptedTest/scripted").mkString(";",";","")) +// we are updating the nightly process, so we are commenting this out for now +// addCommandAlias("scriptedIvy", Seq( +// "lmCore/publishLocal", +// "lmIvy/publishLocal", +// "lmScriptedTest/clean", +// """set ThisBuild / scriptedTestLMImpl := "ivy"""", +// """set ThisBuild / scriptedLaunchOpts += "-Ddependency.resolution=ivy" """, +// "lmScriptedTest/scripted").mkString(";",";","")) def customCommands: Seq[Setting[_]] = Seq( commands += Command.command("release") { state => From d15b406d14a9c53d29f6859c4813a623ca4ad626 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 13 May 2019 13:40:52 -0400 Subject: [PATCH 0838/1030] util 1.3.0-M7 --- project/Dependencies.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b34c8edf0..59d2ee7a9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -8,8 +8,7 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.3.0-M10") - private val utilVersion = nightlyVersion.getOrElse("1.3.0-M5") - private val coursierVersion = "1.1.0-M7" + private val utilVersion = nightlyVersion.getOrElse("1.3.0-M7") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -43,8 +42,6 @@ object Dependencies { val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832" - val coursier = "io.get-coursier" %% "coursier" % coursierVersion - val coursierCache = "io.get-coursier" %% "coursier-cache" % coursierVersion val sbtV = "1.0" val scalaV = "2.12" From ef4311acc8d69459e2a697514a91915c71571a6c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 18 Jun 2019 23:10:35 -0400 Subject: [PATCH 0839/1030] Gigahorse 0.5.0 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 59d2ee7a9..d9a1e088a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -58,6 +58,6 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.4.0" + val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" } From 8a6bdff16927ac8fc0b5ee9674ca7ef09d521f53 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 18 Jun 2019 23:15:55 -0400 Subject: [PATCH 0840/1030] bump AdoptOpenJDK --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4ce21ae57..d6e844c13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,9 @@ env: matrix: include: - env: - - TRAVIS_JDK=11.0.2.hs-adpt + - TRAVIS_JDK=11.0.3.hs-adpt - env: - - TRAVIS_JDK=8.0.202.hs-adpt + - TRAVIS_JDK=8.0.212.hs-adpt before_install: - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh From 68adae1c8ec885d52cac255b75e6ec02ab47ba5a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 18 Jun 2019 23:16:30 -0400 Subject: [PATCH 0841/1030] remove jabba --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6e844c13..e1d3fa441 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,9 +18,6 @@ matrix: - env: - TRAVIS_JDK=8.0.212.hs-adpt -before_install: - - curl -sL https://raw.githubusercontent.com/shyiko/jabba/0.11.0/install.sh | bash && . ~/.jabba/jabba.sh - before_install: # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - "[[ -d /home/travis/.sdkman/ ]] && [[ -d /home/travis/.sdkman/bin/ ]] || rm -rf /home/travis/.sdkman/" From 25f36e65a7b266c35c0f6a9ca2e318bf1bca63a4 Mon Sep 17 00:00:00 2001 From: Steve Waldman Date: Fri, 28 Jun 2019 23:30:10 -0700 Subject: [PATCH 0842/1030] Capture and report any error message in the response body when uploads fail. --- .../ivyint/GigahorseUrlHandler.scala | 61 ++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 72c7c58b4..943bab93a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -195,12 +195,71 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { if (l != null) { l.end(new CopyProgressEvent(EmptyBuffer, source.length())) } - validatePutStatusCode(dest, response.code(), response.message()) + validatePutStatusCode(dest, response) } finally { response.close() } } + private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies + private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 + + // this is perhaps overly cautious, but oh well + private def readTruncated(is: InputStream): Option[(Array[Byte], Boolean)] = { + val os = new ByteArrayOutputStream(ErrorBodyTruncateLen) + var count = 0 + var b = is.read() + while (b >= 0 && count < ErrorBodyTruncateLen) { + os.write(b) + count += 1 + b = is.read() + } + if (count > 0) { + Some((os.toByteArray, count >= ErrorBodyTruncateLen)) + } else { + None + } + } + + /* + * Supplements the IOException emitted on a bad status code by our inherited validatePutStatusCode(...) + * method with any message that might be present in an error response body. + * + * after calling this method, the object given as the response parameter must be reliably closed. + */ + private def validatePutStatusCode(dest: URL, response: Response): Unit = { + try { + validatePutStatusCode(dest, response.code(), response.message()) + } catch { + case ioe: IOException => { + val mbBodyMessage = { + for { + body <- Option(response.body()) + is <- Option(body.byteStream) + (bytes, truncated) <- readTruncated(is) + charset <- Option(body.contentType()).map(_.charset(DefaultErrorCharset)) orElse Some( + DefaultErrorCharset + ) + } yield { + val raw = new String(bytes, charset) + if (truncated) raw + "..." else raw + } + } + + mbBodyMessage match { + case Some(bodyMessage) => { // reconstruct the IOException + val newMessage = ioe.getMessage() + s"; Response Body: ${bodyMessage}" + val reconstructed = new IOException(newMessage, ioe.getCause()) + reconstructed.setStackTrace(ioe.getStackTrace()) + throw reconstructed + } + case None => { + throw ioe + } + } + } + } + } } object GigahorseUrlHandler { From 1b21f200b5da906eda7040b5119cae5518f22c90 Mon Sep 17 00:00:00 2001 From: Steve Waldman Date: Fri, 28 Jun 2019 23:31:36 -0700 Subject: [PATCH 0843/1030] Update scalafmt version. --- .scalafmt.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 718ce5aed..8392aa694 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 2.0.0-RC6 +version = 2.0.0-RC8 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] From 20ca549612bafd386ff991130227cfb50c28ddab Mon Sep 17 00:00:00 2001 From: Steve Waldman Date: Sat, 29 Jun 2019 00:08:44 -0700 Subject: [PATCH 0844/1030] Fix detection of truncation (so messages exactly max length aren't flagged truncated) --- .../ivyint/GigahorseUrlHandler.scala | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 943bab93a..1941de252 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -209,13 +209,18 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { val os = new ByteArrayOutputStream(ErrorBodyTruncateLen) var count = 0 var b = is.read() - while (b >= 0 && count < ErrorBodyTruncateLen) { - os.write(b) - count += 1 - b = is.read() + var truncated = false + while (!truncated && b >= 0) { + if (count >= ErrorBodyTruncateLen) { + truncated = true + } else { + os.write(b) + count += 1 + b = is.read() + } } if (count > 0) { - Some((os.toByteArray, count >= ErrorBodyTruncateLen)) + Some((os.toByteArray, truncated)) } else { None } From 315fbec370a8648d2b1d649f5f635cdca30f7947 Mon Sep 17 00:00:00 2001 From: Steve Waldman Date: Sat, 29 Jun 2019 12:41:26 -0700 Subject: [PATCH 0845/1030] Add more neurotic resource management, close()ing of streams. --- .../ivyint/GigahorseUrlHandler.scala | 59 +++++++++++++------ 1 file changed, 42 insertions(+), 17 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 1941de252..87ed352b1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -204,25 +204,50 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 - // this is perhaps overly cautious, but oh well - private def readTruncated(is: InputStream): Option[(Array[Byte], Boolean)] = { - val os = new ByteArrayOutputStream(ErrorBodyTruncateLen) - var count = 0 - var b = is.read() - var truncated = false - while (!truncated && b >= 0) { - if (count >= ErrorBodyTruncateLen) { - truncated = true - } else { - os.write(b) - count += 1 - b = is.read() + // neurotic resource managemement... + // we could use this elsewhere in the class too + private def borrow[S <: AutoCloseable, T](rsrc: => S)(op: S => T): T = { + val r = rsrc + val out = { + try { + op(r) + } catch { + case NonFatal(t) => { + try { + r.close() + } catch { + case NonFatal(ct) => t.addSuppressed(ct) + } + throw t + } } } - if (count > 0) { - Some((os.toByteArray, truncated)) - } else { - None + r.close() + out + } + + // this is perhaps overly cautious, but oh well + private def readTruncated(byteStream: InputStream): Option[(Array[Byte], Boolean)] = { + borrow(byteStream) { is => + borrow(new ByteArrayOutputStream(ErrorBodyTruncateLen)) { os => + var count = 0 + var b = is.read() + var truncated = false + while (!truncated && b >= 0) { + if (count >= ErrorBodyTruncateLen) { + truncated = true + } else { + os.write(b) + count += 1 + b = is.read() + } + } + if (count > 0) { + Some((os.toByteArray, truncated)) + } else { + None + } + } } } From 6329098beb83cc02049f34cb8cf1b6c5d2139124 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 9 Jul 2019 07:39:12 -0400 Subject: [PATCH 0846/1030] Detect latest AdoptOpenJDK JDK 8 and 11 --- .travis.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1d3fa441..8d7443c0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ -sudo: false -dist: trusty +dist: xenial group: stable language: scala @@ -14,21 +13,21 @@ env: matrix: include: - env: - - TRAVIS_JDK=11.0.3.hs-adpt + - ADOPTOPENJDK=11 - env: - - TRAVIS_JDK=8.0.212.hs-adpt + - ADOPTOPENJDK=8 before_install: # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - - "[[ -d /home/travis/.sdkman/ ]] && [[ -d /home/travis/.sdkman/bin/ ]] || rm -rf /home/travis/.sdkman/" + - "[[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/" - curl -sL https://get.sdkman.io | bash - - echo sdkman_auto_answer=true > /home/travis/.sdkman/etc/config - - source "/home/travis/.sdkman/bin/sdkman-init.sh" + - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config + - source "$HOME/.sdkman/bin/sdkman-init.sh" install: - - sdk install java $TRAVIS_JDK + - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | tail -1) - bin/fixpreloaded.sh - - unset _JAVA_OPTIONS + - unset JAVA_HOME - java -Xmx32m -version # detect sbt version from project/build.properties # - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" From c89695b4b2a62fa0bd7e024aebaafb1f07fd4937 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Aug 2019 16:20:22 -0400 Subject: [PATCH 0847/1030] Deprecate HTTP resolvers Ref https://github.com/sbt/sbt/issues/4905 --- .scalafmt.conf | 2 +- .../sbt/librarymanagement/URLRepository.scala | 2 +- .../main/contraband/librarymanagement.json | 5 +++- .../DependencyBuilders.scala | 1 + .../sbt/librarymanagement/ModuleIDExtra.scala | 5 +++- .../sbt/librarymanagement/ResolverExtra.scala | 25 +++++++++++++++++++ .../librarymanagement/ResolverSpec.scala | 16 ++++++++++++ 7 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 718ce5aed..e98e60599 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,4 +1,4 @@ -version = 2.0.0-RC6 +version = 2.0.0 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 1768cacda..fc39dda73 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class URLRepository private ( name: String, patterns: sbt.librarymanagement.Patterns) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { - + Resolver.validatePatterns(patterns) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 52cb34905..2fc2c6fbb 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -641,7 +641,10 @@ "name": "URLRepository", "namespace": "sbt.librarymanagement", "target": "Scala", - "type": "record" + "type": "record", + "extra": [ + "Resolver.validatePatterns(patterns)" + ] }, { "name": "SshBasedRepository", diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala index 09b1d8468..a9c9d86fd 100755 --- a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -69,6 +69,7 @@ object DependencyBuilders { final class RepositoryName private[sbt] (name: String) { def at(location: String) = { nonEmpty(location, "Repository location") + Resolver.validateUrlString(location) MavenRepository(name, location) } } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index f15c5acb3..d8c6ca6f2 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -99,7 +99,10 @@ private[librarymanagement] abstract class ModuleIDExtra { * This value is only consulted if the module is not found in a repository. * It is not included in published metadata. */ - def from(url: String) = artifacts(Artifact(name, new URL(url))) + def from(url: String) = { + Resolver.validateUrlString(url) + artifacts(Artifact(name, new URL(url))) + } /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String) = artifacts(Artifact(name, c)) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d359f31ad..d1d435014 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -7,6 +7,7 @@ import java.io.{ IOException, File } import java.net.URL import scala.xml.XML import org.xml.sax.SAXParseException +import sbt.util.{ Level, LogExchange } final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -403,4 +404,28 @@ private[librarymanagement] abstract class ResolverFunctions { val pList = Vector(localBasePattern) Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) } + + lazy val log = { + val log0 = LogExchange.logger("sbt.librarymanagement.ResolverExtra") + LogExchange.bindLoggerAppenders( + "sbt.librarymanagement.ResolverExtra", + List(LogExchange.buildAsyncStdout -> Level.Info) + ) + log0 + } + private[sbt] def warnHttp(value: String): Unit = { + log.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS") + } + private[sbt] def validatePatterns(patterns: Patterns): Unit = { + val ivy = patterns.ivyPatterns.headOption map (_.startsWith("http:")) + val art = patterns.artifactPatterns.headOption map (_.startsWith("http:")) + (ivy orElse art) foreach { _ => + warnHttp(patterns.toString) + } + } + private[sbt] def validateUrlString(url: String): Unit = { + if (url.startsWith("http:")) { + warnHttp(url) + } + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala new file mode 100644 index 000000000..64afda27e --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala @@ -0,0 +1,16 @@ +package sbttest + +import java.net.URL +import org.scalatest._ +import sbt.librarymanagement._ +import sbt.librarymanagement.syntax._ + +class ResolverSpec extends FunSuite with DiagrammedAssertions { + test("Resolver.url") { + Resolver.url("Test Repo", new URL("http://example.com/"))(Resolver.ivyStylePatterns) + } + + test("at") { + "something" at "http://example.com" + } +} From fcc8b610112fdee9c28fb821df8d0011b87ef3d6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 1 Aug 2019 17:47:38 -0400 Subject: [PATCH 0848/1030] use head -1 SDKMAN lists the latest one first. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8d7443c0e..a8a7e50e7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,7 @@ before_install: - source "$HOME/.sdkman/bin/sdkman-init.sh" install: - - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | tail -1) + - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) - bin/fixpreloaded.sh - unset JAVA_HOME - java -Xmx32m -version From 8fee1e2666ddf391d5ba7c7cc9ac33a196a2b534 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 13 Aug 2019 23:35:50 -0400 Subject: [PATCH 0849/1030] improve "X is evicted completely" Fixes https://github.com/sbt/sbt/issues/4946 1. This rewords "evicted completely" to "evicted for all versions" 2. Skips transitive and complete evictions (eviction that has no winner version) --- .../main/scala/sbt/librarymanagement/EvictionWarning.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 22405934c..c090cd2ad 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -183,7 +183,7 @@ object EvictionPair { } val winnerRev = a.winner match { case Some(r) => s":${r.module.revision} is selected over ${revsStr}" - case _ => " is evicted completely" + case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") @@ -312,7 +312,9 @@ object EvictionWarning { binaryIncompatibleEvictionExists = true } case p => - if (!guessCompatible(p)) { + // don't report on a transitive eviction that does not have a winner + // https://github.com/sbt/sbt/issues/4946 + if (!guessCompatible(p) && p.winner.isDefined) { if (options.warnTransitiveEvictions) transitiveEvictions += p if (options.warnEvictionSummary) From 8c16fd0edf52b7c33116f86dc9ef834235180896 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 14 Aug 2019 02:21:24 -0400 Subject: [PATCH 0850/1030] switch to using scala-verify --- build.sbt | 5 +- .../AbstractEngineSpec.scala | 3 +- .../librarymanagement/ResolutionSpec.scala | 34 +- .../internal/librarymanagement/UnitSpec.scala | 5 - .../ComponentManagerTest.scala | 60 +- .../CustomPomParserTest.scala | 15 +- .../DMSerializationSpec.scala | 56 +- .../EvictionWarningSpec.scala | 524 +++++++++--------- .../FakeResolverSpecification.scala | 36 +- .../librarymanagement/FrozenModeSpec.scala | 4 +- .../librarymanagement/InclExclSpec.scala | 97 ++-- .../InconsistentDuplicateSpec.scala | 25 +- .../librarymanagement/IvyRepoSpec.scala | 20 +- .../librarymanagement/MakePomSpec.scala | 48 +- .../ManagedChecksumsSpec.scala | 4 +- .../MergeDescriptorSpec.scala | 8 +- .../ModuleResolversTest.scala | 4 +- .../librarymanagement/OfflineModeSpec.scala | 15 +- .../librarymanagement/ResolverSpec.scala | 6 +- .../librarymanagement/ScalaOverrideTest.scala | 198 ++++--- .../librarymanagement/SftpRepoSpec.scala | 4 +- .../librarymanagement/UpdateOptionsSpec.scala | 22 +- project/Dependencies.scala | 1 + 23 files changed, 641 insertions(+), 553 deletions(-) delete mode 100644 common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala diff --git a/build.sbt b/build.sbt index f47cccaf3..923df2598 100644 --- a/build.sbt +++ b/build.sbt @@ -27,6 +27,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", + testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), @@ -96,7 +97,7 @@ lazy val lmCore = (project in file("core")) okhttpUrlconnection, sjsonnewScalaJson.value % Optional, scalaTest % Test, - scalaCheck % Test + scalaCheck % Test, ), libraryDependencies += scalaXml, resourceGenerators in Compile += Def @@ -222,7 +223,7 @@ lazy val lmCommonTest = (project in file("common-test")) commonSettings, skip in publish := true, name := "common-test", - libraryDependencies ++= Seq(scalaTest, scalaCheck), + libraryDependencies ++= Seq(scalaTest, scalaCheck, scalaVerify), scalacOptions in (Compile, console) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala index e676b7857..55089330d 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala @@ -1,8 +1,9 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ +import verify.BasicTestSuite -abstract class AbstractEngineSpec extends UnitSpec { +abstract class AbstractEngineSpec extends BasicTestSuite { def cleanCache(): Unit def module( diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala index fe14d1370..818da8155 100644 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala +++ b/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala @@ -8,7 +8,7 @@ import sbt.librarymanagement.syntax._ abstract class ResolutionSpec extends AbstractEngineSpec { import ShowLines._ - "Resolving the same module twice" should "work" in { + test("Resolving the same module twice should work") { cleanCache() val m = module( exampleModuleId("0.1.0"), @@ -22,10 +22,10 @@ abstract class ResolutionSpec extends AbstractEngineSpec { println(report) // second resolution reads from the minigraph println(report.configurations.head.modules.head.artifacts) - report.configurations.size shouldBe 3 + assert(report.configurations.size == 3) } - "Resolving the unsolvable module should" should "not work" in { + test("Resolving the unsolvable module should should not work") { // log.setLevel(Level.Debug) val m = module( exampleModuleId("0.2.0"), @@ -40,11 +40,15 @@ abstract class ResolutionSpec extends AbstractEngineSpec { updateEither(m) match { case Right(_) => sys.error("this should've failed 2") case Left(uw) => - uw.lines should contain allOf ("\n\tNote: Unresolved dependencies path:", - "\t\tfoundrylogic.vpp:vpp:2.2.1", - "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", - "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", - "\t\t +- com.example:foo:0.2.0") + List( + "\n\tNote: Unresolved dependencies path:", + "\t\tfoundrylogic.vpp:vpp:2.2.1", + "\t\t +- org.apache.cayenne:cayenne-tools:3.0.2", + "\t\t +- org.apache.cayenne.plugins:maven-cayenne-plugin:3.0.2", + "\t\t +- com.example:foo:0.2.0" + ) foreach { line => + assert(uw.lines.contains[String](line)) + } } } @@ -52,7 +56,7 @@ abstract class ResolutionSpec extends AbstractEngineSpec { // data-avro:1.9.40 depends on avro:1.4.0, which depends on netty:3.2.1.Final. // avro:1.4.0 will be evicted by avro:1.7.7. // #2046 says that netty:3.2.0.Final is incorrectly evicted by netty:3.2.1.Final - "Resolving a module with a pseudo-conflict" should "work" in { + test("Resolving a module with a pseudo-conflict should work") { // log.setLevel(Level.Debug) cleanCache() val m = module( @@ -74,7 +78,7 @@ abstract class ResolutionSpec extends AbstractEngineSpec { })) } - "Resolving a module with sbt cross build" should "work" in { + test("Resolving a module with sbt cross build should work") { cleanCache() val attributes013 = Map("e:sbtVersion" -> "0.13", "e:scalaVersion" -> "2.10") val attributes10 = Map("e:sbtVersion" -> "1.0", "e:scalaVersion" -> "2.12") @@ -88,11 +92,13 @@ abstract class ResolutionSpec extends AbstractEngineSpec { Vector(sbtRelease.withExtraAttributes(attributes10)), Some("2.12.3") ) - update(module013).configurations.head.modules.map(_.toString).loneElement should include( - "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" + assert( + update(module013).configurations.head.modules.map(_.toString).loneElement + contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" ) - update(module10).configurations.head.modules.map(_.toString).loneElement should include( - "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" + assert( + update(module10).configurations.head.modules.map(_.toString).loneElement + contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" ) } diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala b/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala deleted file mode 100644 index dfd947c8f..000000000 --- a/common-test/src/main/scala/sbt/internal/librarymanagement/UnitSpec.scala +++ /dev/null @@ -1,5 +0,0 @@ -package sbt.internal.librarymanagement - -import org.scalatest._ - -abstract class UnitSpec extends FlatSpec with Matchers diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index 2a9f3f675..dc2947e26 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -7,65 +7,83 @@ import sbt.io.IO import org.apache.ivy.util.ChecksumHelper import IfMissing.Fail import xsbti.ComponentProvider +import verify.BasicTestSuite // TODO - We need to re-enable this test. Right now, we dont' have a "stub" launcher for this. // This is testing something which uses a launcher interface, but was grabbing the underlying class directly // when it really should, instead, be stubbing out the underyling class. -class ComponentManagerTest extends UnitSpec { +object ComponentManagerTest extends BasicTestSuite { val TestID = "manager-test" - "Component manager" should "throw an exception if 'file' is called for a non-existing component" in { + test( + "Component manager should throw an exception if 'file' is called for a non-existing component" + ) { withManager { manager => - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "throw an exception if 'file' is called for an empty component" in { + + test("it should throw an exception if 'file' is called for an empty component") { withManager { manager => manager.define(TestID, Nil) - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "return the file for a single-file component" in { + + test("it should return the file for a single-file component") { withManager { manager => val hash = defineFile(manager, TestID, "a") - checksum(manager.file(TestID)(Fail)) shouldBe hash + assert(checksum(manager.file(TestID)(Fail)) == hash) } } - it should "throw an exception if 'file' is called for multi-file component" in { + + test("it should throw an exception if 'file' is called for multi-file component") { withManager { manager => defineFiles(manager, TestID, "a", "b") - intercept[InvalidComponent] { manager.file(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.file(TestID)(Fail) + () + } } } - it should "return the files for a multi-file component" in { + + test("it should return the files for a multi-file component") { withManager { manager => val hashes = defineFiles(manager, TestID, "a", "b") - checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) + assert(checksum(manager.files(TestID)(Fail)).toSet == hashes.toSet) } } - it should "return the files for a single-file component" in { + + test("it should return the files for a single-file component") { withManager { manager => val hashes = defineFiles(manager, TestID, "a") - checksum(manager.files(TestID)(Fail)) should contain theSameElementsAs (hashes) + assert(checksum(manager.files(TestID)(Fail)).toSet == hashes.toSet) } } - it should "throw an exception if 'files' is called for a non-existing component" in { + + test("it should throw an exception if 'files' is called for a non-existing component") { withManager { manager => - intercept[InvalidComponent] { manager.files(TestID)(Fail) } - () + intercept[InvalidComponent] { + manager.files(TestID)(Fail) + () + } } } - it should "properly cache a file and then retrieve it to an unresolved component" in { + + test("it should properly cache a file and then retrieve it to an unresolved component") { withTemporaryDirectory { ivyHome => withManagerHome(ivyHome) { definingManager => val hash = defineFile(definingManager, TestID, "a") try { definingManager.cache(TestID) withManagerHome(ivyHome) { usingManager => - checksum(usingManager.file(TestID)(Fail)) shouldBe hash + assert(checksum(usingManager.file(TestID)(Fail)) == hash) } } finally { definingManager.clearCache(TestID) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala index 97d5c54cb..e987b7c18 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CustomPomParserTest.scala @@ -8,9 +8,12 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.io.IO.withTemporaryDirectory import sbt.internal.util.ConsoleLogger +import verify.BasicTestSuite -class CustomPomParserTest extends UnitSpec { - "CustomPomParser" should "resolve an artifact with packaging 'scala-jar' as a regular jar file." in { +object CustomPomParserTest extends BasicTestSuite { + test( + "CustomPomParser should resolve an artifact with packaging 'scala-jar' as a regular jar file." + ) { val log = ConsoleLogger() withTemporaryDirectory { cacheDir => val repoUrl = getClass.getResource("/test-maven-repo") @@ -28,12 +31,12 @@ class CustomPomParserTest extends UnitSpec { ivy.resolve(mrid, resolveOpts, true) } - resolveReport.hasError shouldBe false - resolveReport.getArtifacts.size() shouldBe 1 + assert(!resolveReport.hasError) + assert(resolveReport.getArtifacts.size() == 1) val artifact: IvyArtifact = resolveReport.getArtifacts.asInstanceOf[java.util.List[IvyArtifact]].get(0) - artifact.getModuleRevisionId shouldBe mrid - artifact.getExt shouldBe "jar" + assert(artifact.getModuleRevisionId == mrid) + assert(artifact.getExt == "jar") } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 586b04531..ace394002 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -6,47 +6,59 @@ import java.io.File import sbt.librarymanagement._ import sjsonnew.shaded.scalajson.ast.unsafe._ import sjsonnew._, support.scalajson.unsafe._ -import org.scalatest.Assertion import LibraryManagementCodec._ +import verify.BasicTestSuite -class DMSerializationSpec extends UnitSpec { - "CrossVersion.full" should "roundtrip" in { +object DMSerializationSpec extends BasicTestSuite { + test("CrossVersion.full should roundtrip") { roundtripStr(CrossVersion.full: CrossVersion) } - "CrossVersion.binary" should "roundtrip" in { + + test("CrossVersion.binary should roundtrip") { roundtripStr(CrossVersion.binary: CrossVersion) } - "CrossVersion.Disabled" should "roundtrip" in { + + test("CrossVersion.Disabled should roundtrip") { roundtrip(Disabled(): CrossVersion) } - """Artifact("foo")""" should "roundtrip" in { + + test("""Artifact("foo") should roundtrip""") { roundtrip(Artifact("foo")) } - """Artifact("foo", "sources")""" should "roundtrip" in { + + test("""Artifact("foo", "sources") should roundtrip""") { roundtrip(Artifact("foo", "sources")) } - """Artifact.pom("foo")""" should "roundtrip" in { + + test("""Artifact.pom("foo") should roundtrip""") { roundtrip(Artifact.pom("foo")) } - """Artifact("foo", url("http://example.com/"))""" should "roundtrip" in { + + test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { roundtrip(Artifact("foo", new URL("http://example.com/"))) } - """Artifact("foo").extra(("key", "value"))""" should "roundtrip" in { + + test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { roundtrip(Artifact("foo").extra(("key", "value"))) } - """ModuleID("org", "name", "1.0")""" should "roundtrip" in { + + test("""ModuleID("org", "name", "1.0") should roundtrip""") { roundtrip(ModuleID("org", "name", "1.0")) } - """ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil)""" should "roundtrip" in { + + test("""ModuleReport(ModuleID("org", "name", "1.0"), Nil, Nil) should roundtrip""") { roundtripStr(ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty)) } - "Organization artifact report" should "roundtrip" in { + + test("Organization artifact report should roundtrip") { roundtripStr(organizationArtifactReportExample) } - "Configuration report" should "roundtrip" in { + + test("Configuration report should roundtrip") { roundtripStr(configurationReportExample) } - "Update report" should "roundtrip" in { + + test("Update report should roundtrip") { roundtripStr(updateReportExample) } @@ -68,13 +80,17 @@ class DMSerializationSpec extends UnitSpec { lazy val moduleReportExample = ModuleReport(ModuleID("org", "name", "1.0"), Vector.empty, Vector.empty) - def roundtrip[A: JsonReader: JsonWriter](a: A): Assertion = - roundtripBuilder(a) { _ shouldBe _ } + def roundtrip[A: JsonReader: JsonWriter](a: A): Unit = + roundtripBuilder(a) { (x1, x2) => + assert(x1 == x2) + } - def roundtripStr[A: JsonReader: JsonWriter](a: A): Assertion = - roundtripBuilder(a) { _.toString shouldBe _.toString } + def roundtripStr[A: JsonReader: JsonWriter](a: A): Unit = + roundtripBuilder(a) { (x1, x2) => + assert(x1.toString == x2.toString) + } - def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Assertion): Assertion = { + def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit = { val json = isoString to (Converter toJsonUnsafe a) println(json) val obj = Converter fromJsonUnsafe [A] (isoString from json) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 3a90fc05a..925bdb599 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -4,52 +4,269 @@ import sbt.librarymanagement._ import sbt.internal.librarymanagement.cross.CrossVersionUtil import sbt.librarymanagement.syntax._ -class EvictionWarningSpec extends BaseIvySpecification { +object EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - """Eviction of non-overridden scala-library whose scalaVersion - """ should "be detected" in scalaVersionWarn1() - it should "not be detected if it's disabled" in scalaVersionWarn2() - it should "print out message about the eviction" in scalaVersionWarn3() - it should "print out message about the eviction with callers" in scalaVersionWarn4() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaVersionWarn5() + import sbt.util.ShowLines._ + def scalaVersionDeps = Vector(scala2102, akkaActor230) - """Non-eviction of overridden scala-library whose scalaVersion - """ should "not be detected if it's enabled" in scalaVersionNoWarn1() - it should "not be detected if it's disabled" in scalaVersionNoWarn2() + test("Eviction of non-overridden scala-library whose scalaVersion should be detected") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).scalaEvictions.size == 1) + } - """Including two (suspect) binary incompatible Java libraries to direct dependencies - """ should "be detected as eviction" in javaLibWarn1() - it should "not be detected if it's disabled" in javaLibWarn2() - it should "print out message about the eviction" in javaLibWarn3() - it should "print out message about the eviction with callers" in javaLibWarn4() - it should "print out summary about the eviction if warn eviction summary enabled" in javaLibWarn5() + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + ) + } - """Including two (suspect) binary compatible Java libraries to direct dependencies - """ should "not be detected as eviction" in javaLibNoWarn1() - it should "not print out message about the eviction" in javaLibNoWarn2() + test("it should print out message about the eviction") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withShowCallers(false), report).lines == + List( + "Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "", + "To force scalaVersion, add the following:", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + ) + ) + } - """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies - """ should "be detected as eviction" in javaLibTransitiveWarn2() + test("it should print out message about the eviction with callers") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Scala version was updated by one of library dependencies:", + "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", + "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", + "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", + "", + "To force scalaVersion, add the following:", + "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + ) + ) + } - //it should "print out message about the eviction if it's enabled" in javaLibTransitiveWarn3() + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } - """Including two (suspect) binary incompatible Scala libraries to direct dependencies - """ should "be detected as eviction" in scalaLibWarn1() - it should "print out message about the eviction" in scalaLibWarn2() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibWarn3() + test( + """Non-eviction of overridden scala-library whose scalaVersion should "not be detected if it's enabled"""" + ) { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).scalaEvictions.size == 0) + } - """Including two (suspect) binary compatible Scala libraries to direct dependencies - """ should "not be detected as eviction" in scalaLibNoWarn1() - it should "not print out message about the eviction" in scalaLibNoWarn2() - it should "not print out summary about the eviction even if warn eviction summary enabled" in scalaLibNoWarn3() + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + ) + } - """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies - """ should "be detected as eviction" in scalaLibTransitiveWarn2() - it should "print out message about the eviction if it's enabled" in scalaLibTransitiveWarn3() - it should "print out summary about the eviction if warn eviction summary enabled" in scalaLibTransitiveWarn4() + test( + """Including two (suspect) binary incompatible Java libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } - "Comparing sbt 0.x" should "use Second Segment Variation semantics" in { + test("it should not be detected if it's disabled") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning( + m, + fullOptions + .withWarnDirectEvictions(false) + .withWarnTransitiveEvictions(false), + report + ).reportedEvictions.size == 0 + ) + } + + test("it should print out message about the eviction") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "" + ) + ) + } + + test("it should print out message about the eviction with callers") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions.withShowCallers(true), report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* commons-io:commons-io:2.4 is selected over 1.4", + "\t +- com.example:foo:0.1.0 (depends on 1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test( + """Including two (suspect) binary compatible Java libraries to direct dependencies should not be detected as eviction""" + ) { + val deps = Vector(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 0) + } + + test("it should not print out message about the eviction") { + val deps = Vector(commonsIo14, commonsIo13) + val m = module(defaultModuleId, deps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).lines == Nil) + } + + test( + """Including two (suspect) transitively binary incompatible Java libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test( + """Including two (suspect) binary incompatible Scala libraries to direct dependencies should be detected as eviction""" + ) { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test("it should print out message about the eviction") { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val deps = Vector(scala2104, akkaActor214, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test( + """Including two (suspect) binary compatible Scala libraries to direct dependencies should not be detected as eviction""" + ) { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 0) + } + + test("it should not print out message about the eviction") { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).lines == Nil) + } + + test("it should not print out summary about the eviction even if warn eviction summary enabled") { + val deps = Vector(scala2104, akkaActor230, akkaActor234) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, EvictionWarningOptions.summary, report).lines == Nil) + } + + test( + """Including two (suspect) transitively binary incompatible Scala libraries to direct dependencies should be detected as eviction""" + ) { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionWarning(m, fullOptions, report).reportedEvictions.size == 1) + } + + test("it should print out message about the eviction if it's enabled") { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, fullOptions, report).lines == + List( + "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should print out summary about the eviction if warn eviction summary enabled") { + val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionWarning(m, EvictionWarningOptions.summary, report).lines == + List( + "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + ) + ) + } + + test("Comparing sbt 0.x should use Second Segment Variation semantics") { val m1 = "org.scala-sbt" % "util-logging" % "0.13.16" val m2 = "org.scala-sbt" % "util-logging" % "0.13.1" assert( @@ -57,7 +274,7 @@ class EvictionWarningSpec extends BaseIvySpecification { ) } - "Comparing sbt 1.x" should "use Semantic Versioning semantics" in { + test("Comparing sbt 1.x should use Semantic Versioning semantics") { val m1 = "org.scala-sbt" % "util-logging_2.12" % "1.0.0" val m2 = "org.scala-sbt" % "util-logging_2.12" % "1.1.0" assert( @@ -91,244 +308,9 @@ class EvictionWarningSpec extends BaseIvySpecification { ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 def fullOptions = EvictionWarningOptions.full - - import sbt.util.ShowLines._ - - def scalaVersionDeps = Vector(scala2102, akkaActor230) - - def scalaVersionWarn1() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).scalaEvictions should have size (1) - } - - def scalaVersionWarn2() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) - } - - def scalaVersionWarn3() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withShowCallers(false), report).lines shouldBe - List( - "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", - "", - "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - ) - } - - def scalaVersionWarn4() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Scala version was updated by one of library dependencies:", - "\t* org.scala-lang:scala-library:2.10.3 is selected over 2.10.2", - "\t +- com.typesafe.akka:akka-actor_2.10:2.3.0 (depends on 2.10.3)", - "\t +- com.example:foo:0.1.0 (depends on 2.10.2)", - "", - "To force scalaVersion, add the following:", - "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - ) - } - - def scalaVersionWarn5() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def scalaVersionNoWarn1() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).scalaEvictions should have size (0) - } - - def scalaVersionNoWarn2() = { - val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions should have size (0) - } - def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) - - def javaLibWarn1() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def javaLibWarn2() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning( - m, - fullOptions - .withWarnDirectEvictions(false) - .withWarnTransitiveEvictions(false), - report - ).reportedEvictions should have size (0) - } - - def javaLibWarn3() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* commons-io:commons-io:2.4 is selected over 1.4", - "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "" - ) - } - - def javaLibWarn4() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions.withShowCallers(true), report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* commons-io:commons-io:2.4 is selected over 1.4", - "\t +- com.example:foo:0.1.0 (depends on 1.4)", - "" - ) - } - - def javaLibWarn5() = { - val m = module(defaultModuleId, javaLibDirectDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def javaLibNoWarn1() = { - val deps = Vector(commonsIo14, commonsIo13) - val m = module(defaultModuleId, deps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) - } - - def javaLibNoWarn2() = { - val deps = Vector(commonsIo14, commonsIo13) - val m = module(defaultModuleId, deps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe Nil - } - def javaLibTransitiveDeps = Vector(unfilteredUploads080, bnfparser10) - - def javaLibTransitiveWarn2() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def javaLibTransitiveWarn3() = { - val m = module(defaultModuleId, javaLibTransitiveDeps, Some("2.10.3")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings.", - "Here are some of the libraries that were evicted:", - "\t* commons-io:commons-io:1.4 -> 2.4 (caller: ca.gobits.bnf:bnfparser:1.0, net.databinder:unfiltered-uploads_2.10:0.8.0)" - ) - } - - def scalaLibWarn1() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def scalaLibWarn2() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", - "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", - "" - ) - } - - def scalaLibWarn3() = { - val deps = Vector(scala2104, akkaActor214, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - - def scalaLibNoWarn1() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (0) - } - - def scalaLibNoWarn2() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe Nil - } - - def scalaLibNoWarn3() = { - val deps = Vector(scala2104, akkaActor230, akkaActor234) - val m = module(defaultModuleId, deps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe Nil - } - def scalaLibTransitiveDeps = Vector(scala2104, bananaSesame04, akkaRemote234) - - def scalaLibTransitiveWarn2() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).reportedEvictions should have size (1) - } - - def scalaLibTransitiveWarn3() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, fullOptions, report).lines shouldBe - List( - "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", - "", - "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 is selected over 2.1.4", - "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", - "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", - "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", - "" - ) - } - - def scalaLibTransitiveWarn4() = { - val m = module(defaultModuleId, scalaLibTransitiveDeps, Some("2.10.4")) - val report = ivyUpdate(m) - EvictionWarning(m, EvictionWarningOptions.summary, report).lines shouldBe - List( - "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - ) - } - def dummyScalaModuleInfo(v: String): ScalaModuleInfo = ScalaModuleInfo( scalaFullVersion = v, diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index fdb5cc413..89095a51c 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -6,7 +6,7 @@ import java.io.File import sbt.librarymanagement.{ ModuleID, RawRepository, Resolver, UpdateReport, ResolveException } -class FakeResolverSpecification extends BaseIvySpecification { +object FakeResolverSpecification extends BaseIvySpecification { import FakeResolver._ val myModule = @@ -17,36 +17,42 @@ class FakeResolverSpecification extends BaseIvySpecification { val nonExisting = ModuleID("com.example", "does-not-exist", "1.2.3").withConfigurations(Some("compile")) - "The FakeResolver" should "find modules with only one artifact" in { + test("The FakeResolver should find modules with only one artifact") { val m = getModule(myModule) val report = ivyUpdate(m) val allFiles = getAllFiles(report) - report.allModules.length shouldBe 1 - report.configurations.length shouldBe 3 - allFiles.toSet.size shouldBe 1 - allFiles(1).getName shouldBe "artifact1-0.0.1-SNAPSHOT.jar" + assert(report.allModules.length == 1) + assert(report.configurations.length == 3) + assert(allFiles.toSet.size == 1) + assert(allFiles(1).getName == "artifact1-0.0.1-SNAPSHOT.jar") } - it should "find modules with more than one artifact" in { + test("it should find modules with more than one artifact") { val m = getModule(example) val report = ivyUpdate(m) val allFiles = getAllFiles(report).toSet - report.allModules.length shouldBe 1 - report.configurations.length shouldBe 3 - allFiles.toSet.size shouldBe 2 - allFiles map (_.getName) shouldBe Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt") + assert(report.allModules.length == 1) + assert(report.configurations.length == 3) + assert(allFiles.toSet.size == 2) + assert(allFiles.map(_.getName) == Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt")) } - it should "fail gracefully when asked for unknown modules" in { + test("it should fail gracefully when asked for unknown modules") { val m = getModule(nonExisting) - a[ResolveException] should be thrownBy ivyUpdate(m) + intercept[ResolveException] { + ivyUpdate(m) + () + } } - it should "fail gracefully when some artifacts cannot be found" in { + test("it should fail gracefully when some artifacts cannot be found") { val m = getModule(anotherExample) - the[ResolveException] thrownBy ivyUpdate(m) should have message "download failed: com.example#another-example;1.0.0!non-existing.txt" + intercept[ResolveException] { + ivyUpdate(m) + () + } } private def artifact1 = new File(getClass.getResource("/artifact1.jar").toURI.getPath) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index c6620bee7..cae7b3f48 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -4,7 +4,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions import sbt.librarymanagement.syntax._ -class FrozenModeSpec extends BaseIvySpecification { +object FrozenModeSpec extends BaseIvySpecification { private final val targetDir = Some(currentDependency) private final val onlineConf = makeUpdateConfiguration(false, targetDir) private final val frozenConf = makeUpdateConfiguration(false, targetDir).withFrozen(true) @@ -26,7 +26,7 @@ class FrozenModeSpec extends BaseIvySpecification { "com.lihaoyi" % "sourcecode_2.12" % "0.1.3" % "compile" ) - it should "fail when artifacts are missing in the cache" in { + test("fail when artifacts are missing in the cache") { cleanIvyCache() def update(module: IvySbt#Module, conf: UpdateConfiguration) = IvyActions.updateEither(module, conf, warningConf, log) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala index 1c35fc007..d05f115ef 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala @@ -2,10 +2,53 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ -import org.scalatest.Assertion import DependencyBuilders.OrganizationArtifactName -class InclExclSpec extends BaseIvySpecification { +object InclExclSpec extends BaseIvySpecification { + val scala210 = Some("2.10.4") + test("it should exclude any version of lift-json via a new exclusion rule") { + val toExclude = ExclusionRule("net.liftweb", "lift-json_2.10") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testLiftJsonIsMissing(report) + } + + test("it should exclude any version of lift-json with explicit Scala version") { + val excluded: OrganizationArtifactName = "net.liftweb" % "lift-json_2.10" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + test("it should exclude any version of cross-built lift-json") { + val excluded: OrganizationArtifactName = "net.liftweb" %% "lift-json" + val report = getIvyReport(createLiftDep(excluded), scala210) + testLiftJsonIsMissing(report) + } + + val scala2122 = Some("2.12.2") + test("it should exclude a concrete version of lift-json when it's full cross version") { + val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } + + test("it should exclude any version of lift-json when it's full cross version") { + val excluded = new OrganizationArtifactName("net.liftweb", "lift-json", CrossVersion.full) + val report = getIvyReport(createMetaDep(excluded), scala2122) + testScalahostIsMissing(report) + } + + test("it should exclude any version of scala-library via * artifact id") { + val toExclude = ExclusionRule("org.scala-lang", "*") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } + + test("it should exclude any version of scala-library via * org id") { + val toExclude = ExclusionRule("*", "scala-library") + val report = getIvyReport(createLiftDep(toExclude), scala210) + testScalaLibraryIsMissing(report) + } + def createLiftDep(toExclude: ExclusionRule): ModuleID = ("net.liftweb" %% "lift-mapper" % "2.6-M4" % "compile").excludeAll(toExclude) @@ -20,68 +63,24 @@ class InclExclSpec extends BaseIvySpecification { ivyUpdate(ivyModule) } - def testLiftJsonIsMissing(report: UpdateReport): Assertion = { + def testLiftJsonIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("lift-json")), "lift-json has not been excluded." ) } - def testScalaLibraryIsMissing(report: UpdateReport): Assertion = { + def testScalaLibraryIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("scala-library")), "scala-library has not been excluded." ) } - def testScalahostIsMissing(report: UpdateReport): Assertion = { + def testScalahostIsMissing(report: UpdateReport): Unit = { assert( !report.allModules.exists(_.name.contains("scalahost")), "scalahost has not been excluded." ) } - - val scala210 = Some("2.10.4") - it should "exclude any version of lift-json via a new exclusion rule" in { - val toExclude = ExclusionRule("net.liftweb", "lift-json_2.10") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testLiftJsonIsMissing(report) - } - - it should "exclude any version of lift-json with explicit Scala version" in { - val excluded: OrganizationArtifactName = "net.liftweb" % "lift-json_2.10" - val report = getIvyReport(createLiftDep(excluded), scala210) - testLiftJsonIsMissing(report) - } - - it should "exclude any version of cross-built lift-json" in { - val excluded: OrganizationArtifactName = "net.liftweb" %% "lift-json" - val report = getIvyReport(createLiftDep(excluded), scala210) - testLiftJsonIsMissing(report) - } - - val scala2122 = Some("2.12.2") - it should "exclude a concrete version of lift-json when it's full cross version" in { - val excluded: ModuleID = ("org.scalameta" % "scalahost" % "1.7.0").cross(CrossVersion.full) - val report = getIvyReport(createMetaDep(excluded), scala2122) - testScalahostIsMissing(report) - } - - it should "exclude any version of lift-json when it's full cross version" in { - val excluded = new OrganizationArtifactName("net.liftweb", "lift-json", CrossVersion.full) - val report = getIvyReport(createMetaDep(excluded), scala2122) - testScalahostIsMissing(report) - } - - it should "exclude any version of scala-library via * artifact id" in { - val toExclude = ExclusionRule("org.scala-lang", "*") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testScalaLibraryIsMissing(report) - } - - it should "exclude any version of scala-library via * org id" in { - val toExclude = ExclusionRule("*", "scala-library") - val report = getIvyReport(createLiftDep(toExclude), scala210) - testScalaLibraryIsMissing(report) - } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala index 8ba690221..db9344070 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala @@ -1,23 +1,26 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ +import verify.BasicTestSuite // This is a specification to check the inconsistent duplicate warnings -class InconsistentDuplicateSpec extends UnitSpec { - "Duplicate with different version" should "be warned" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) shouldBe - List( - "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", - " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)" - ) +object InconsistentDuplicateSpec extends BasicTestSuite { + test("Duplicate with different version should be warned") { + assert( + IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230)) == + List( + "Multiple dependencies with the same organization/name but different versions. To avoid conflict, pick one version:", + " * com.typesafe.akka:akka-actor:(2.1.4, 2.3.0)" + ) + ) } - it should "not be warned if in different configurations" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230Test)) shouldBe Nil + test("it should not be warned if in different configurations") { + assert(IvySbt.inconsistentDuplicateWarning(Seq(akkaActor214, akkaActor230Test)) == Nil) } - "Duplicate with same version" should "not be warned" in { - IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) shouldBe Nil + test("Duplicate with same version should not be warned") { + assert(IvySbt.inconsistentDuplicateWarning(Seq(akkaActor230Test, akkaActor230)) == Nil) } def akkaActor214 = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 468b9fef6..97515d9ef 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -5,7 +5,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ import InternalDefaults._ -class IvyRepoSpec extends BaseIvySpecification { +object IvyRepoSpec extends BaseIvySpecification { val ourModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) @@ -21,7 +21,9 @@ class IvyRepoSpec extends BaseIvySpecification { ) } - "ivyUpdate from ivy repository" should "resolve only binary artifact from module which also contains a sources artifact under the same configuration." in { + test( + "ivyUpdate from ivy repository should resolve only binary artifact from module which also contains a sources artifact under the same configuration." + ) { cleanIvyCache() val m = makeModuleForDepWithSources @@ -33,13 +35,15 @@ class IvyRepoSpec extends BaseIvySpecification { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => - ar.`type` shouldBe "jar" - ar.extension shouldBe "jar" + assert(ar.`type` == "jar") + assert(ar.extension == "jar") } } } - it should "resolve only sources artifact of an acceptable artifact type, \"src\", when calling updateClassifiers." in { + test( + "it should resolve only sources artifact of an acceptable artifact type, \"src\", when calling updateClassifiers." + ) { cleanIvyCache() val m = makeModuleForDepWithSources @@ -90,9 +94,9 @@ class IvyRepoSpec extends BaseIvySpecification { case Some(Seq(mr)) => inside(mr.artifacts) { case Seq((ar, _)) => - ar.name shouldBe "libmodule-source" - ar.`type` shouldBe "src" - ar.extension shouldBe "jar" + assert(ar.name == "libmodule-source") + assert(ar.`type` == "src") + assert(ar.extension == "jar") } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala index 886b2018e..30c36e093 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala @@ -1,79 +1,87 @@ package sbt.internal.librarymanagement import sbt.internal.util.ConsoleLogger +import verify.BasicTestSuite // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html // http://maven.apache.org/enforcer/enforcer-rules/versionRanges.html -class MakePomSpec extends UnitSpec { +object MakePomSpec extends BasicTestSuite { // This is a specification to check the Ivy revision number conversion to pom. - "1.0" should "convert to 1.0" in convertTo("1.0", "1.0") + test("1.0 should convert to 1.0") { + convertTo("1.0", "1.0") + } - "[1.0,2.0]" should "convert to [1.0,2.0]" in { + test("[1.0,2.0] should convert to [1.0,2.0]") { convertTo("[1.0,2.0]", "[1.0,2.0]") } - "[1.0,2.0[" should "convert to [1.0,2.0)" in { + test("[1.0,2.0[ should convert to [1.0,2.0)") { convertTo("[1.0,2.0[", "[1.0,2.0)") } - "]1.0,2.0]" should "convert to (1.0,2.0]" in { + test("]1.0,2.0] should convert to (1.0,2.0]") { convertTo("]1.0,2.0]", "(1.0,2.0]") } - "]1.0,2.0[" should "convert to (1.0,2.0)" in { + test("]1.0,2.0[ should convert to (1.0,2.0)") { convertTo("]1.0,2.0[", "(1.0,2.0)") } - "[1.0,)" should "convert to [1.0,)" in { + test("[1.0,) should convert to [1.0,)") { convertTo("[1.0,)", "[1.0,)") } - "]1.0,)" should "convert to (1.0,)" in { + test("]1.0,) should convert to (1.0,)") { convertTo("]1.0,)", "(1.0,)") } - "(,2.0]" should "convert to (,2.0]" in { + test("(,2.0] should convert to (,2.0]") { convertTo("(,2.0]", "(,2.0]") } - "(,2.0[" should "convert to (,2.0)" in { + test("(,2.0[ should convert to (,2.0)") { convertTo("(,2.0[", "(,2.0)") } - "1.+" should "convert to [1,2)" in { + test("1.+ should convert to [1,2)") { convertTo("1.+", "[1,2)") } - "1.2.3.4.+" should "convert to [1.2.3.4,1.2.3.5)" in { + test("1.2.3.4.+ should convert to [1.2.3.4,1.2.3.5)") { convertTo("1.2.3.4.+", "[1.2.3.4,1.2.3.5)") } - "12.31.42.+" should "convert to [12.31.42,12.31.43)" in { + test("12.31.42.+ should convert to [12.31.42,12.31.43)") { convertTo("12.31.42.+", "[12.31.42,12.31.43)") } - "1.1+" should "convert to [1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)" in { + test( + "1.1+ should convert to [1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)" + ) { convertTo("1.1+", "[1.1,1.2),[1.10,1.20),[1.100,1.200),[1.1000,1.2000),[1.10000,1.20000)") } - "1+" should "convert to [1,2),[10,20),[100,200),[1000,2000),[10000,20000)" in { + test("1+ should convert to [1,2),[10,20),[100,200),[1000,2000),[10000,20000)") { convertTo("1+", "[1,2),[10,20),[100,200),[1000,2000),[10000,20000)") } - "+" should "convert to [0,)" in convertTo("+", "[0,)") + test("+ should convert to [0,)") { + convertTo("+", "[0,)") + } - "foo+" should "convert to foo+" in beParsedAsError("foo+") + test("foo+ should convert to foo+") { + beParsedAsError("foo+") + } val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String): Unit = { - MakePom.makeDependencyVersion(s) shouldBe expected - () + assert(MakePom.makeDependencyVersion(s) == expected) } def beParsedAsError(s: String): Unit = { intercept[Throwable] { MakePom.makeDependencyVersion(s) + () } - () } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index 7ef540583..e9e133d4c 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -7,7 +7,7 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ import sbt.io.IO -class ManagedChecksumsSpec extends BaseIvySpecification { +object ManagedChecksumsSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def warningConf = UnresolvedWarningConfiguration() @@ -47,7 +47,7 @@ class ManagedChecksumsSpec extends BaseIvySpecification { assert(shaFile.exists(), s"The checksum $Checksum for $file does not exist") } - "Managed checksums" should "should download the checksum files" in { + test("Managed checksums should should download the checksum files") { cleanAll() val updateOptions = UpdateOptions() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala index ded1a9f15..898402224 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala @@ -5,8 +5,8 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions import sbt.internal.librarymanagement.ivyint._ -class MergeDescriptorSpec extends BaseIvySpecification { - "Merging duplicate dependencies" should "work" in { +object MergeDescriptorSpec extends BaseIvySpecification { + test("Merging duplicate dependencies should work") { cleanIvyCache() val m = module( ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")), @@ -25,8 +25,8 @@ class MergeDescriptorSpec extends BaseIvySpecification { val a1: DependencyArtifactDescriptor = arts.toList(1) val configs0 = a0.getConfigurations.toList val configs1 = a1.getConfigurations.toList - configs0 shouldEqual List("compile") - configs1 shouldEqual List("test") + assert(configs0 == List("compile")) + assert(configs1 == List("test")) } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index 8519a6d95..d1b06b242 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -5,7 +5,7 @@ import sbt.librarymanagement.syntax._ import sbt.librarymanagement.ivy.UpdateOptions import Resolver._ -class ModuleResolversTest extends BaseIvySpecification { +object ModuleResolversTest extends BaseIvySpecification { override final val resolvers = Vector( DefaultMavenRepository, JavaNet2Repository, @@ -20,7 +20,7 @@ class ModuleResolversTest extends BaseIvySpecification { "com.jfrog.bintray.client" % "bintray-client-java-api" % "0.9.2" % "compile" ).map(_.withIsTransitive(false)) - "The direct resolvers in update options" should "skip the rest of resolvers" in { + test("The direct resolvers in update options should skip the rest of resolvers") { cleanIvyCache() val updateOptions = UpdateOptions() val ivyModule = module(stubModule, dependencies, None, updateOptions) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala index 028c2b0b3..5044be951 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala @@ -2,10 +2,9 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.ivy.UpdateOptions -import org.scalatest.{ Assertion, DiagrammedAssertions } import sbt.io.IO -class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { +object OfflineModeSpec extends BaseIvySpecification { private final def targetDir = Some(currentDependency) private final def onlineConf = makeUpdateConfiguration(false, targetDir) private final def offlineConf = makeUpdateConfiguration(true, targetDir) @@ -26,7 +25,7 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { IO.delete(currentDependency) } - def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Assertion = { + def checkOnlineAndOfflineResolution(updateOptions: UpdateOptions): Unit = { cleanAll() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) @@ -46,15 +45,15 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { assert(originalResolveTime > resolveTime) } - "Offline update configuration" should "reuse the caches when offline is enabled" in { + test("Offline update configuration should reuse the caches when offline is enabled") { checkOnlineAndOfflineResolution(normalOptions) } - it should "reuse the caches when offline and cached resolution are enabled" in { + test("it should reuse the caches when offline and cached resolution are enabled") { checkOnlineAndOfflineResolution(cachedOptions) } - def checkFailingResolution(updateOptions: UpdateOptions): Assertion = { + def checkFailingResolution(updateOptions: UpdateOptions): Unit = { cleanAll() val toResolve = module(defaultModuleId, dependencies, None, updateOptions) if (updateOptions.cachedResolution) cleanCachedResolutionCache(toResolve) @@ -63,11 +62,11 @@ class OfflineModeSpec extends BaseIvySpecification with DiagrammedAssertions { assert(failedOfflineResolution.isLeft) } - it should "fail when artifacts are missing in the cache" in { + test("it should fail when artifacts are missing in the cache") { checkFailingResolution(normalOptions) } - it should "fail when artifacts are missing in the cache for cached resolution" in { + test("it should fail when artifacts are missing in the cache for cached resolution") { checkFailingResolution(cachedOptions) } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala index 64afda27e..92cb9fa32 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala @@ -1,16 +1,18 @@ package sbttest import java.net.URL -import org.scalatest._ import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ +import verify.BasicTestSuite -class ResolverSpec extends FunSuite with DiagrammedAssertions { +class ResolverSpec extends BasicTestSuite { test("Resolver.url") { Resolver.url("Test Repo", new URL("http://example.com/"))(Resolver.ivyStylePatterns) + () } test("at") { "something" at "http://example.com" + () } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index 3dcfff33f..d9ed46cf3 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -6,8 +6,9 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor import sbt.internal.librarymanagement.IvyScalaUtil.OverrideScalaMediator import sbt.librarymanagement._ import sbt.librarymanagement.ScalaArtifacts._ +import verify.BasicTestSuite -class ScalaOverrideTest extends UnitSpec { +object ScalaOverrideTest extends BasicTestSuite { val OtherOrgID = "other.org" def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { @@ -21,85 +22,126 @@ class ScalaOverrideTest extends UnitSpec { dd.addDependencyConfiguration("compile", "compile") val res = osm.mediate(dd) - res.getDependencyRevisionId shouldBe ModuleRevisionId.newInstance(org0, name1, version0) + assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version0)) } - """OverrideScalaMediator - """ should "Override compiler version" in check(Organization, "2.11.8")( - Organization, - CompilerID, - "2.11.9" - ) - it should "Override library version" in check(Organization, "2.11.8")( - Organization, - LibraryID, - "2.11.8" - ) - it should "Override reflect version" in check(Organization, "2.11.8")( - Organization, - ReflectID, - "2.11.7" - ) - it should "Override actors version" in check(Organization, "2.11.8")( - Organization, - ActorsID, - "2.11.6" - ) - it should "Override scalap version" in check(Organization, "2.11.8")( - Organization, - ScalapID, - "2.11.5" - ) + test("""OverrideScalaMediator should override compiler version""") { + check(Organization, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + } - it should "Override default compiler organization" in check(OtherOrgID, "2.11.8")( - Organization, - CompilerID, - "2.11.9" - ) - it should "Override default library organization" in check(OtherOrgID, "2.11.8")( - Organization, - LibraryID, - "2.11.8" - ) - it should "Override default reflect organization" in check(OtherOrgID, "2.11.8")( - Organization, - ReflectID, - "2.11.7" - ) - it should "Override default actors organization" in check(OtherOrgID, "2.11.8")( - Organization, - ActorsID, - "2.11.6" - ) - it should "Override default scalap organization" in check(OtherOrgID, "2.11.8")( - Organization, - ScalapID, - "2.11.5" - ) + test("it should override library version") { + check(Organization, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + } - it should "Override custom compiler organization" in check(Organization, "2.11.8")( - OtherOrgID, - CompilerID, - "2.11.9" - ) - it should "Override custom library organization" in check(Organization, "2.11.8")( - OtherOrgID, - LibraryID, - "2.11.8" - ) - it should "Override custom reflect organization" in check(Organization, "2.11.8")( - OtherOrgID, - ReflectID, - "2.11.7" - ) - it should "Override custom actors organization" in check(Organization, "2.11.8")( - OtherOrgID, - ActorsID, - "2.11.6" - ) - it should "Override custom scalap organization" in check(Organization, "2.11.8")( - OtherOrgID, - ScalapID, - "2.11.5" - ) + test("it should override reflect version") { + check(Organization, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + } + + test("it should override actors version") { + check(Organization, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + } + + test("it should override scalap version") { + check(Organization, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) + } + + test("it should override default compiler organization") { + check(OtherOrgID, "2.11.8")( + Organization, + CompilerID, + "2.11.9" + ) + } + + test("it should override default library organization") { + check(OtherOrgID, "2.11.8")( + Organization, + LibraryID, + "2.11.8" + ) + } + + test("it should override default reflect organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ReflectID, + "2.11.7" + ) + } + + test("it should override default actors organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ActorsID, + "2.11.6" + ) + } + + test("it should override default scalap organization") { + check(OtherOrgID, "2.11.8")( + Organization, + ScalapID, + "2.11.5" + ) + } + + test("it should override custom compiler organization") { + check(Organization, "2.11.8")( + OtherOrgID, + CompilerID, + "2.11.9" + ) + } + + test("it should override custom library organization") { + check(Organization, "2.11.8")( + OtherOrgID, + LibraryID, + "2.11.8" + ) + } + + test("it should override custom reflect organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ReflectID, + "2.11.7" + ) + } + + test("it should override custom actors organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ActorsID, + "2.11.6" + ) + } + + test("it should override custom scalap organization") { + check(Organization, "2.11.8")( + OtherOrgID, + ScalapID, + "2.11.5" + ) + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala index 8da14644a..2bf13668d 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -10,7 +10,7 @@ import java.nio.file.Paths //by default this test is ignored //to run this you need to change "repo" to point to some sftp repository which contains a dependency referring a dependency in same repo //it will then attempt to authenticate via key file and fetch the dependency specified via "org" and "module" -class SftpRepoSpec extends BaseIvySpecification { +object SftpRepoSpec extends BaseIvySpecification { val repo: Option[String] = None // val repo: Option[String] = Some("some repo") //a dependency which depends on another in the repo @@ -25,7 +25,7 @@ class SftpRepoSpec extends BaseIvySpecification { }.toVector ++ super.resolvers } - "resolving multiple deps from sftp repo" should "not hang or fail" in { + test("resolving multiple deps from sftp repo should not hang or fail") { repo match { case Some(repo) => IO.delete(currentTarget / "cache" / org(repo)) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala index 9b7c9c126..5729bd06e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/UpdateOptionsSpec.scala @@ -1,24 +1,26 @@ package sbt.internal.librarymanagement import sbt.librarymanagement.ivy._ +import verify.BasicTestSuite -class UpdateOptionsSpec extends UnitSpec { - - "UpdateOptions" should "have proper toString defined" in { - UpdateOptions().toString() should be("""|UpdateOptions( +class UpdateOptionsSpec extends BasicTestSuite { + test("UpdateOptions should have proper toString defined") { + assert(UpdateOptions().toString() == """|UpdateOptions( | circularDependencyLevel = warn, | latestSnapshots = true, | cachedResolution = false |)""".stripMargin) - UpdateOptions() - .withCircularDependencyLevel(CircularDependencyLevel.Error) - .withCachedResolution(true) - .withLatestSnapshots(false) - .toString() should be("""|UpdateOptions( + assert( + UpdateOptions() + .withCircularDependencyLevel(CircularDependencyLevel.Error) + .withCachedResolution(true) + .withLatestSnapshots(false) + .toString() == """|UpdateOptions( | circularDependencyLevel = error, | latestSnapshots = false, | cachedResolution = true - |)""".stripMargin) + |)""".stripMargin + ) } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d9a1e088a..b321b2cbb 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -51,6 +51,7 @@ object Dependencies { val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" val scalaTest = "org.scalatest" %% "scalatest" % "3.0.6-SNAP5" + val scalaVerify = "com.eed3si9n.verify" %% "verify" % "0.1.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value From a9873101bf4290c48de3e8008545ada22155b9f1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 17 Aug 2019 22:17:58 -0400 Subject: [PATCH 0851/1030] Fix validatePatterns https://github.com/sbt/librarymanagement/pull/312 had a bug. --- .../scala/sbt/librarymanagement/ResolverExtra.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d1d435014..835445ec1 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -417,9 +417,15 @@ private[librarymanagement] abstract class ResolverFunctions { log.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS") } private[sbt] def validatePatterns(patterns: Patterns): Unit = { - val ivy = patterns.ivyPatterns.headOption map (_.startsWith("http:")) - val art = patterns.artifactPatterns.headOption map (_.startsWith("http:")) - (ivy orElse art) foreach { _ => + val ivy = patterns.ivyPatterns.headOption match { + case Some(x) => x.startsWith("http:") + case _ => false + } + val art = patterns.artifactPatterns.headOption match { + case Some(x) => x.startsWith("http:") + case _ => false + } + if (ivy || art) { warnHttp(patterns.toString) } } From cc6147c8d2f8523e86e45f503c1fbdad982c0c1d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 17 Aug 2019 23:06:52 -0400 Subject: [PATCH 0852/1030] Remove lmCommonTest --- build.sbt | 24 +++++++------------ .../AbstractEngineSpec.scala | 0 .../librarymanagement/ResolutionSpec.scala | 0 3 files changed, 9 insertions(+), 15 deletions(-) rename {common-test/src/main => ivy/src/test}/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala (100%) rename {common-test/src/main => ivy/src/test}/scala/sbt/internal/librarymanagement/ResolutionSpec.scala (100%) diff --git a/build.sbt b/build.sbt index 923df2598..1c06bbb25 100644 --- a/build.sbt +++ b/build.sbt @@ -98,6 +98,7 @@ lazy val lmCore = (project in file("core")) sjsonnewScalaJson.value % Optional, scalaTest % Test, scalaCheck % Test, + scalaVerify % Test, ), libraryDependencies += scalaXml, resourceGenerators in Compile += Def @@ -217,25 +218,18 @@ lazy val lmCore = (project in file("core")) ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) -lazy val lmCommonTest = (project in file("common-test")) +lazy val lmIvy = (project in file("ivy")) + .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .dependsOn(lmCore) - .settings( - commonSettings, - skip in publish := true, - name := "common-test", - libraryDependencies ++= Seq(scalaTest, scalaCheck, scalaVerify), - scalacOptions in (Compile, console) --= - Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), - mimaSettings, - ) - -lazy val lmIvy = (project in file("ivy")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) - .dependsOn(lmCore, lmCommonTest % Test) .settings( commonSettings, name := "librarymanagement-ivy", - libraryDependencies ++= Seq(ivy), + libraryDependencies ++= Seq( + ivy, + scalaTest % Test, + scalaCheck % Test, + scalaVerify % Test, + ), managedSourceDirectories in Compile += baseDirectory.value / "src" / "main" / "contraband-scala", sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala similarity index 100% rename from common-test/src/main/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/AbstractEngineSpec.scala diff --git a/common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala similarity index 100% rename from common-test/src/main/scala/sbt/internal/librarymanagement/ResolutionSpec.scala rename to ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala From 153ac7161df5baf5ae8a2a625cd463bb25774540 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 18 Aug 2019 23:56:20 -0400 Subject: [PATCH 0853/1030] bump modules --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b321b2cbb..e36f10fba 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,8 +7,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.3.0-M10") - private val utilVersion = nightlyVersion.getOrElse("1.3.0-M7") + private val ioVersion = nightlyVersion.getOrElse("1.3.0-M16") + private val utilVersion = nightlyVersion.getOrElse("1.3.0-M9") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From c22cb34e7b3f4cf0fad9edca8d191af561c2cad2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 22 Aug 2019 01:54:14 -0400 Subject: [PATCH 0854/1030] Make CrossVersion.Disabled stable Fixes https://github.com/sbt/sbt/issues/4975 This makes `CrossVersion.Disabled` a stable identifier by reverting `final def` back to `final val`. This is to fix Scala.JS build ``` [error] ScalaJSCrossVersion.scala:34:23: stable identifier required, but sbt.`package`.CrossVersion.Disabled found. [error] case CrossVersion.Disabled => [error] ^ [error] one error found [error] (Compile / compileIncremental) Compilation failed ``` ### notes - #121 added `final val Disabled = sbt.librarymanagement.Disabled` but it was just a companion object - #280 actually made it `final val Disabled = sbt.librarymanagement.Disabled()`, but this broke Cat's build that was calling `CrossVersion.Disabled()` - #290 changed to `final def Disabled = sbt.librarymanagement.Disabled` and `object Disabled extends sbt.librarymanagement.Disabled` - This changes back to `final val Disabled = sbt.librarymanagement.Disabled` (but because we changed the companion object in #290 that's ok) --- .../sbt/librarymanagement/CrossVersion.scala | 2 +- .../librarymanagement/CrossVersionExtra.scala | 2 +- .../tests/CrossVersionCompatTest.scala | 70 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 core/src/test/scala/example/tests/CrossVersionCompatTest.scala diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 6c37596b3..19e712981 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -39,7 +39,7 @@ sealed class Disabled private () extends sbt.librarymanagement.CrossVersion() wi } object Disabled extends sbt.librarymanagement.Disabled { - def apply(): Disabled = new Disabled() + def apply(): Disabled = Disabled } /** diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index d8e54d8c8..4db8c7516 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -8,7 +8,7 @@ final case class ScalaVersion(full: String, binary: String) private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ - final def Disabled = sbt.librarymanagement.Disabled + final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full diff --git a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala new file mode 100644 index 000000000..11eaa54ea --- /dev/null +++ b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala @@ -0,0 +1,70 @@ +package example.tests + +import sbt.librarymanagement.{ CrossVersion, Disabled } +import verify.BasicTestSuite + +object CrossVersionCompatTest extends BasicTestSuite { + test("CrossVersion.Disabled is typed to be Disabled") { + assert(CrossVersion.Disabled match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.Disabled functions as disabled") { + assert(CrossVersion(CrossVersion.disabled, "1.0.0", "1.0") == None) + assert(CrossVersion(CrossVersion.Disabled, "1.0.0", "1.0") == None) + } + + test("CrossVersion.Disabled() is typed to be Disabled") { + assert(CrossVersion.Disabled() match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.Disabled() functions as disabled") { + assert(CrossVersion(CrossVersion.disabled, "1.0.0", "1.0") == None) + assert(CrossVersion(CrossVersion.Disabled(), "1.0.0", "1.0") == None) + } + + test("CrossVersion.Disabled is stable") { + assert(CrossVersion.Disabled match { + case CrossVersion.Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled is typed to be Disabled") { + assert(Disabled match { + case _: Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled is stable") { + assert(Disabled match { + case Disabled => true + case _ => false + }) + } + + test("sbt.librarymanagement.Disabled() is typed to be Disabled") { + assert(Disabled() match { + case _: Disabled => true + case _ => false + }) + } + + test("CrossVersion.disabled is sbt.librarymanagement.Disabled") { + assert(CrossVersion.disabled == Disabled) + } + + test("CrossVersion.Disabled is sbt.librarymanagement.Disabled") { + assert(CrossVersion.Disabled == Disabled) + } + + test("CrossVersion.Disabled() is sbt.librarymanagement.Disabled") { + assert(CrossVersion.Disabled() == Disabled) + } +} From 4a1b6232e44216b244ab116e2fb9d4550e660597 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 22 Aug 2019 10:33:11 -0400 Subject: [PATCH 0855/1030] deprecate CrossVersion.Disabled --- build.sbt | 4 ++++ .../scala/sbt/librarymanagement/CrossVersionExtra.scala | 6 +++++- .../test/scala/example/tests/CrossVersionCompatTest.scala | 2 ++ project/Dependencies.scala | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 1c06bbb25..b6804e2e4 100644 --- a/build.sbt +++ b/build.sbt @@ -100,6 +100,10 @@ lazy val lmCore = (project in file("core")) scalaCheck % Test, scalaVerify % Test, ), + libraryDependencies ++= (scalaVersion.value match { + case v if v.startsWith("2.12.") => List(compilerPlugin(silencerPlugin)) + case _ => List() + }), libraryDependencies += scalaXml, resourceGenerators in Compile += Def .task( diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 4db8c7516..43a46073f 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -8,6 +8,10 @@ final case class ScalaVersion(full: String, binary: String) private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ + @deprecated( + "use CrossVersion.disabled instead. prior to sbt 1.3.0, Diabled did not work without apply(). sbt/sbt#4977", + "1.3.0" + ) final val Disabled = sbt.librarymanagement.Disabled final val Binary = sbt.librarymanagement.Binary final val Constant = sbt.librarymanagement.Constant @@ -37,7 +41,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ - def disabled: CrossVersion = Disabled + def disabled: CrossVersion = sbt.librarymanagement.Disabled /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) diff --git a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala index 11eaa54ea..8aa136e8c 100644 --- a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala +++ b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala @@ -2,7 +2,9 @@ package example.tests import sbt.librarymanagement.{ CrossVersion, Disabled } import verify.BasicTestSuite +import com.github.ghik.silencer.silent +@silent object CrossVersionCompatTest extends BasicTestSuite { test("CrossVersion.Disabled is typed to be Disabled") { assert(CrossVersion.Disabled match { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e36f10fba..a6cf0fdef 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -61,4 +61,5 @@ object Dependencies { } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" + val silencerPlugin = "com.github.ghik" %% "silencer-plugin" % "1.4.1" } From d0ce65378c2cb4cba75393a2a01fce7b2434af38 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Aug 2019 17:18:05 -0400 Subject: [PATCH 0856/1030] Refactor system properties lookup --- .../librarymanagement/LMSysProp.scala | 58 +++++++++++++++++++ .../sbt/librarymanagement/ResolverExtra.scala | 3 +- .../librarymanagement/CustomPomParser.scala | 5 +- .../ivyint/ErrorMessageAuthenticator.scala | 12 +--- .../librarymanagement/ivy/UpdateOptions.scala | 3 +- 5 files changed, 64 insertions(+), 17 deletions(-) create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala new file mode 100644 index 000000000..1fe46916f --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -0,0 +1,58 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package internal +package librarymanagement + +import java.util.Locale + +object LMSysProp { + def booleanOpt(name: String): Option[Boolean] = + sys.props.get(name).flatMap { x => + x.toLowerCase(Locale.ENGLISH) match { + case "1" | "always" | "true" => Some(true) + case "0" | "never" | "false" => Some(false) + case "auto" => None + case _ => None + } + } + + def getOrFalse(name: String): Boolean = booleanOpt(name).getOrElse(false) + def getOrTrue(name: String): Boolean = booleanOpt(name).getOrElse(true) + + // System property style: + // 1. use sbt. prefix + // 2. prefer short nouns + // 3. use dot for namespacing, and avoid making dot-separated English phrase + // 4. make active/enable properties, instead of "sbt.disable." + // + // Good: sbt.offline + // + // Bad: + // sbt.disable.interface.classloader.cache + // sbt.task.timings.on.shutdown + // sbt.skip.version.write -> sbt.genbuildprops=false + + val useSecureResolvers: Boolean = getOrTrue("sbt.repository.secure") + + def modifyVersionRange: Boolean = getOrTrue("sbt.modversionrange") + + lazy val isJavaVersion9Plus: Boolean = javaVersion > 8 + lazy val javaVersion: Int = { + // See Oracle section 1.5.3 at: + // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html + val version = sys.props("java.specification.version").split("\\.").toList.map(_.toInt) + version match { + case 1 :: minor :: _ => minor + case major :: _ => major + case _ => 0 + } + } + + lazy val useGigahorse: Boolean = getOrTrue("sbt.gigahorse") +} diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 835445ec1..d45166997 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -95,8 +95,7 @@ private[sbt] class FakeRepository(resolver: AnyRef, name: String) extends xsbti. } private[librarymanagement] abstract class ResolverFunctions { - private[sbt] def useSecureResolvers = - sys.props.get("sbt.repository.secure") map { _.toLowerCase == "true" } getOrElse true + import sbt.internal.librarymanagement.LMSysProp.useSecureResolvers val TypesafeRepositoryRoot = typesafeRepositoryRoot(useSecureResolvers) val SbtRepositoryRoot = sbtRepositoryRoot(useSecureResolvers) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index c906fc818..591e3e881 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -242,9 +242,6 @@ object CustomPomParser { transform(dd, _ => newId) case None => dd } - private[sbt] lazy val versionRangeFlag = sys.props.get("sbt.modversionrange") map { - _.toLowerCase == "true" - } getOrElse true import collection.JavaConverters._ def addExtra( @@ -281,7 +278,7 @@ object CustomPomParser { addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = - if (versionRangeFlag) withExtra map { stripVersionRange } else withExtra + if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 1e842c458..2ba03b741 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -15,7 +15,8 @@ object ErrorMessageAuthenticator { private var securityWarningLogged = false private def originalAuthenticator: Option[Authenticator] = { - if (isJavaVersion9Plus) getDefaultAuthenticator else getTheAuthenticator + if (LMSysProp.isJavaVersion9Plus) getDefaultAuthenticator + else getTheAuthenticator } private[this] def getTheAuthenticator: Option[Authenticator] = { @@ -100,15 +101,6 @@ object ErrorMessageAuthenticator { } doInstallIfIvy(originalAuthenticator) } - - private[this] def isJavaVersion9Plus = javaVersion > 8 - private[this] def javaVersion = { - // See Oracle section 1.5.3 at: - // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html - val version = sys.props("java.specification.version").split("\\.").map(_.toInt) - if (version(0) == 1) version(1) else version(0) - } - } /** diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 6f12ba053..1ac339eec 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -4,6 +4,7 @@ package ivy import org.apache.ivy.plugins.resolver.DependencyResolver import org.apache.ivy.core.settings.IvySettings import sbt.util.Logger +import sbt.internal.librarymanagement.LMSysProp /** * Represents configurable options for update task. @@ -109,7 +110,7 @@ object UpdateOptions { interProjectFirst = true, latestSnapshots = true, cachedResolution = false, - gigahorse = sys.props.get("sbt.gigahorse") map { _.toLowerCase == "true" } getOrElse true, + gigahorse = LMSysProp.useGigahorse, resolverConverter = PartialFunction.empty, moduleResolvers = Map.empty ) From c5ce6363764b4256e2d70e470634d8e75fc2f565 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Aug 2019 17:47:32 -0400 Subject: [PATCH 0857/1030] Flip the default to not use Gigahorse by default Fixes https://github.com/sbt/sbt/issues/3570 The primary motivation for bringing in Gigahorse was to speed up the dependency resolution, especially in a high-latency environment like Australia, by enabling keep-alive. One of unintended consequences was that it ended up exposing either a bug in okhttp or Nexus / Artifactory's handling of keep-alive, since corporate users behind these proxy repositories started to experience problem publishing. Multiple people have also reported that putting network proxies like HAProxy works around this issue, which seems consistent with the theory. Now that dependency resolution has switched to using Coursier by default, I am just going to flip the default here so publishing would use Ivy's default URL handler based on `java.net.HttpURLConnection` - https://github.com/sbt/ivy/blob/5681e1a77a149b93a4cfbe4a86d0263d7bd223eb/src/java/org/apache/ivy/util/url/BasicURLHandler.java --- .../main/scala/sbt/internal/librarymanagement/LMSysProp.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala index 1fe46916f..15bb4a9e5 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -54,5 +54,5 @@ object LMSysProp { } } - lazy val useGigahorse: Boolean = getOrTrue("sbt.gigahorse") + lazy val useGigahorse: Boolean = getOrFalse("sbt.gigahorse") } From 54806467156f00b520c90c50ef07591693e6de6f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Aug 2019 17:51:19 -0400 Subject: [PATCH 0858/1030] pass in Locale toLowerCase would act differently in Turkey. --- .../librarymanagement/SemanticSelectorExtra.scala | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index c609a1529..f3f28cf7a 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -4,6 +4,7 @@ import sbt.librarymanagement.VersionNumber import sbt.internal.librarymanagement.SemSelOperator.{ Lt, Lte, Gt, Gte, Eq } import scala.annotation.tailrec +import java.util.Locale private[librarymanagement] abstract class SemSelAndChunkFunctions { protected def parse(andClauseToken: String): SemSelAndChunk = { @@ -123,10 +124,11 @@ private[librarymanagement] abstract class SemComparatorExtra { // Identifiers consisting of only digits are compared numerically. // Numeric identifiers always have lower precedence than non-numeric identifiers. // Identifiers with letters are compared case insensitive lexical order. - case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) - case (false, true) => 1 - case (true, false) => -1 - case (false, false) => ts1head.toLowerCase.compareTo(ts2head.toLowerCase) + case (true, true) => implicitly[Ordering[Long]].compare(ts1head.toLong, ts2head.toLong) + case (false, true) => 1 + case (true, false) => -1 + case (false, false) => + ts1head.toLowerCase(Locale.ENGLISH).compareTo(ts2head.toLowerCase(Locale.ENGLISH)) } if (cmp == 0) compareTags(ts1.tail, ts2.tail) else cmp From 40598cc5a47d298ed3688e95a86f5fbecceb4663 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Aug 2019 18:50:17 -0400 Subject: [PATCH 0859/1030] mima + scalafmt --- build.sbt | 163 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 111 insertions(+), 52 deletions(-) diff --git a/build.sbt b/build.sbt index b6804e2e4..2ed58e87d 100644 --- a/build.sbt +++ b/build.sbt @@ -42,7 +42,9 @@ def commonSettings: Seq[Setting[_]] = Def.settings( case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") } }, - inCompileAndTest(scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint")), + inCompileAndTest( + scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") + ), scalafmtOnCompile := true, Test / scalafmtOnCompile := true, publishArtifact in Compile := true, @@ -52,13 +54,22 @@ def commonSettings: Seq[Setting[_]] = Def.settings( val mimaSettings = Def settings ( mimaPreviousArtifacts := Set( - "1.0.0", "1.0.1", "1.0.2", "1.0.3", "1.0.4", - "1.1.0", "1.1.1", "1.1.2", "1.1.3", "1.1.4", + "1.0.0", + "1.0.1", + "1.0.2", + "1.0.3", + "1.0.4", + "1.1.0", + "1.1.1", + "1.1.2", + "1.1.3", + "1.1.4", "1.2.0", - ) map (version => - organization.value %% moduleName.value % version - cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) - ), + ) map ( + version => + organization.value %% moduleName.value % version + cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) + ), ) lazy val lmRoot = (project in file(".")) @@ -73,7 +84,8 @@ lazy val lmRoot = (project in file(".")) Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) }, bintrayPackage := "librarymanagement", - )), + ) + ), commonSettings, name := "LM Root", publish := {}, @@ -134,33 +146,32 @@ lazy val lmCore = (project in file("core")) mimaBinaryIssueFilters ++= Seq( exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.this"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.EvictionWarningOptions.copy"), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.EvictionWarningOptions.copy$default$7"), - + exclude[IncompatibleResultTypeProblem]( + "sbt.librarymanagement.EvictionWarningOptions.copy$default$7" + ), // internal class moved exclude[MissingClassProblem]("sbt.internal.librarymanagement.InlineConfigurationFunctions"), // dropped internal class parent (InlineConfigurationFunctions) exclude[MissingTypesProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration$"), - // Configuration's copy method was never meant to be public exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Configuration.copy$default$*"), - // the data type copy methods were never meant to be public exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.copy$default$*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.copy$default$*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.copy$default$*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ArtifactTypeFilterExtra.copy$default$*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.copy$default$*"), - // these abstract classes are private[librarymanagement] so it's fine if they have more methods exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleReportExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.*"), exclude[ReversedMissingMethodProblem]("sbt.librarymanagement.ModuleIDExtra.*"), - // these abstract classes are private[librarymanagement] so they can lose these abstract methods exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.type"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.url"), @@ -170,9 +181,10 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.classifier"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactExtra.extension"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilterExtra.types"), - // contraband issue - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ConfigurationReportLite.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ConfigurationReportLite.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.UpdateReportLite.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Artifact.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ArtifactTypeFilter.copy*"), @@ -189,7 +201,9 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.FileRepository.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.Full.copy*"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.GetClassifiersConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.GetClassifiersModule.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.InclExclRule.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.IvyFileConfiguration.copy*"), @@ -198,7 +212,9 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenCache.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.MavenRepo.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleConfiguration.copy*"), - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleDescriptorConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ModuleDescriptorConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleID.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleInfo.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ModuleReport.copy*"), @@ -218,6 +234,10 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateReport.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.UpdateStats.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.URLRepository.copy*"), + // private[sbt] + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ResolverFunctions.useSecureResolvers" + ), ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -242,33 +262,68 @@ lazy val lmIvy = (project in file("ivy")) Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, mimaBinaryIssueFilters ++= Seq( - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), - + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[IncompatibleMethTypeProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode" + ), // sbt.internal methods that changed type signatures and aren't used elsewhere in production code - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt#ParallelCachedResolutionResolveEngine.mergeErrors"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.cleanCachedResolutionCache"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvySbt#ParallelCachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvySbt.cleanCachedResolutionCache" + ), exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyRetrieve.artifacts"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvyScalaUtil.checkModule"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptor"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptors"), - exclude[ReversedMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors"), - - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[IncompatibleMethTypeProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode"), - + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.IvyScalaUtil.checkModule" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptor" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveCache.buildArtificialModuleDescriptors" + ), + exclude[ReversedMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.CachedResolutionResolveEngine.mergeErrors" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[IncompatibleMethTypeProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.checkStatusCode" + ), // contraband issue - exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ivy.ExternalIvyConfiguration.copy*" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.InlineIvyConfiguration.copy*"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPaths.copy*"), - - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.urlFactory"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.http"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.open"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.this"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.urlFactory" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.http" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.open" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler.this" + ), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.CustomPomParser.versionRangeFlag" + ), ), ) @@ -278,11 +333,13 @@ lazy val lmScriptedTest = (project in file("scripted-test")) commonSettings, skip in publish := true, name := "scripted-test", - scriptedLaunchOpts := { scriptedLaunchOpts.value ++ - Seq("-Xmx1024M", "-Dplugin.version=" + version.value) + scriptedLaunchOpts := { + scriptedLaunchOpts.value ++ + Seq("-Xmx1024M", "-Dplugin.version=" + version.value) }, scriptedBufferLog := false - ).enablePlugins(SbtScriptedIT) + ) + .enablePlugins(SbtScriptedIT) // we are updating the nightly process, so we are commenting this out for now // addCommandAlias("scriptedIvy", Seq( @@ -303,14 +360,16 @@ def customCommands: Seq[Setting[_]] = Seq( } ) -inThisBuild(Seq( - whitesourceProduct := "Lightbend Reactive Platform", - whitesourceAggregateProjectName := "sbt-lm-master", - whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", - whitesourceIgnoredScopes += "scalafmt", - whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present - whitesourceForceCheckAllDependencies := true, -)) +inThisBuild( + Seq( + whitesourceProduct := "Lightbend Reactive Platform", + whitesourceAggregateProjectName := "sbt-lm-master", + whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", + whitesourceIgnoredScopes += "scalafmt", + whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present + whitesourceForceCheckAllDependencies := true, + ) +) def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] = Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*))) From 7ad02276e90580b5fe87779570dcc4b373b158d3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 27 Aug 2019 23:37:45 -0400 Subject: [PATCH 0860/1030] adding try-catch per review --- .../librarymanagement/LMSysProp.scala | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala index 15bb4a9e5..d2a28d3eb 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -10,6 +10,7 @@ package internal package librarymanagement import java.util.Locale +import scala.util.control.NonFatal object LMSysProp { def booleanOpt(name: String): Option[Boolean] = @@ -40,17 +41,21 @@ object LMSysProp { val useSecureResolvers: Boolean = getOrTrue("sbt.repository.secure") - def modifyVersionRange: Boolean = getOrTrue("sbt.modversionrange") + lazy val modifyVersionRange: Boolean = getOrTrue("sbt.modversionrange") lazy val isJavaVersion9Plus: Boolean = javaVersion > 8 lazy val javaVersion: Int = { - // See Oracle section 1.5.3 at: - // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html - val version = sys.props("java.specification.version").split("\\.").toList.map(_.toInt) - version match { - case 1 :: minor :: _ => minor - case major :: _ => major - case _ => 0 + try { + // See Oracle section 1.5.3 at: + // https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html + val version = sys.props("java.specification.version").split("\\.").toList.map(_.toInt) + version match { + case 1 :: minor :: _ => minor + case major :: _ => major + case _ => 0 + } + } catch { + case NonFatal(_) => 0 } } From 337716830f7f34c2bc828788505c6833df8a6bc0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 28 Aug 2019 15:07:35 -0400 Subject: [PATCH 0861/1030] Deprecate HTTP resolvers (take 2) Ref https://github.com/sbt/sbt/issues/4905 Ref https://github.com/sbt/librarymanagement/pull/312 Based on the discussion in https://github.com/sbt/sbt/issues/4905, this will exempt localhost, and also allows per-resolver opt-in for HTTP. --- build.sbt | 3 + .../sbt/librarymanagement/Artifact.scala | 22 ++++-- .../librarymanagement/ArtifactFormats.scala | 4 +- .../librarymanagement/ChainedResolver.scala | 2 +- .../sbt/librarymanagement/MavenCache.scala | 3 +- .../sbt/librarymanagement/MavenRepo.scala | 23 ++++-- .../librarymanagement/MavenRepoFormats.scala | 4 +- .../librarymanagement/MavenRepository.scala | 6 ++ .../sbt/librarymanagement/Resolver.scala | 3 +- .../sbt/librarymanagement/URLRepository.scala | 21 +++-- .../URLRepositoryFormats.scala | 4 +- .../main/contraband/librarymanagement.json | 43 +++++++++-- .../sbt/librarymanagement/ArtifactExtra.scala | 8 +- .../DependencyBuilders.scala | 3 +- .../sbt/librarymanagement/ModuleIDExtra.scala | 52 ++++++++----- .../sbt/librarymanagement/ResolverExtra.scala | 77 +++++++++++++------ 16 files changed, 194 insertions(+), 84 deletions(-) diff --git a/build.sbt b/build.sbt index 2ed58e87d..25e1d9eab 100644 --- a/build.sbt +++ b/build.sbt @@ -238,6 +238,9 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]( "sbt.librarymanagement.ResolverFunctions.useSecureResolvers" ), + exclude[ReversedMissingMethodProblem]( + "sbt.librarymanagement.MavenRepository.allowInsecureProtocol" + ) ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index d337cb364..9cae77dca 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -12,22 +12,24 @@ final class Artifact private ( val configurations: Vector[sbt.librarymanagement.ConfigRef], val url: Option[java.net.URL], val extraAttributes: Map[String, String], - val checksum: Option[sbt.librarymanagement.Checksum]) extends sbt.librarymanagement.ArtifactExtra with Serializable { - - private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None) + val checksum: Option[sbt.librarymanagement.Checksum], + val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { + private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger) + private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) + private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) override def equals(o: Any): Boolean = o match { - case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) + case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + allowInsecureProtocol.##) } override def toString: String = { - "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ")" + "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum): Artifact = { - new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { + new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } def withName(name: String): Artifact = { copy(name = name) @@ -53,9 +55,13 @@ final class Artifact private ( def withChecksum(checksum: Option[sbt.librarymanagement.Checksum]): Artifact = { copy(checksum = checksum) } + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): Artifact = { + copy(allowInsecureProtocol = allowInsecureProtocol) + } } object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name) def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 4dfc42b54..2c9b2a02d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -19,8 +19,9 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") + val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + sbt.librarymanagement.Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -35,6 +36,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n builder.addField("url", obj.url) builder.addField("extraAttributes", obj.extraAttributes) builder.addField("checksum", obj.checksum) + builder.addField("allowInsecureProtocol", obj.allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index d98e6d1cb..fa950e86b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class ChainedResolver private ( name: String, val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable { - + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger)) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index b1501e3d4..1ed824c7b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -14,7 +14,8 @@ final class MavenCache private ( localIfFile: Boolean, val rootFile: java.io.File) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile) - def isCache: Boolean = true + override def isCache: Boolean = true + override def allowInsecureProtocol: Boolean = false private def this(name: String, root: String, rootFile: java.io.File) = this(name, root, true, rootFile) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index b01c6d8a9..a23e1a225 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -4,25 +4,30 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement +/** This is the internal implementation of actual Maven Repository (as opposed to a file cache). */ final class MavenRepo private ( name: String, root: String, - localIfFile: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { - def isCache: Boolean = false - private def this(name: String, root: String) = this(name, root, true) + localIfFile: Boolean, + val _allowInsecureProtocol: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { + override def isCache: Boolean = false + override def allowInsecureProtocol: Boolean = _allowInsecureProtocol + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger) + private def this(name: String, root: String) = this(name, root, true, false) + private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false) override def equals(o: Any): Boolean = o match { - case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) + case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) && (this._allowInsecureProtocol == x._allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) + 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) + _allowInsecureProtocol.##) } override def toString: String = { s"$name: $root" } - private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile): MavenRepo = { - new MavenRepo(name, root, localIfFile) + private[this] def copy(name: String = name, root: String = root, localIfFile: Boolean = localIfFile, _allowInsecureProtocol: Boolean = _allowInsecureProtocol): MavenRepo = { + new MavenRepo(name, root, localIfFile, _allowInsecureProtocol) } def withName(name: String): MavenRepo = { copy(name = name) @@ -33,9 +38,13 @@ final class MavenRepo private ( def withLocalIfFile(localIfFile: Boolean): MavenRepo = { copy(localIfFile = localIfFile) } + def with_allowInsecureProtocol(_allowInsecureProtocol: Boolean): MavenRepo = { + copy(_allowInsecureProtocol = _allowInsecureProtocol) + } } object MavenRepo { def apply(name: String, root: String): MavenRepo = new MavenRepo(name, root) def apply(name: String, root: String, localIfFile: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile) + def apply(name: String, root: String, localIfFile: Boolean, _allowInsecureProtocol: Boolean): MavenRepo = new MavenRepo(name, root, localIfFile, _allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala index 235de9643..e4c979985 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala @@ -14,8 +14,9 @@ implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = val name = unbuilder.readField[String]("name") val root = unbuilder.readField[String]("root") val localIfFile = unbuilder.readField[Boolean]("localIfFile") + val _allowInsecureProtocol = unbuilder.readField[Boolean]("_allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.MavenRepo(name, root, localIfFile) + sbt.librarymanagement.MavenRepo(name, root, localIfFile, _allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -25,6 +26,7 @@ implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = builder.addField("name", obj.name) builder.addField("root", obj.root) builder.addField("localIfFile", obj.localIfFile) + builder.addField("_allowInsecureProtocol", obj._allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala index f1bbb608c..3f891ef19 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -10,6 +10,12 @@ abstract class MavenRepository( val root: String, val localIfFile: Boolean) extends sbt.librarymanagement.Resolver(name) with Serializable { def isCache: Boolean + def allowInsecureProtocol: Boolean + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): MavenRepository = + this match { + case x: MavenRepo => x.with_allowInsecureProtocol(allowInsecureProtocol) + case x: MavenCache => x + } def this(name: String, root: String) = this(name, root, true) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index c6caf7eaf..448b04334 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -6,7 +6,8 @@ package sbt.librarymanagement abstract class Resolver( val name: String) extends Serializable { - + /** check for HTTP */ + private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = () diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index fc39dda73..9f0efa520 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -6,22 +6,23 @@ package sbt.librarymanagement final class URLRepository private ( name: String, - patterns: sbt.librarymanagement.Patterns) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { - Resolver.validatePatterns(patterns) - + patterns: sbt.librarymanagement.Patterns, + val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger) + private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false) override def equals(o: Any): Boolean = o match { - case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) + case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false } override def hashCode: Int = { - 37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) + 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) + allowInsecureProtocol.##) } override def toString: String = { - "URLRepository(" + name + ", " + patterns + ")" + "URLRepository(" + name + ", " + patterns + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns): URLRepository = { - new URLRepository(name, patterns) + private[this] def copy(name: String = name, patterns: sbt.librarymanagement.Patterns = patterns, allowInsecureProtocol: Boolean = allowInsecureProtocol): URLRepository = { + new URLRepository(name, patterns, allowInsecureProtocol) } def withName(name: String): URLRepository = { copy(name = name) @@ -29,8 +30,12 @@ final class URLRepository private ( def withPatterns(patterns: sbt.librarymanagement.Patterns): URLRepository = { copy(patterns = patterns) } + def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): URLRepository = { + copy(allowInsecureProtocol = allowInsecureProtocol) + } } object URLRepository { def apply(name: String, patterns: sbt.librarymanagement.Patterns): URLRepository = new URLRepository(name, patterns) + def apply(name: String, patterns: sbt.librarymanagement.Patterns, allowInsecureProtocol: Boolean): URLRepository = new URLRepository(name, patterns, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala index dbf9e9cfa..4ab1b23c8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala @@ -13,8 +13,9 @@ implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepos unbuilder.beginObject(js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") + val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") unbuilder.endObject() - sbt.librarymanagement.URLRepository(name, patterns) + sbt.librarymanagement.URLRepository(name, patterns, allowInsecureProtocol) case None => deserializationError("Expected JsObject but found None") } @@ -23,6 +24,7 @@ implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepos builder.beginObject() builder.addField("name", obj.name) builder.addField("patterns", obj.patterns) + builder.addField("allowInsecureProtocol", obj.allowInsecureProtocol) builder.endObject() } } diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 2fc2c6fbb..67d655470 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -143,7 +143,11 @@ { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, - { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" } + { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" }, + { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } + ], + "extra": [ + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger)" ], "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" }, @@ -557,6 +561,10 @@ "fields": [ { "name": "name", "type": "String" } ], + "extra": [ + "/** check for HTTP */", + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = ()" + ], "types": [ { "name": "ChainedResolver", @@ -565,6 +573,9 @@ "type": "record", "fields": [ { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" } + ], + "extra": [ + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger))" ] }, { @@ -583,7 +594,17 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", - "extra": "def isCache: Boolean = false", + "doc": [ + "This is the internal implementation of actual Maven Repository (as opposed to a file cache)." + ], + "fields": [ + { "name": "_allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } + ], + "extra": [ + "override def isCache: Boolean = false", + "override def allowInsecureProtocol: Boolean = _allowInsecureProtocol", + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger)" + ], "toString": "s\"$name: $root\"" }, { @@ -600,13 +621,22 @@ ], "extra": [ "def this(name: String, rootFile: java.io.File) = this(name, rootFile.toURI.toURL.toString, true, rootFile)", - "def isCache: Boolean = true" + "override def isCache: Boolean = true", + "override def allowInsecureProtocol: Boolean = false" ], "toString": "s\"cache:$name: ${rootFile.getAbsolutePath}\"", "extraCompanion": "def apply(name: String, rootFile: java.io.File): MavenCache = new MavenCache(name, rootFile)" } ], - "extra": "def isCache: Boolean", + "extra": [ + "def isCache: Boolean", + "def allowInsecureProtocol: Boolean", + "def withAllowInsecureProtocol(allowInsecureProtocol: Boolean): MavenRepository =", + " this match {", + " case x: MavenRepo => x.with_allowInsecureProtocol(allowInsecureProtocol)", + " case x: MavenCache => x", + " }" + ], "parentsCompanion": "sbt.librarymanagement.MavenRepositoryFunctions" }, { @@ -642,8 +672,11 @@ "namespace": "sbt.librarymanagement", "target": "Scala", "type": "record", + "fields": [ + { "name": "allowInsecureProtocol", "type": "boolean", "default": "false", "since": "1.3.0" } + ], "extra": [ - "Resolver.validatePatterns(patterns)" + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger)" ] }, { diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index f90b9e29b..63a992d2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -26,14 +26,18 @@ private[librarymanagement] abstract class ArtifactFunctions { Artifact(name, `type`, extension, None, Vector.empty, None) def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) - def apply(name: String, url: URL): Artifact = + def apply(name: String, url: URL): Artifact = Artifact(name, url, false) + def apply(name: String, url: URL, allowInsecureProtocol: Boolean): Artifact = Artifact( name, extract(url, DefaultType), extract(url, DefaultExtension), None, Vector.empty, - Some(url) + Some(url), + Map.empty, + None, + allowInsecureProtocol ) private final val empty = Map.empty[String, String] diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala index a9c9d86fd..99e64106d 100755 --- a/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyBuilders.scala @@ -67,9 +67,8 @@ object DependencyBuilders { } final class RepositoryName private[sbt] (name: String) { - def at(location: String) = { + def at(location: String): MavenRepository = { nonEmpty(location, "Repository location") - Resolver.validateUrlString(location) MavenRepository(name, location) } } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index d8c6ca6f2..40db9def1 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -8,6 +8,7 @@ import java.net.URL import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer import sbt.librarymanagement.syntax._ +import sbt.util.Logger private[librarymanagement] abstract class ModuleIDExtra { def organization: String @@ -75,10 +76,10 @@ private[librarymanagement] abstract class ModuleIDExtra { // () required for chaining /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ - def notTransitive() = intransitive() + def notTransitive(): ModuleID = intransitive() /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ - def intransitive() = withIsTransitive(false) + def intransitive(): ModuleID = withIsTransitive(false) /** * Marks this dependency as "changing". Ivy will always check if the metadata has changed and then if the artifact has changed, @@ -86,49 +87,58 @@ private[librarymanagement] abstract class ModuleIDExtra { * * See the "Changes in artifacts" section of https://ant.apache.org/ivy/history/trunk/concept.html for full details. */ - def changing() = withIsChanging(true) + def changing(): ModuleID = withIsChanging(true) /** * Indicates that conflict resolution should only select this module's revision. * This prevents a newer revision from being pulled in by a transitive dependency, for example. */ - def force() = withIsForce(true) + def force(): ModuleID = withIsForce(true) + + private[sbt] def validateProtocol(logger: Logger): Unit = { + explicitArtifacts foreach { _.validateProtocol(logger) } + } /** * Specifies a URL from which the main artifact for this dependency can be downloaded. * This value is only consulted if the module is not found in a repository. * It is not included in published metadata. */ - def from(url: String) = { - Resolver.validateUrlString(url) - artifacts(Artifact(name, new URL(url))) - } + def from(url: String): ModuleID = from(url, false) + + /** + * Specifies a URL from which the main artifact for this dependency can be downloaded. + * This value is only consulted if the module is not found in a repository. + * It is not included in published metadata. + */ + def from(url: String, allowInsecureProtocol: Boolean): ModuleID = + artifacts(Artifact(name, new URL(url), allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ - def classifier(c: String) = artifacts(Artifact(name, c)) + def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) /** * Declares the explicit artifacts for this module. If this ModuleID represents a dependency, * these artifact definitions override the information in the dependency's published metadata. */ - def artifacts(newArtifacts: Artifact*) = + def artifacts(newArtifacts: Artifact*): ModuleID = withExplicitArtifacts(newArtifacts.toVector ++ explicitArtifacts) /** * Applies the provided exclusions to dependencies of this module. Note that only exclusions that specify * both the exact organization and name and nothing else will be included in a pom.xml. */ - def excludeAll(rules: ExclusionRule*) = withExclusions(exclusions ++ rules) + def excludeAll(rules: ExclusionRule*): ModuleID = withExclusions(exclusions ++ rules) /** Excludes the dependency with organization `org` and `name` from being introduced by this dependency during resolution. */ - def exclude(org: String, name: String) = + def exclude(org: String, name: String): ModuleID = excludeAll(ExclusionRule().withOrganization(org).withName(name)) /** * Adds extra attributes for this module. All keys are prefixed with `e:` if they are not already so prefixed. * This information will only be published in an ivy.xml and not in a pom.xml. */ - def extra(attributes: (String, String)*) = + def extra(attributes: (String, String)*): ModuleID = withExtraAttributes(extraAttributes ++ ModuleID.checkE(attributes)) /** @@ -136,30 +146,30 @@ private[librarymanagement] abstract class ModuleIDExtra { * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withSources()` instead. */ - def sources() = artifacts(Artifact.sources(name)) + def sources(): ModuleID = artifacts(Artifact.sources(name)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" * classifier. If you want to also depend on the main artifact, be sure to also call `jar()` or use `withJavadoc()` instead. */ - def javadoc() = artifacts(Artifact.javadoc(name)) + def javadoc(): ModuleID = artifacts(Artifact.javadoc(name)) - def pomOnly() = artifacts(Artifact.pom(name)) + def pomOnly(): ModuleID = artifacts(Artifact.pom(name)) /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "sources" * classifier. If there is not already an explicit dependency on the main artifact, this adds one. */ - def withSources() = jarIfEmpty.sources() + def withSources(): ModuleID = jarIfEmpty.sources() /** * Not recommended for new use. This method is not deprecated, but the `update-classifiers` task is preferred * for performance and correctness. This method adds a dependency on this module's artifact with the "javadoc" * classifier. If there is not already an explicit dependency on the main artifact, this adds one. */ - def withJavadoc() = jarIfEmpty.javadoc() + def withJavadoc(): ModuleID = jarIfEmpty.javadoc() private def jarIfEmpty = if (explicitArtifacts.isEmpty) jar() else this @@ -167,14 +177,14 @@ private[librarymanagement] abstract class ModuleIDExtra { * Declares a dependency on the main artifact. This is implied by default unless artifacts are explicitly declared, such * as when adding a dependency on an artifact with a classifier. */ - def jar() = artifacts(Artifact(name)) + def jar(): ModuleID = artifacts(Artifact(name)) /** * Sets the Ivy branch of this module. */ - def branch(branchName: String) = withBranchName(Some(branchName)) + def branch(branchName: String): ModuleID = withBranchName(Some(branchName)) - def branch(branchName: Option[String]) = withBranchName(branchName) + def branch(branchName: Option[String]): ModuleID = withBranchName(branchName) } private[librarymanagement] abstract class ModuleIDFunctions { diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d45166997..33944a268 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -7,7 +7,7 @@ import java.io.{ IOException, File } import java.net.URL import scala.xml.XML import org.xml.sax.SAXParseException -import sbt.util.{ Level, LogExchange } +import sbt.util.Logger final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -404,33 +404,60 @@ private[librarymanagement] abstract class ResolverFunctions { Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) } - lazy val log = { - val log0 = LogExchange.logger("sbt.librarymanagement.ResolverExtra") - LogExchange.bindLoggerAppenders( - "sbt.librarymanagement.ResolverExtra", - List(LogExchange.buildAsyncStdout -> Level.Info) - ) - log0 + private[sbt] def warnHttp(value: String, suggestion: String, logger: Logger): Unit = { + logger.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS$suggestion") } - private[sbt] def warnHttp(value: String): Unit = { - log.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS") + private[sbt] def isInsecureUrl(str: String): Boolean = { + // don't try to parse str as URL because it could contain $variable from Ivy pattern + str.startsWith("http:") && + !(str.startsWith("http://localhost/") + || str.startsWith("http://localhost:") + || str.startsWith("http://127.0.0.1/") + || str.startsWith("http://127.0.0.1:")) } - private[sbt] def validatePatterns(patterns: Patterns): Unit = { - val ivy = patterns.ivyPatterns.headOption match { - case Some(x) => x.startsWith("http:") - case _ => false - } - val art = patterns.artifactPatterns.headOption match { - case Some(x) => x.startsWith("http:") - case _ => false - } - if (ivy || art) { - warnHttp(patterns.toString) + private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Unit = { + if (repo.allowInsecureProtocol) () + else { + val patterns = repo.patterns + val ivy = patterns.ivyPatterns.headOption match { + case Some(x) => isInsecureUrl(x) + case _ => false + } + val art = patterns.artifactPatterns.headOption match { + case Some(x) => isInsecureUrl(x) + case _ => false + } + if (ivy || art) { + warnHttp( + patterns.toString, + s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true)""", + logger + ) + } } } - private[sbt] def validateUrlString(url: String): Unit = { - if (url.startsWith("http:")) { - warnHttp(url) + + private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Unit = + if (repo.allowInsecureProtocol) () + else if (isInsecureUrl(repo.root)) { + warnHttp( + repo.root, + s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true)""", + logger + ) + } + + private[sbt] def validateArtifact(art: Artifact, logger: Logger): Unit = + if (art.allowInsecureProtocol) () + else { + art.url foreach { url => + if (isInsecureUrl(url.toString)) { + warnHttp( + art.toString, + " or opt-in using from(url(...), allowInsecureProtocol = true) on ModuleID or .withAllowInsecureProtocol(true) on Artifact", + logger + ) + } + } } - } } From 2071b297481bc25e60a624e2532ac7eec2b9283d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 28 Aug 2019 18:28:30 -0400 Subject: [PATCH 0862/1030] Remove unused file --- .../librarymanagement/DisabledFormats.scala | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala deleted file mode 100644 index 7c0602834..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DisabledFormats.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = new JsonFormat[sbt.librarymanagement.Disabled] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Disabled = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) - - unbuilder.endObject() - sbt.librarymanagement.Disabled() - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.Disabled, builder: Builder[J]): Unit = { - builder.beginObject() - - builder.endObject() - } -} -} From b01b61384e7e51442089e7bde0b727101fc53de9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 28 Aug 2019 18:33:46 -0400 Subject: [PATCH 0863/1030] Add custom handling for Disabled companion object https://github.com/sbt/librarymanagement/pull/316 started returning Disabled companion object for `apply()` instead of creating a new instance. This leaked into JSON as it uses runtime types for union. This works around that by providing a hand-crafted format. Ref https://github.com/sbt/sbt/pull/4997 --- .../sbt/librarymanagement/CrossVersion.scala | 34 ++++++++++++++----- .../sbt/librarymanagement/ModuleIdTest.scala | 14 ++++++++ 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 19e712981..4ab1b6446 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -331,14 +331,30 @@ trait CrossVersionFormats { with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats => - implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] = - flatUnionFormat6[ - sbt.librarymanagement.CrossVersion, - sbt.librarymanagement.Disabled, - sbt.librarymanagement.Disabled.type, - sbt.librarymanagement.Binary, - sbt.librarymanagement.Constant, - sbt.librarymanagement.Patch, - sbt.librarymanagement.Full + implicit lazy val CrossVersionFormat: JsonFormat[CrossVersion] = { + val format = flatUnionFormat6[ + CrossVersion, + Disabled, + Disabled.type, + Binary, + Constant, + Patch, + Full ]("type") + // This is a hand-crafted formatter to avoid Disabled$ showing up in JSON + new JsonFormat[CrossVersion] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): CrossVersion = + format.read(jsOpt, unbuilder) + override def write[J](obj: CrossVersion, builder: Builder[J]): Unit = { + if (obj == Disabled) { + builder.beginPreObject() + builder.addFieldName("type") + builder.writeString("Disabled") + builder.endPreObject() + builder.beginObject() + builder.endObject() + } else format.write(obj, builder) + } + } + } } diff --git a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala index a9bab61f0..1698f317a 100644 --- a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala @@ -1,8 +1,11 @@ package sbt.librarymanagement import sbt.internal.librarymanagement.UnitSpec +import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter, Parser } class ModuleIdTest extends UnitSpec { + val expectedJson = + """{"organization":"com.acme","name":"foo","revision":"1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}""" "Module Id" should "return cross-disabled module id as equal to a copy" in { ModuleID("com.acme", "foo", "1") shouldBe ModuleID("com.acme", "foo", "1") } @@ -14,4 +17,15 @@ class ModuleIdTest extends UnitSpec { (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) shouldBe (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) } + it should "format itself into JSON" in { + import LibraryManagementCodec._ + val json = Converter.toJson(ModuleID("com.acme", "foo", "1")).get + assert(CompactPrinter(json) == expectedJson) + } + it should "thaw back from JSON" in { + import LibraryManagementCodec._ + val json = Parser.parseUnsafe(expectedJson) + val m = Converter.fromJsonUnsafe[ModuleID](json) + assert(m == ModuleID("com.acme", "foo", "1")) + } } From d4f2b237810c2b51c8a6f40dc8bff93e567b6853 Mon Sep 17 00:00:00 2001 From: Vincent PERICART Date: Thu, 12 Sep 2019 10:34:44 +0900 Subject: [PATCH 0864/1030] Fix typo: cachedResolution --- .../main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 1ac339eec..0a41509bb 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -37,8 +37,8 @@ final class UpdateOptions private[sbt] ( copy(interProjectFirst = interProjectFirst) def withLatestSnapshots(latestSnapshots: Boolean): UpdateOptions = copy(latestSnapshots = latestSnapshots) - def withCachedResolution(cachedResoluton: Boolean): UpdateOptions = - copy(cachedResolution = cachedResoluton) + def withCachedResolution(cachedResolution: Boolean): UpdateOptions = + copy(cachedResolution = cachedResolution) def withGigahorse(gigahorse: Boolean): UpdateOptions = copy(gigahorse = gigahorse) From 8aeb43fc1189eb2aaca06d78eaa1091f94ac1f54 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 19 Oct 2019 19:53:11 -0400 Subject: [PATCH 0865/1030] in-source sbt-houserules --- build.sbt | 60 +++++------ project/HouseRulesPlugin.scala | 58 +++++++++++ project/SbtScriptedIT.scala | 178 ++++++++++++++++----------------- project/plugins.sbt | 7 +- 4 files changed, 183 insertions(+), 120 deletions(-) create mode 100644 project/HouseRulesPlugin.scala diff --git a/build.sbt b/build.sbt index 25e1d9eab..6931c8a8e 100644 --- a/build.sbt +++ b/build.sbt @@ -7,16 +7,28 @@ val _ = { sys.props += ("line.separator" -> "\n") } -ThisBuild / git.baseVersion := "1.3.0" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { case Some(v) => v - case _ => - if (old contains "SNAPSHOT") git.baseVersion.value + "-SNAPSHOT" - else old + case _ => old } } +ThisBuild / organization := "org.scala-sbt" +ThisBuild / bintrayPackage := "librarymanagement" +ThisBuild / homepage := Some(url("https://github.com/sbt/librarymanagement")) +ThisBuild / description := "Library management module for sbt" +ThisBuild / scmInfo := { + val slug = "sbt/librarymanagement" + Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) +} +ThisBuild / licenses := List(("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0"))) +ThisBuild / scalafmtOnCompile := true +ThisBuild / developers := List( + Developer("harrah", "Mark Harrah", "@harrah", url("https://github.com/harrah")), + Developer("eed3si9n", "Eugene Yokota", "@eed3si9n", url("http://eed3si9n.com/")), + Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")), +) ThisBuild / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat @@ -75,24 +87,14 @@ val mimaSettings = Def settings ( lazy val lmRoot = (project in file(".")) .aggregate(lmCore, lmIvy) .settings( - inThisBuild( - Seq( - homepage := Some(url("https://github.com/sbt/librarymanagement")), - description := "Library management module for sbt", - scmInfo := { - val slug = "sbt/librarymanagement" - Some(ScmInfo(url(s"https://github.com/$slug"), s"git@github.com:$slug.git")) - }, - bintrayPackage := "librarymanagement", - ) - ), commonSettings, name := "LM Root", publish := {}, publishLocal := {}, publishArtifact in Compile := false, publishArtifact := false, - customCommands + mimaPreviousArtifacts := Set.empty, + customCommands, ) lazy val lmCore = (project in file("core")) @@ -330,19 +332,19 @@ lazy val lmIvy = (project in file("ivy")) ), ) -lazy val lmScriptedTest = (project in file("scripted-test")) - .enablePlugins(SbtPlugin) - .settings( - commonSettings, - skip in publish := true, - name := "scripted-test", - scriptedLaunchOpts := { - scriptedLaunchOpts.value ++ - Seq("-Xmx1024M", "-Dplugin.version=" + version.value) - }, - scriptedBufferLog := false - ) - .enablePlugins(SbtScriptedIT) +// lazy val lmScriptedTest = (project in file("scripted-test")) +// .enablePlugins(SbtPlugin) +// .settings( +// commonSettings, +// skip in publish := true, +// name := "scripted-test", +// scriptedLaunchOpts := { +// scriptedLaunchOpts.value ++ +// Seq("-Xmx1024M", "-Dplugin.version=" + version.value) +// }, +// scriptedBufferLog := false +// ) +// .enablePlugins(SbtScriptedIT) // we are updating the nightly process, so we are commenting this out for now // addCommandAlias("scriptedIvy", Seq( diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala new file mode 100644 index 000000000..8c8958c4f --- /dev/null +++ b/project/HouseRulesPlugin.scala @@ -0,0 +1,58 @@ +import sbt._ +import Keys._ +import bintray.BintrayPlugin +import bintray.BintrayPlugin.autoImport._ + +object HouseRulesPlugin extends AutoPlugin { + override def requires = plugins.JvmPlugin && BintrayPlugin + override def trigger = allRequirements + + override def buildSettings: Seq[Def.Setting[_]] = baseBuildSettings + override def projectSettings: Seq[Def.Setting[_]] = baseSettings + + lazy val baseBuildSettings: Seq[Def.Setting[_]] = Seq( + bintrayOrganization := Some("sbt"), + bintrayRepository := "maven-releases", + ) + + lazy val baseSettings: Seq[Def.Setting[_]] = Seq( + bintrayPackage := (ThisBuild / bintrayPackage).value, + bintrayRepository := (ThisBuild / bintrayRepository).value, + scalacOptions ++= Seq("-encoding", "utf8"), + scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint"), + scalacOptions += "-language:higherKinds", + scalacOptions += "-language:implicitConversions", + scalacOptions ++= "-Xfuture".ifScala213OrMinus.value.toList, + scalacOptions += "-Xlint", + scalacOptions ++= "-Xfatal-warnings" + .ifScala(v => { + sys.props.get("sbt.build.fatal") match { + case Some(_) => java.lang.Boolean.getBoolean("sbt.build.fatal") + case _ => v == 12 + } + }) + .value + .toList, + scalacOptions ++= "-Yinline-warnings".ifScala211OrMinus.value.toList, + scalacOptions ++= "-Yno-adapted-args".ifScala212OrMinus.value.toList, + scalacOptions += "-Ywarn-dead-code", + scalacOptions += "-Ywarn-numeric-widen", + scalacOptions += "-Ywarn-value-discard", + scalacOptions ++= "-Ywarn-unused-import".ifScala(v => 11 <= v && v <= 12).value.toList + ) ++ Seq(Compile, Test).flatMap( + c => scalacOptions in (c, console) --= Seq("-Ywarn-unused-import", "-Xlint") + ) + + private def scalaPartV = Def setting (CrossVersion partialVersion scalaVersion.value) + + private implicit final class AnyWithIfScala[A](val __x: A) { + def ifScala(p: Long => Boolean) = + Def setting (scalaPartV.value collect { case (2, y) if p(y) => __x }) + def ifScalaLte(v: Long) = ifScala(_ <= v) + def ifScalaGte(v: Long) = ifScala(_ >= v) + def ifScala211OrMinus = ifScalaLte(11) + def ifScala211OrPlus = ifScalaGte(11) + def ifScala212OrMinus = ifScalaLte(12) + def ifScala213OrMinus = ifScalaLte(13) + } +} diff --git a/project/SbtScriptedIT.scala b/project/SbtScriptedIT.scala index 7094191ab..d80d277b9 100644 --- a/project/SbtScriptedIT.scala +++ b/project/SbtScriptedIT.scala @@ -1,108 +1,108 @@ -import sbt._ -import Keys._ +// import sbt._ +// import Keys._ -import java.io.File -import java.util.UUID.randomUUID +// import java.io.File +// import java.util.UUID.randomUUID -object SbtScriptedIT extends AutoPlugin { +// object SbtScriptedIT extends AutoPlugin { - object autoImport { - val scriptedTestSbtRepo = settingKey[String]("SBT repository to be used in scripted tests") - val scriptedTestSbtRef = settingKey[String]("SBT branch to be used in scripted tests") - val scriptedTestLMImpl = settingKey[String]("Librarymanagement implementation to be used in scripted tests") - val scriptedSbtVersion = settingKey[String]("SBT version to be published locally for IT tests") - } +// object autoImport { +// val scriptedTestSbtRepo = settingKey[String]("SBT repository to be used in scripted tests") +// val scriptedTestSbtRef = settingKey[String]("SBT branch to be used in scripted tests") +// val scriptedTestLMImpl = settingKey[String]("Librarymanagement implementation to be used in scripted tests") +// val scriptedSbtVersion = settingKey[String]("SBT version to be published locally for IT tests") +// } - import autoImport._ - override def requires = ScriptedPlugin +// import autoImport._ +// override def requires = ScriptedPlugin - override def trigger = noTrigger +// override def trigger = noTrigger - override lazy val globalSettings = Seq( - scriptedTestSbtRepo := "https://github.com/sbt/sbt.git", - scriptedTestSbtRef := "develop", - scriptedTestLMImpl := "ivy", - scriptedSbtVersion := s"""${sbtVersion.value}-LM-SNAPSHOT""" - ) +// override lazy val globalSettings = Seq( +// scriptedTestSbtRepo := "https://github.com/sbt/sbt.git", +// scriptedTestSbtRef := "develop", +// scriptedTestLMImpl := "ivy", +// scriptedSbtVersion := s"""${sbtVersion.value}-LM-SNAPSHOT""" +// ) - private def cloneSbt(targetDir: File, repo: String, ref: String) = { - import org.eclipse.jgit.api._ +// private def cloneSbt(targetDir: File, repo: String, ref: String) = { +// import org.eclipse.jgit.api._ - if (!targetDir.exists) { - IO.createDirectory(targetDir) +// if (!targetDir.exists) { +// IO.createDirectory(targetDir) - new CloneCommand() - .setDirectory(targetDir) - .setURI(repo) - .call() +// new CloneCommand() +// .setDirectory(targetDir) +// .setURI(repo) +// .call() - val git = Git.open(targetDir) +// val git = Git.open(targetDir) - git.checkout().setName(ref).call() - } - } +// git.checkout().setName(ref).call() +// } +// } - private def publishLocalSbt( - targetDir: File, - lmVersion: String, - lmGroupID: String, - lmArtifactID: String, - version: String) = { - import sys.process._ - Process( - Seq( - "sbt", - "-J-Xms2048m", - "-J-Xmx2048m", - "-J-XX:ReservedCodeCacheSize=256m", - "-J-XX:MaxMetaspaceSize=512m", - s"""-Dsbt.build.lm.version=${lmVersion}""", - s"""-Dsbt.build.lm.organization=${lmGroupID}""", - s"""-Dsbt.build.lm.moduleName=${lmArtifactID}""", - s"""set ThisBuild / version := "${version}"""", - "clean", - "publishLocal" - ), - Some(targetDir) - ) ! - } +// private def publishLocalSbt( +// targetDir: File, +// lmVersion: String, +// lmGroupID: String, +// lmArtifactID: String, +// version: String) = { +// import sys.process._ +// Process( +// Seq( +// "sbt", +// "-J-Xms2048m", +// "-J-Xmx2048m", +// "-J-XX:ReservedCodeCacheSize=256m", +// "-J-XX:MaxMetaspaceSize=512m", +// s"""-Dsbt.build.lm.version=${lmVersion}""", +// s"""-Dsbt.build.lm.organization=${lmGroupID}""", +// s"""-Dsbt.build.lm.moduleName=${lmArtifactID}""", +// s"""set ThisBuild / version := "${version}"""", +// "clean", +// "publishLocal" +// ), +// Some(targetDir) +// ) ! +// } - private def setScriptedTestsSbtVersion(baseDir: File, version: String) = { - IO.listFiles(baseDir).foreach { d => - if (d.isDirectory) { - IO.createDirectory(d / "project") - IO.write( - d / "project" / "build.properties", - s"sbt.version=$version" - ) - } - } - } +// private def setScriptedTestsSbtVersion(baseDir: File, version: String) = { +// IO.listFiles(baseDir).foreach { d => +// if (d.isDirectory) { +// IO.createDirectory(d / "project") +// IO.write( +// d / "project" / "build.properties", +// s"sbt.version=$version" +// ) +// } +// } +// } - import sbt.ScriptedPlugin.autoImport._ +// import sbt.ScriptedPlugin.autoImport._ - override lazy val projectSettings = Seq( - scriptedTests := { - val targetDir = target.value / "sbt" +// override lazy val projectSettings = Seq( +// scriptedTests := { +// val targetDir = target.value / "sbt" - if (!targetDir.exists) { - cloneSbt(targetDir, scriptedTestSbtRepo.value, scriptedTestSbtRef.value) +// if (!targetDir.exists) { +// cloneSbt(targetDir, scriptedTestSbtRepo.value, scriptedTestSbtRef.value) - publishLocalSbt( - targetDir, - version.value, - organization.value, - s"librarymanagement-${scriptedTestLMImpl.value}", - scriptedSbtVersion.value - ) - } +// publishLocalSbt( +// targetDir, +// version.value, +// organization.value, +// s"librarymanagement-${scriptedTestLMImpl.value}", +// scriptedSbtVersion.value +// ) +// } - setScriptedTestsSbtVersion( - sbtTestDirectory.value / thisProject.value.id, - scriptedSbtVersion.value - ) +// setScriptedTestsSbtVersion( +// sbtTestDirectory.value / thisProject.value.id, +// scriptedSbtVersion.value +// ) - scriptedTests.value - } - ) -} +// scriptedTests.value +// } +// ) +// } diff --git a/project/plugins.sbt b/project/plugins.sbt index 3794c4ca6..52b4bcbbb 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,8 @@ -addSbtPlugin("org.scala-sbt" % "sbt-houserules" % "0.3.9") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.0") +addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") +addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.5") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.2") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") From e0d2455982a9f26888fe83038226dcc00acff534 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 19 Oct 2019 19:56:19 -0400 Subject: [PATCH 0866/1030] sbt 1.3.3 --- .travis.yml | 5 ++--- project/build.properties | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index a8a7e50e7..3a27de94e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,9 +30,8 @@ install: - unset JAVA_HOME - java -Xmx32m -version # detect sbt version from project/build.properties - # - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" - # use 1.2.8 until 1.3.0 installer is out - - export TRAVIS_SBT=1.2.8 + - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" + # - export TRAVIS_SBT=1.3.3 - sdk install sbt $TRAVIS_SBT # override Travis CI's SBT_OPTS - unset SBT_OPTS diff --git a/project/build.properties b/project/build.properties index c59667ce9..6adcdc753 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.0-M3 +sbt.version=1.3.3 From 6807e91edde87faa8e2be8c44b80ef3a78dfde94 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 19 Oct 2019 19:59:13 -0400 Subject: [PATCH 0867/1030] Scala 2.12.10 --- .travis.yml | 2 +- project/Dependencies.scala | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3a27de94e..0b066459c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ group: stable language: scala scala: - - 2.12.8 + - 2.12.10 env: global: diff --git a/project/Dependencies.scala b/project/Dependencies.scala index a6cf0fdef..b46fb6c20 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,12 +3,12 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.8" + val scala212 = "2.12.10" def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.3.0-M16") - private val utilVersion = nightlyVersion.getOrElse("1.3.0-M9") + private val ioVersion = nightlyVersion.getOrElse("1.3.1") + private val utilVersion = nightlyVersion.getOrElse("1.3.2") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 705cb472b62b1246ed23121a58ab25dc6ae511d4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 19 Oct 2019 20:02:25 -0400 Subject: [PATCH 0868/1030] Add previous artifact --- build.sbt | 1 + 1 file changed, 1 insertion(+) diff --git a/build.sbt b/build.sbt index 6931c8a8e..c2037fcbc 100644 --- a/build.sbt +++ b/build.sbt @@ -77,6 +77,7 @@ val mimaSettings = Def settings ( "1.1.3", "1.1.4", "1.2.0", + "1.3.0", ) map ( version => organization.value %% moduleName.value % version From 6200255eedb6023f0af7f9d27f0954c64a55db07 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 20 Oct 2019 11:42:41 -0400 Subject: [PATCH 0869/1030] ivy 2.3.0-sbt-88d6a93d15f9b029958c1c289a8859e8dfe31a19 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b46fb6c20..0f75498a2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -41,7 +41,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-cb9cc189e9f3af519f9f102e6c5d446488ff6832" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-88d6a93d15f9b029958c1c289a8859e8dfe31a19" val sbtV = "1.0" val scalaV = "2.12" From ea9d382b8932ddd3a46259248fc3c04fa7a95054 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 28 Dec 2019 16:04:18 -0500 Subject: [PATCH 0870/1030] add hook for nightly build --- build.sbt | 8 ++++++++ project/plugins.sbt | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index c2037fcbc..24c2c8da3 100644 --- a/build.sbt +++ b/build.sbt @@ -366,6 +366,14 @@ def customCommands: Seq[Setting[_]] = Seq( } ) +ThisBuild / publishTo := { + val old = (ThisBuild / publishTo).value + sys.props.get("sbt.build.localmaven") match { + case Some(path) => Some(MavenCache("local-maven", file(path))) + case _ => old + } +} + inThisBuild( Seq( whitesourceProduct := "Lightbend Reactive Platform", diff --git a/project/plugins.sbt b/project/plugins.sbt index 52b4bcbbb..0b4d75847 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,5 +1,5 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") -addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.5") +addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") From e77dc68e34e9f446f96dd4050e1ab3d4835f30ae Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 28 Dec 2019 16:09:02 -0500 Subject: [PATCH 0871/1030] bump sbt and IO --- project/Dependencies.scala | 2 +- project/build.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 0f75498a2..95e1dc022 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,7 +7,7 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.3.1") + private val ioVersion = nightlyVersion.getOrElse("1.4.0-M2") private val utilVersion = nightlyVersion.getOrElse("1.3.2") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/build.properties b/project/build.properties index 6adcdc753..00b48d978 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.3 +sbt.version=1.3.6 From cdba2dbc53fe385ee8246a0d5e20f61ce9d1e485 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 6 Jan 2020 21:25:57 -0500 Subject: [PATCH 0872/1030] Remove "merged artifact" error message Fixes https://github.com/sbt/sbt/issues/4520 It seems to display "Detected merged artifact" whenever the download fails, which is confusing. --- .../ivyint/ParallelResolveEngine.scala | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index cac26e395..9af7ef6cb 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -8,7 +8,6 @@ import org.apache.ivy.core.module.descriptor.Artifact import org.apache.ivy.core.report._ import org.apache.ivy.core.resolve._ import org.apache.ivy.core.sort.SortEngine -import org.apache.ivy.util.Message import org.apache.ivy.util.filter.Filter import scala.concurrent.duration.Duration @@ -103,16 +102,6 @@ private[sbt] class ParallelResolveEngine( artifactReport.getDownloadStatus match { case DownloadStatus.SUCCESSFUL => size + artifactReport.getSize - case DownloadStatus.FAILED => - val artifact = artifactReport.getArtifact - val mergedAttribute = artifact.getExtraAttribute("ivy:merged") - if (mergedAttribute != null) { - Message.warn(s"\tMissing merged artifact: $artifact, required by $mergedAttribute.") - } else { - Message.warn(s"\tDetected merged artifact: $artifactReport.") - resolver.reportFailure(artifactReport.getArtifact) - } - size case _ => size } } From a9405ff0431aabc6f6baaa1e20f2e56108902754 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 6 Jan 2020 21:34:11 -0500 Subject: [PATCH 0873/1030] Fix Travis CI setup with SDKMAN --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0b066459c..d06d8f6c1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,17 +22,18 @@ before_install: - "[[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/" - curl -sL https://get.sdkman.io | bash - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config + - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - source "$HOME/.sdkman/bin/sdkman-init.sh" install: - - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) + - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) || true - bin/fixpreloaded.sh - unset JAVA_HOME - java -Xmx32m -version # detect sbt version from project/build.properties - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" # - export TRAVIS_SBT=1.3.3 - - sdk install sbt $TRAVIS_SBT + - sdk install sbt $TRAVIS_SBT || true # override Travis CI's SBT_OPTS - unset SBT_OPTS - export JAVA_OPTS="-Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M" From 2d6f102f9a34b33394b78da383677c7987b1d8dd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 22 Feb 2020 15:29:37 -0500 Subject: [PATCH 0874/1030] Ivy 2.3.0-sbt-fa726854dd30be842ff9e6d2093df6adfe3871f5 Fixes https://github.com/sbt/sbt/issues/2366 --- build.sbt | 5 ++++- project/Dependencies.scala | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 24c2c8da3..b8f4787db 100644 --- a/build.sbt +++ b/build.sbt @@ -11,9 +11,12 @@ ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { case Some(v) => v - case _ => old + case _ => + if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + else old } } + ThisBuild / organization := "org.scala-sbt" ThisBuild / bintrayPackage := "librarymanagement" ThisBuild / homepage := Some(url("https://github.com/sbt/librarymanagement")) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 95e1dc022..4aa7896ac 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -41,7 +41,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-88d6a93d15f9b029958c1c289a8859e8dfe31a19" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-fa726854dd30be842ff9e6d2093df6adfe3871f5" val sbtV = "1.0" val scalaV = "2.12" From ab06affe7c8c7a12c66117be6bde07b6e3b00ecb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 6 Apr 2020 18:15:29 -0400 Subject: [PATCH 0875/1030] Bump util --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 95e1dc022..7e13bd02d 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -8,7 +8,7 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.4.0-M2") - private val utilVersion = nightlyVersion.getOrElse("1.3.2") + private val utilVersion = nightlyVersion.getOrElse("1.3.3") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From fd71e8cb176933702461f365d1b5cf7f35624d31 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 6 Apr 2020 18:15:46 -0400 Subject: [PATCH 0876/1030] Bump Contraband --- .../librarymanagement/ConfigurationReportLite.scala | 2 +- .../sbt/internal/librarymanagement/SemComparator.scala | 2 +- .../internal/librarymanagement/SemSelAndChunk.scala | 2 +- .../internal/librarymanagement/UpdateReportLite.scala | 2 +- .../sbt/librarymanagement/Artifact.scala | 2 +- .../sbt/librarymanagement/ArtifactFormats.scala | 10 +++++----- .../sbt/librarymanagement/ArtifactTypeFilter.scala | 2 +- .../librarymanagement/ArtifactTypeFilterFormats.scala | 10 +++++----- .../sbt/librarymanagement/Caller.scala | 2 +- .../sbt/librarymanagement/CallerFormats.scala | 10 +++++----- .../sbt/librarymanagement/ChainedResolver.scala | 2 +- .../sbt/librarymanagement/ChainedResolverFormats.scala | 10 +++++----- .../sbt/librarymanagement/Checksum.scala | 2 +- .../sbt/librarymanagement/ChecksumFormats.scala | 10 +++++----- .../sbt/librarymanagement/ConfigRef.scala | 2 +- .../sbt/librarymanagement/ConfigRefFormats.scala | 10 +++++----- .../sbt/librarymanagement/ConfigurationReport.scala | 2 +- .../librarymanagement/ConfigurationReportFormats.scala | 10 +++++----- .../ConfigurationReportLiteFormats.scala | 10 +++++----- .../sbt/librarymanagement/ConflictManager.scala | 2 +- .../sbt/librarymanagement/ConflictManagerFormats.scala | 10 +++++----- .../sbt/librarymanagement/Developer.scala | 2 +- .../sbt/librarymanagement/DeveloperFormats.scala | 10 +++++----- .../sbt/librarymanagement/FileConfiguration.scala | 2 +- .../librarymanagement/FileConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/FileRepository.scala | 2 +- .../sbt/librarymanagement/FileRepositoryFormats.scala | 10 +++++----- .../GetClassifiersConfiguration.scala | 2 +- .../GetClassifiersConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/GetClassifiersModule.scala | 2 +- .../GetClassifiersModuleFormats.scala | 10 +++++----- .../sbt/librarymanagement/InclExclRule.scala | 2 +- .../sbt/librarymanagement/InclExclRuleFormats.scala | 10 +++++----- .../sbt/librarymanagement/IvyFileConfiguration.scala | 2 +- .../IvyFileConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/KeyFileAuthentication.scala | 2 +- .../KeyFileAuthenticationFormats.scala | 10 +++++----- .../sbt/librarymanagement/LibraryManagementCodec.scala | 2 +- .../sbt/librarymanagement/MakePomConfiguration.scala | 2 +- .../sbt/librarymanagement/MavenCache.scala | 2 +- .../sbt/librarymanagement/MavenCacheFormats.scala | 10 +++++----- .../sbt/librarymanagement/MavenRepo.scala | 2 +- .../sbt/librarymanagement/MavenRepoFormats.scala | 10 +++++----- .../sbt/librarymanagement/MavenRepository.scala | 2 +- .../sbt/librarymanagement/MavenRepositoryFormats.scala | 2 +- .../sbt/librarymanagement/ModuleConfiguration.scala | 2 +- .../librarymanagement/ModuleConfigurationFormats.scala | 10 +++++----- .../ModuleDescriptorConfiguration.scala | 2 +- .../ModuleDescriptorConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/ModuleID.scala | 2 +- .../sbt/librarymanagement/ModuleIDFormats.scala | 10 +++++----- .../sbt/librarymanagement/ModuleInfo.scala | 2 +- .../sbt/librarymanagement/ModuleInfoFormats.scala | 10 +++++----- .../sbt/librarymanagement/ModuleReport.scala | 2 +- .../sbt/librarymanagement/ModuleReportFormats.scala | 10 +++++----- .../sbt/librarymanagement/ModuleSettings.scala | 2 +- .../sbt/librarymanagement/ModuleSettingsFormats.scala | 2 +- .../librarymanagement/OrganizationArtifactReport.scala | 2 +- .../OrganizationArtifactReportFormats.scala | 10 +++++----- .../sbt/librarymanagement/PasswordAuthentication.scala | 2 +- .../PasswordAuthenticationFormats.scala | 10 +++++----- .../sbt/librarymanagement/Patterns.scala | 2 +- .../librarymanagement/PatternsBasedRepository.scala | 2 +- .../PatternsBasedRepositoryFormats.scala | 2 +- .../sbt/librarymanagement/PatternsFormats.scala | 10 +++++----- .../sbt/librarymanagement/PomConfiguration.scala | 2 +- .../librarymanagement/PomConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/PublishConfiguration.scala | 2 +- .../PublishConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/Resolver.scala | 2 +- .../sbt/librarymanagement/ResolverFormats.scala | 2 +- .../sbt/librarymanagement/RetrieveConfiguration.scala | 2 +- .../RetrieveConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/ScalaModuleInfo.scala | 2 +- .../sbt/librarymanagement/ScalaModuleInfoFormats.scala | 10 +++++----- .../sbt/librarymanagement/ScmInfo.scala | 2 +- .../sbt/librarymanagement/ScmInfoFormats.scala | 10 +++++----- .../sbt/librarymanagement/SemanticSelector.scala | 2 +- .../sbt/librarymanagement/SftpRepository.scala | 2 +- .../sbt/librarymanagement/SftpRepositoryFormats.scala | 10 +++++----- .../sbt/librarymanagement/SshAuthentication.scala | 2 +- .../librarymanagement/SshAuthenticationFormats.scala | 2 +- .../sbt/librarymanagement/SshBasedRepository.scala | 2 +- .../librarymanagement/SshBasedRepositoryFormats.scala | 2 +- .../sbt/librarymanagement/SshConnection.scala | 2 +- .../sbt/librarymanagement/SshConnectionFormats.scala | 10 +++++----- .../sbt/librarymanagement/SshRepository.scala | 2 +- .../sbt/librarymanagement/SshRepositoryFormats.scala | 10 +++++----- .../sbt/librarymanagement/URLRepository.scala | 2 +- .../sbt/librarymanagement/URLRepositoryFormats.scala | 10 +++++----- .../sbt/librarymanagement/UpdateConfiguration.scala | 2 +- .../librarymanagement/UpdateConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/UpdateLogging.scala | 2 +- .../sbt/librarymanagement/UpdateLoggingFormats.scala | 10 +++++----- .../sbt/librarymanagement/UpdateReport.scala | 2 +- .../sbt/librarymanagement/UpdateReportFormats.scala | 10 +++++----- .../librarymanagement/UpdateReportLiteFormats.scala | 10 +++++----- .../sbt/librarymanagement/UpdateStats.scala | 2 +- .../sbt/librarymanagement/UpdateStatsFormats.scala | 10 +++++----- .../ivy/ExternalIvyConfiguration.scala | 2 +- .../ivy/ExternalIvyConfigurationFormats.scala | 10 +++++----- .../librarymanagement/ivy/InlineIvyConfiguration.scala | 2 +- .../ivy/InlineIvyConfigurationFormats.scala | 10 +++++----- .../sbt/librarymanagement/ivy/IvyConfiguration.scala | 2 +- .../ivy/IvyConfigurationFormats.scala | 2 +- .../sbt/librarymanagement/ivy/IvyPaths.scala | 2 +- .../sbt/librarymanagement/ivy/IvyPathsFormats.scala | 10 +++++----- project/build.properties | 2 +- project/plugins.sbt | 6 +++--- 109 files changed, 287 insertions(+), 287 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala index e43ee8de8..b9a9c46f3 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala index fd3ff81db..fda56f608 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala index 9e25e9789..3b8ab91a8 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala index 864709b5d..948280532 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 9cae77dca..ad2dafa0c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 2c9b2a02d..ae951d635 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ArtifactFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = new JsonFormat[sbt.librarymanagement.Artifact] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Artifact = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val `type` = unbuilder.readField[String]("type") val extension = unbuilder.readField[String]("extension") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala index ce5ab7765..fbdbc8dc7 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala index ec7a3919e..75e185a13 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilterFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ArtifactTypeFilterFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ArtifactTypeFilterFormat: JsonFormat[sbt.librarymanagement.ArtifactTypeFilter] = new JsonFormat[sbt.librarymanagement.ArtifactTypeFilter] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ArtifactTypeFilter = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ArtifactTypeFilter = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val types = unbuilder.readField[Set[String]]("types") val inverted = unbuilder.readField[Boolean]("inverted") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala index b29caaf26..074740502 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala index a7b863a5a..41c97f1be 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => implicit lazy val CallerFormat: JsonFormat[sbt.librarymanagement.Caller] = new JsonFormat[sbt.librarymanagement.Caller] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Caller = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Caller = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val caller = unbuilder.readField[sbt.librarymanagement.ModuleID]("caller") val callerConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("callerConfigurations") val callerExtraAttributes = unbuilder.readField[Map[String, String]]("callerExtraAttributes") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index fa950e86b..ebfa1fa6a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala index 3972cb500..61cf796da 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ChainedResolverFormat: JsonFormat[sbt.librarymanagement.ChainedResolver] = new JsonFormat[sbt.librarymanagement.ChainedResolver] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala index 20f136226..fafa5e340 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala index 7f674171e..365bf5770 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChecksumFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ChecksumFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ChecksumFormat: JsonFormat[sbt.librarymanagement.Checksum] = new JsonFormat[sbt.librarymanagement.Checksum] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Checksum = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Checksum = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val digest = unbuilder.readField[String]("digest") val `type` = unbuilder.readField[String]("type") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index f956602f6..383c5e772 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala index 9996bd2db..ffbb7f296 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ConfigRefFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ConfigRefFormat: JsonFormat[sbt.librarymanagement.ConfigRef] = new JsonFormat[sbt.librarymanagement.ConfigRef] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigRef = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigRef = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") unbuilder.endObject() sbt.librarymanagement.ConfigRef(name) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index 1243665a1..379a090fa 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index d94d09184..c2017c8be 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val configuration = unbuilder.readField[sbt.librarymanagement.ConfigRef]("configuration") val modules = unbuilder.readField[Vector[sbt.librarymanagement.ModuleReport]]("modules") val details = unbuilder.readField[Vector[sbt.librarymanagement.OrganizationArtifactReport]]("details") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala index be62807e4..59a27855a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ConfigurationReportLiteFormats { self: sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ConfigurationReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] = new JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ConfigurationReportLite = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ConfigurationReportLite = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val configuration = unbuilder.readField[String]("configuration") val details = unbuilder.readField[Vector[sbt.librarymanagement.OrganizationArtifactReport]]("details") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala index b4022dda4..3779a9801 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala index 40271b940..7511f4c4b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManagerFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ConflictManagerFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ConflictManagerFormat: JsonFormat[sbt.librarymanagement.ConflictManager] = new JsonFormat[sbt.librarymanagement.ConflictManager] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConflictManager = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConflictManager = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val organization = unbuilder.readField[String]("organization") val module = unbuilder.readField[String]("module") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index 30c20f3b9..eb12f67f2 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index ee1e87e45..381013ab0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait DeveloperFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = new JsonFormat[sbt.librarymanagement.Developer] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Developer = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Developer = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") val email = unbuilder.readField[String]("email") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala index 376efe8e4..26be3bbca 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala index 8117d6b15..be208ebec 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait FileConfigurationFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val FileConfigurationFormat: JsonFormat[sbt.librarymanagement.FileConfiguration] = new JsonFormat[sbt.librarymanagement.FileConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val isLocal = unbuilder.readField[Boolean]("isLocal") val isTransactional = unbuilder.readField[Option[Boolean]]("isTransactional") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala index 75790b075..ceb376bdf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala index 31a282b3b..18099155e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait FileRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val FileRepositoryFormat: JsonFormat[sbt.librarymanagement.FileRepository] = new JsonFormat[sbt.librarymanagement.FileRepository] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileRepository = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileRepository = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") val configuration = unbuilder.readField[sbt.librarymanagement.FileConfiguration]("configuration") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala index 1448c1d9e..dfcc0a031 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala index f93af3a85..19abfb80e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait GetClassifiersConfigurationFormats { self: sbt.librarymanagement.GetClassifiersModuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.UpdateConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val GetClassifiersConfigurationFormat: JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] = new JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val module = unbuilder.readField[sbt.librarymanagement.GetClassifiersModule]("module") val excludes = unbuilder.readField[Vector[scala.Tuple2[sbt.librarymanagement.ModuleID, scala.Vector[sbt.librarymanagement.ConfigRef]]]]("excludes") val updateConfiguration = unbuilder.readField[sbt.librarymanagement.UpdateConfiguration]("updateConfiguration") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala index 3f69e3a36..57459661d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala index 8bedbe9a3..e981e5761 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait GetClassifiersModuleFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val GetClassifiersModuleFormat: JsonFormat[sbt.librarymanagement.GetClassifiersModule] = new JsonFormat[sbt.librarymanagement.GetClassifiersModule] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersModule = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersModule = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val id = unbuilder.readField[sbt.librarymanagement.ModuleID]("id") val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val dependencies = unbuilder.readField[Vector[sbt.librarymanagement.ModuleID]]("dependencies") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index f37f2de74..65bbf0308 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala index e7f9ac838..a6a4bcd2d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclRule] = new JsonFormat[sbt.librarymanagement.InclExclRule] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val organization = unbuilder.readField[String]("organization") val name = unbuilder.readField[String]("name") val artifact = unbuilder.readField[String]("artifact") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala index 98a005c1c..4413ba31a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala index 1747cef64..a78fcc09d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait IvyFileConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => implicit lazy val IvyFileConfigurationFormat: JsonFormat[sbt.librarymanagement.IvyFileConfiguration] = new JsonFormat[sbt.librarymanagement.IvyFileConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyFileConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyFileConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val validate = unbuilder.readField[Boolean]("validate") val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val file = unbuilder.readField[java.io.File]("file") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala index d818a88c8..824315201 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala index 965c48625..8f99b0e10 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthenticationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait KeyFileAuthenticationFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val KeyFileAuthenticationFormat: JsonFormat[sbt.librarymanagement.KeyFileAuthentication] = new JsonFormat[sbt.librarymanagement.KeyFileAuthentication] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.KeyFileAuthentication = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.KeyFileAuthentication = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val user = unbuilder.readField[String]("user") val keyfile = unbuilder.readField[java.io.File]("keyfile") val password = unbuilder.readField[Option[String]]("password") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 6c82fab1a..06f3bfa22 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala index e7d0ffe2c..5ff0e386e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index 1ed824c7b..aac4cf776 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala index 4079ded96..9b28abfda 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCacheFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait MavenCacheFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val MavenCacheFormat: JsonFormat[sbt.librarymanagement.MavenCache] = new JsonFormat[sbt.librarymanagement.MavenCache] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenCache = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenCache = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val root = unbuilder.readField[String]("root") val localIfFile = unbuilder.readField[Boolean]("localIfFile") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index a23e1a225..b93d5b204 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala index e4c979985..21da41dcd 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepoFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait MavenRepoFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val MavenRepoFormat: JsonFormat[sbt.librarymanagement.MavenRepo] = new JsonFormat[sbt.librarymanagement.MavenRepo] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenRepo = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.MavenRepo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val root = unbuilder.readField[String]("root") val localIfFile = unbuilder.readField[Boolean]("localIfFile") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala index 3f891ef19..73623d6e5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala index 6e8a14d3c..34e8f0975 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala index 3bd4b9591..9953ac698 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala index 8ac48ea5c..1f34ab28f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val organization = unbuilder.readField[String]("organization") val name = unbuilder.readField[String]("name") val revision = unbuilder.readField[String]("revision") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 8d79275e6..5a093be12 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala index 2062ac0f0..7005fb518 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ModuleDescriptorConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleDescriptorConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleDescriptorConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleDescriptorConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val validate = unbuilder.readField[Boolean]("validate") val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val module = unbuilder.readField[sbt.librarymanagement.ModuleID]("module") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index 485f8c533..144e5058a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala index eeebd0d33..f09a501cc 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = new JsonFormat[sbt.librarymanagement.ModuleID] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val organization = unbuilder.readField[String]("organization") val name = unbuilder.readField[String]("name") val revision = unbuilder.readField[String]("revision") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index 545941120..a86e285d1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala index 8d9c1c8b0..4707e0bd1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ModuleInfoFormats { self: sbt.librarymanagement.ScmInfoFormats with sbt.librarymanagement.DeveloperFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleInfoFormat: JsonFormat[sbt.librarymanagement.ModuleInfo] = new JsonFormat[sbt.librarymanagement.ModuleInfo] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleInfo = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val nameFormal = unbuilder.readField[String]("nameFormal") val description = unbuilder.readField[String]("description") val homepage = unbuilder.readField[Option[java.net.URL]]("homepage") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 22c028d26..372468f1d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala index 78052a649..efcc6d76f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CallerFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleReportFormat: JsonFormat[sbt.librarymanagement.ModuleReport] = new JsonFormat[sbt.librarymanagement.ModuleReport] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleReport = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleReport = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val module = unbuilder.readField[sbt.librarymanagement.ModuleID]("module") val artifacts = unbuilder.readField[Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]]]("artifacts") val missingArtifacts = unbuilder.readField[Vector[sbt.librarymanagement.Artifact]]("missingArtifacts") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala index 2ce752c29..e210651b6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala index 09a7a0774..23b6bea80 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index 0bef821d4..693134253 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala index eacd8605c..1b2c4810f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait OrganizationArtifactReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sjsonnew.BasicJsonProtocol => implicit lazy val OrganizationArtifactReportFormat: JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] = new JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.OrganizationArtifactReport = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.OrganizationArtifactReport = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val organization = unbuilder.readField[String]("organization") val name = unbuilder.readField[String]("name") val modules = unbuilder.readField[Vector[sbt.librarymanagement.ModuleReport]]("modules") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala index 93de4085d..fb4c1bf1b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala index 0ece82e2a..646853d49 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthenticationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait PasswordAuthenticationFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val PasswordAuthenticationFormat: JsonFormat[sbt.librarymanagement.PasswordAuthentication] = new JsonFormat[sbt.librarymanagement.PasswordAuthentication] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PasswordAuthentication = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PasswordAuthentication = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val user = unbuilder.readField[String]("user") val password = unbuilder.readField[Option[String]]("password") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala index 57c0d03c4..609fc59d4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala index 93e624284..3ddc7b1cc 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala index a63b8da50..96e5a93cd 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala index b530299c2..fe190bc92 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait PatternsFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val PatternsFormat: JsonFormat[sbt.librarymanagement.Patterns] = new JsonFormat[sbt.librarymanagement.Patterns] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Patterns = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Patterns = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val ivyPatterns = unbuilder.readField[Vector[String]]("ivyPatterns") val artifactPatterns = unbuilder.readField[Vector[String]]("artifactPatterns") val isMavenCompatible = unbuilder.readField[Boolean]("isMavenCompatible") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala index f36a34149..8359588b6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala index 44c8bb008..0529fba88 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait PomConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PomConfigurationFormat: JsonFormat[sbt.librarymanagement.PomConfiguration] = new JsonFormat[sbt.librarymanagement.PomConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PomConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PomConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val validate = unbuilder.readField[Boolean]("validate") val scalaModuleInfo = unbuilder.readField[Option[sbt.librarymanagement.ScalaModuleInfo]]("scalaModuleInfo") val file = unbuilder.readField[java.io.File]("file") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala index 0b0bafa46..6391c8c3e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala index 14990899e..d1fde3d18 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.UpdateLoggingFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PublishConfigurationFormat: JsonFormat[sbt.librarymanagement.PublishConfiguration] = new JsonFormat[sbt.librarymanagement.PublishConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val publishMavenStyle = unbuilder.readField[Boolean]("publishMavenStyle") val deliverIvyPattern = unbuilder.readField[Option[String]]("deliverIvyPattern") val status = unbuilder.readField[Option[String]]("status") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index 448b04334..599fb562b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala index dc1daceea..67d790a14 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala index 814b688dd..7daf0d5f0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala index bd12840f7..9505bf2ef 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait RetrieveConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => implicit lazy val RetrieveConfigurationFormat: JsonFormat[sbt.librarymanagement.RetrieveConfiguration] = new JsonFormat[sbt.librarymanagement.RetrieveConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.RetrieveConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.RetrieveConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val retrieveDirectory = unbuilder.readField[Option[java.io.File]]("retrieveDirectory") val outputPattern = unbuilder.readField[Option[String]]("outputPattern") val sync = unbuilder.readField[Boolean]("sync") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index 0f938830b..c8b8ee745 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala index c3996cbec..8977be68d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ScalaModuleInfoFormats { self: sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ScalaModuleInfoFormat: JsonFormat[sbt.librarymanagement.ScalaModuleInfo] = new JsonFormat[sbt.librarymanagement.ScalaModuleInfo] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScalaModuleInfo = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScalaModuleInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val scalaFullVersion = unbuilder.readField[String]("scalaFullVersion") val scalaBinaryVersion = unbuilder.readField[String]("scalaBinaryVersion") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.Configuration]]("configurations") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 4d40ee514..837f9e11a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala index 38e04f37d..bacca95d8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ScmInfoFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val ScmInfoFormat: JsonFormat[sbt.librarymanagement.ScmInfo] = new JsonFormat[sbt.librarymanagement.ScmInfo] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScmInfo = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ScmInfo = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val browseUrl = unbuilder.readField[java.net.URL]("browseUrl") val connection = unbuilder.readField[String]("connection") val devConnection = unbuilder.readField[Option[String]]("devConnection") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala index fe159fd3c..4faf5ff19 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala index 6bd5679c7..f79ae577a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala index 43932f61e..a5fdb55a3 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") val connection = unbuilder.readField[sbt.librarymanagement.SshConnection]("connection") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala index 2ad8a3f57..e85c1454f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala index 4539a2598..2783143ec 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthenticationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala index 958439832..ef5e743a1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala index c7f0bff21..7561f480a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala index a722ce55a..796cdb961 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala index ec0e4cb74..9daea2940 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SshConnectionFormat: JsonFormat[sbt.librarymanagement.SshConnection] = new JsonFormat[sbt.librarymanagement.SshConnection] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val authentication = unbuilder.readField[Option[sbt.librarymanagement.SshAuthentication]]("authentication") val hostname = unbuilder.readField[Option[String]]("hostname") val port = unbuilder.readField[Option[Int]]("port") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala index 4cb9a18b8..a71e2bd5d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala index 3f6284b2f..d9f141b18 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") val connection = unbuilder.readField[sbt.librarymanagement.SshConnection]("connection") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 9f0efa520..11a19137f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala index 4ab1b23c8..d9bb6f32b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepositoryFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait URLRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol => implicit lazy val URLRepositoryFormat: JsonFormat[sbt.librarymanagement.URLRepository] = new JsonFormat[sbt.librarymanagement.URLRepository] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.URLRepository = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.URLRepository = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val name = unbuilder.readField[String]("name") val patterns = unbuilder.readField[sbt.librarymanagement.Patterns]("patterns") val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index 4443f1eb8..f1fd781fc 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala index bf14c2e99..8114a8576 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats with sbt.librarymanagement.ArtifactTypeFilterFormats with sjsonnew.BasicJsonProtocol => implicit lazy val UpdateConfigurationFormat: JsonFormat[sbt.librarymanagement.UpdateConfiguration] = new JsonFormat[sbt.librarymanagement.UpdateConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val retrieveManaged = unbuilder.readField[Option[sbt.librarymanagement.RetrieveConfiguration]]("retrieveManaged") val missingOk = unbuilder.readField[Boolean]("missingOk") val logging = unbuilder.readField[sbt.librarymanagement.UpdateLogging]("logging") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala index f749ef9d5..ee1db908a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLogging.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala index 77e18d19c..8da04c8ee 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateLoggingFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait UpdateLoggingFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val UpdateLoggingFormat: JsonFormat[sbt.librarymanagement.UpdateLogging] = new JsonFormat[sbt.librarymanagement.UpdateLogging] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateLogging = { - jsOpt match { - case Some(js) => - unbuilder.readString(js) match { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateLogging = { + __jsOpt match { + case Some(__js) => + unbuilder.readString(__js) match { case "Full" => sbt.librarymanagement.UpdateLogging.Full case "DownloadOnly" => sbt.librarymanagement.UpdateLogging.DownloadOnly case "Quiet" => sbt.librarymanagement.UpdateLogging.Quiet diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index ef6da3930..fd5f22a72 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala index 54e858000..2defd540e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait UpdateReportFormats { self: sbt.librarymanagement.ConfigurationReportFormats with sbt.librarymanagement.UpdateStatsFormats with sjsonnew.BasicJsonProtocol => implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateReport] = new JsonFormat[sbt.librarymanagement.UpdateReport] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateReport = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateReport = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val cachedDescriptor = unbuilder.readField[java.io.File]("cachedDescriptor") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigurationReport]]("configurations") val stats = unbuilder.readField[sbt.librarymanagement.UpdateStats]("stats") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala index 9736e62ca..4e9641f9e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait UpdateReportLiteFormats { self: sbt.librarymanagement.ConfigurationReportLiteFormats with sjsonnew.BasicJsonProtocol => implicit lazy val UpdateReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] = new JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.UpdateReportLite = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.UpdateReportLite = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val configurations = unbuilder.readField[Vector[sbt.internal.librarymanagement.ConfigurationReportLite]]("configurations") unbuilder.endObject() sbt.internal.librarymanagement.UpdateReportLite(configurations) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala index ef2b53738..96e408316 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala index 21de1bf5c..7457c7a23 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStatsFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait UpdateStatsFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val UpdateStatsFormat: JsonFormat[sbt.librarymanagement.UpdateStats] = new JsonFormat[sbt.librarymanagement.UpdateStats] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateStats = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateStats = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val resolveTime = unbuilder.readField[Long]("resolveTime") val downloadTime = unbuilder.readField[Long]("downloadTime") val downloadSize = unbuilder.readField[Long]("downloadSize") diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala index b1d74e539..c5068c2aa 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala index ae915f0e8..e9384ca63 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") val log = unbuilder.readField[Option[xsbti.Logger]]("log") val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index 209aa3f27..f528b84b4 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala index 8c07808f5..4fa266e4d 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") val log = unbuilder.readField[Option[xsbti.Logger]]("log") val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala index 9ca6e9dd0..8a1fd621d 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala index 1b27eaeaf..ee0807427 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index e1a8e41f0..866e50825 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala index 7c48da84f..1db14727e 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala @@ -1,5 +1,5 @@ /** - * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. */ // DO NOT EDIT MANUALLY @@ -7,10 +7,10 @@ package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } trait IvyPathsFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val IvyPathsFormat: JsonFormat[sbt.librarymanagement.ivy.IvyPaths] = new JsonFormat[sbt.librarymanagement.ivy.IvyPaths] { - override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.IvyPaths = { - jsOpt match { - case Some(js) => - unbuilder.beginObject(js) + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.IvyPaths = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") val ivyHome = unbuilder.readField[Option[java.io.File]]("ivyHome") unbuilder.endObject() diff --git a/project/build.properties b/project/build.properties index 00b48d978..06703e34d 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.6 +sbt.version=1.3.9 diff --git a/project/plugins.sbt b/project/plugins.sbt index 0b4d75847..837b191e2 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,9 +1,9 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.0") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.2") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.6") +addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From c1dbeca90fcbeee97ad92b2106b39a2d07d8e4b8 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 28 May 2020 00:48:36 -0400 Subject: [PATCH 0877/1030] Ivy 2.3.0-sbt-839fad1cdc07cf6fc81364d74c323867230432ad --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 239d6c519..b6137bd8e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -41,7 +41,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-fa726854dd30be842ff9e6d2093df6adfe3871f5" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-839fad1cdc07cf6fc81364d74c323867230432ad" val sbtV = "1.0" val scalaV = "2.12" From 375613efbfed48889b02fedc5090dbc2133f77f9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 5 Jun 2020 18:59:08 -0400 Subject: [PATCH 0878/1030] Make validateProtocol return Boolean Ref https://github.com/sbt/sbt/issues/4905 To deprecate and unsupport HTTP, first log all the error messages out then throw at sbt level. --- build.sbt | 7 +++- .../sbt/librarymanagement/Artifact.scala | 2 +- .../librarymanagement/ChainedResolver.scala | 2 +- .../sbt/librarymanagement/MavenRepo.scala | 2 +- .../sbt/librarymanagement/Resolver.scala | 2 +- .../sbt/librarymanagement/URLRepository.scala | 2 +- .../main/contraband/librarymanagement.json | 10 +++--- .../sbt/librarymanagement/ResolverExtra.scala | 35 ++++++++++--------- 8 files changed, 35 insertions(+), 27 deletions(-) diff --git a/build.sbt b/build.sbt index b8f4787db..f6fd5c8e6 100644 --- a/build.sbt +++ b/build.sbt @@ -246,7 +246,12 @@ lazy val lmCore = (project in file("core")) ), exclude[ReversedMissingMethodProblem]( "sbt.librarymanagement.MavenRepository.allowInsecureProtocol" - ) + ), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateURLRepository"), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateMavenRepo"), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateArtifact"), + exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"), + ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index ad2dafa0c..86d7a218c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -14,7 +14,7 @@ final class Artifact private ( val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum], val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { - private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger) + private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger) private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index ebfa1fa6a..3fe0ce544 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement final class ChainedResolver private ( name: String, val resolvers: Vector[sbt.librarymanagement.Resolver]) extends sbt.librarymanagement.Resolver(name) with Serializable { - private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger)) + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = !resolvers.forall(!_.validateProtocol(logger)) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index b93d5b204..32ce0d0ab 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -12,7 +12,7 @@ final class MavenRepo private ( val _allowInsecureProtocol: Boolean) extends sbt.librarymanagement.MavenRepository(name, root, localIfFile) with Serializable { override def isCache: Boolean = false override def allowInsecureProtocol: Boolean = _allowInsecureProtocol - private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger) + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateMavenRepo(this, logger) private def this(name: String, root: String) = this(name, root, true, false) private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index 599fb562b..f4a7c9627 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -7,7 +7,7 @@ package sbt.librarymanagement abstract class Resolver( val name: String) extends Serializable { /** check for HTTP */ - private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = () + private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = false diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 11a19137f..9acb17c40 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -8,7 +8,7 @@ final class URLRepository private ( name: String, patterns: sbt.librarymanagement.Patterns, val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.PatternsBasedRepository(name, patterns) with Serializable { - private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger) + private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateURLRepository(this, logger) private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false) override def equals(o: Any): Boolean = o match { diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 67d655470..0b9d307fa 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -147,7 +147,7 @@ { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } ], "extra": [ - "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateArtifact(this, logger)" + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger)" ], "parentsCompanion": "sbt.librarymanagement.ArtifactFunctions" }, @@ -563,7 +563,7 @@ ], "extra": [ "/** check for HTTP */", - "private[sbt] def validateProtocol(logger: sbt.util.Logger): Unit = ()" + "private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = false" ], "types": [ { @@ -575,7 +575,7 @@ { "name": "resolvers", "type": "sbt.librarymanagement.Resolver*" } ], "extra": [ - "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = resolvers.foreach(_.validateProtocol(logger))" + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = !resolvers.forall(!_.validateProtocol(logger))" ] }, { @@ -603,7 +603,7 @@ "extra": [ "override def isCache: Boolean = false", "override def allowInsecureProtocol: Boolean = _allowInsecureProtocol", - "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateMavenRepo(this, logger)" + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateMavenRepo(this, logger)" ], "toString": "s\"$name: $root\"" }, @@ -676,7 +676,7 @@ { "name": "allowInsecureProtocol", "type": "boolean", "default": "false", "since": "1.3.0" } ], "extra": [ - "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Unit = Resolver.validateURLRepository(this, logger)" + "private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateURLRepository(this, logger)" ] }, { diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 33944a268..8f79c933d 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -404,8 +404,9 @@ private[librarymanagement] abstract class ResolverFunctions { Patterns().withIvyPatterns(pList).withArtifactPatterns(pList).withIsMavenCompatible(false) } + // to display all error messages at once, just log here don't throw private[sbt] def warnHttp(value: String, suggestion: String, logger: Logger): Unit = { - logger.warn(s"insecure HTTP request is deprecated '$value'; switch to HTTPS$suggestion") + logger.error(s"insecure HTTP request is unsupported '$value'; switch to HTTPS$suggestion") } private[sbt] def isInsecureUrl(str: String): Boolean = { // don't try to parse str as URL because it could contain $variable from Ivy pattern @@ -415,8 +416,8 @@ private[librarymanagement] abstract class ResolverFunctions { || str.startsWith("http://127.0.0.1/") || str.startsWith("http://127.0.0.1:")) } - private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Unit = { - if (repo.allowInsecureProtocol) () + private[sbt] def validateURLRepository(repo: URLRepository, logger: Logger): Boolean = { + if (repo.allowInsecureProtocol) false else { val patterns = repo.patterns val ivy = patterns.ivyPatterns.headOption match { @@ -430,34 +431,36 @@ private[librarymanagement] abstract class ResolverFunctions { if (ivy || art) { warnHttp( patterns.toString, - s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true)""", + s""" or opt-in as Resolver.url("${repo.name}", url(...)).withAllowInsecureProtocol(true), or by using allowInsecureProtocol in repositories file""", logger ) - } + true + } else false } } - private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Unit = - if (repo.allowInsecureProtocol) () + private[sbt] def validateMavenRepo(repo: MavenRepo, logger: Logger): Boolean = + if (repo.allowInsecureProtocol) false else if (isInsecureUrl(repo.root)) { warnHttp( repo.root, - s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true)""", + s""" or opt-in as ("${repo.name}" at "${repo.root}").withAllowInsecureProtocol(true), or by using allowInsecureProtocol in repositories file""", logger ) - } + true + } else false - private[sbt] def validateArtifact(art: Artifact, logger: Logger): Unit = - if (art.allowInsecureProtocol) () - else { - art.url foreach { url => - if (isInsecureUrl(url.toString)) { + private[sbt] def validateArtifact(art: Artifact, logger: Logger): Boolean = + if (art.allowInsecureProtocol) false + else + art.url match { + case Some(url) if isInsecureUrl(url.toString) => warnHttp( art.toString, " or opt-in using from(url(...), allowInsecureProtocol = true) on ModuleID or .withAllowInsecureProtocol(true) on Artifact", logger ) - } + true + case _ => false } - } } From f55b3c1c7a59f3838b7154d249caa3f6c6f07a0b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 9 Jun 2020 12:42:49 -0400 Subject: [PATCH 0879/1030] issue template --- .github/ISSUE_TEMPLATE/no-new-issues.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/no-new-issues.md diff --git a/.github/ISSUE_TEMPLATE/no-new-issues.md b/.github/ISSUE_TEMPLATE/no-new-issues.md new file mode 100644 index 000000000..a3fc484f9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/no-new-issues.md @@ -0,0 +1,9 @@ +--- +name: No new issues +about: Use https://github.com/sbt/sbt/issues/new/choose instead + +--- + +No new issues should be opened against this repo. + +Please use https://github.com/sbt/sbt/issues/new/choose to file an issue against sbt. From c8626e5402b5e6ee562e7f32a12251d666f26c8a Mon Sep 17 00:00:00 2001 From: Maksim Ochenashko Date: Wed, 17 Jun 2020 13:27:26 +0300 Subject: [PATCH 0880/1030] Update ConvertResolver.scala Add information on how to enable overwriting using `pushRemoteCache`. --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 43020d215..e158c09da 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -401,7 +401,11 @@ private[sbt] object ConvertResolver { |If you have a staging repository that has failed, drop it and start over. |Otherwise fix the double publishing, or relax the setting as follows: | publishConfiguration := publishConfiguration.value.withOverwrite(true) - | publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true)""".stripMargin, + | publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true) + | + |If you have a remote cache respoitory, you can enable overwriting as follows: + | pushRemoteCacheConfiguration := pushRemoteCacheConfiguration.value.withOverwrite(true) + |""".stripMargin, ex ) } From 5f4cbad6c4a41b0378c368a36aa26b0bb8c86e77 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 25 Jun 2020 23:24:43 -0400 Subject: [PATCH 0881/1030] support UNC path Fixes https://github.com/sbt/sbt/issues/5596 --- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 8f79c933d..b5ae222b2 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -4,7 +4,7 @@ package sbt.librarymanagement import java.io.{ IOException, File } -import java.net.URL +import java.net.{ URI, URL } import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger @@ -304,9 +304,13 @@ private[librarymanagement] abstract class ResolverFunctions { /** Constructs a file resolver with the given name and base directory. */ def apply(name: String, baseDirectory: File)(implicit basePatterns: Patterns): FileRepository = - baseRepository(new File(baseDirectory.toURI.normalize).getAbsolutePath)( + baseRepository( + new File(toUri(baseDirectory).normalize.getSchemeSpecificPart).getAbsolutePath + )( FileRepository(name, defaultFileConfiguration, _) ) + + private def toUri(dir: File): URI = dir.toPath.toUri } object url { From 9d87715100c99cddabf2845e0ec8a2cfa2e37bcd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 5 Aug 2020 00:08:23 -0400 Subject: [PATCH 0882/1030] Automatic eviction warning This extracts info.versionScheme from POM and uses that to guide the eviction report instead of taking a stab in the dark that all Scala libraries are using pvp. --- .../mavenint/SbtPomExtraProperties.java | 1 + .../librarymanagement/VersionSchemes.scala | 43 +++++++++++ .../librarymanagement/EvictionWarning.scala | 34 ++++++++- .../sbt/librarymanagement/VersionNumber.scala | 75 ++++++++++++++++++- .../librarymanagement/VersionNumberSpec.scala | 44 +++++++---- 5 files changed, 178 insertions(+), 19 deletions(-) create mode 100644 core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala diff --git a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java index 83addbc46..8bc61d549 100644 --- a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java +++ b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java @@ -13,6 +13,7 @@ public class SbtPomExtraProperties { public static final String POM_SCALA_VERSION = "scalaVersion"; public static final String POM_SBT_VERSION = "sbtVersion"; public static final String POM_API_KEY = "info.apiURL"; + public static final String VERSION_SCHEME_KEY = "info.versionScheme"; public static final String LICENSE_COUNT_KEY = "license.count"; diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala new file mode 100644 index 000000000..7e2179f34 --- /dev/null +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -0,0 +1,43 @@ +/* + * sbt + * Copyright 2011 - 2018, Lightbend, Inc. + * Copyright 2008 - 2010, Mark Harrah + * Licensed under Apache License 2.0 (see LICENSE) + */ + +package sbt +package internal +package librarymanagement + +import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties +import sbt.librarymanagement.ModuleID + +// See APIMappings.scala +private[sbt] object VersionSchemes { + final val EarlySemVer = "early-semver" + final val SemVerSpec = "semver-spec" + final val PackVer = "pvp" + + def validateScheme(value: String): Unit = + value match { + case EarlySemVer | SemVerSpec | PackVer => () + case "semver" => + sys.error( + s"""'semver' is ambiguous. + |Based on the Semantic Versioning 2.0.0, 0.y.z updates are all initial development and thus + |0.6.0 and 0.6.1 would NOT maintain any compatibility, but in Scala ecosystem it is + |common to start adopting binary compatibility even in 0.y.z releases. + | + |Specify 'early-semver' for the early variant. + |Specify 'semver-spec' for the spec-correct SemVer.""".stripMargin + ) + case x => sys.error(s"unknown version scheme: $x") + } + + /** info.versionScheme property will be included into POM after sbt 1.4.0. + */ + def extractFromId(mid: ModuleID): Option[String] = extractFromExtraAttributes(mid.extraAttributes) + + def extractFromExtraAttributes(extraAttributes: Map[String, String]): Option[String] = + extraAttributes.get(SbtPomExtraProperties.VERSION_SCHEME_KEY) +} diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index c090cd2ad..e8dff4e6f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -3,6 +3,7 @@ package sbt.librarymanagement import collection.mutable import Configurations.Compile import ScalaArtifacts.{ LibraryID, CompilerID } +import sbt.internal.librarymanagement.VersionSchemes import sbt.util.Logger import sbt.util.ShowLines @@ -136,6 +137,17 @@ object EvictionWarningOptions { } } + lazy val guessEarlySemVer + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (m1, Some(m2), _) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.EarlySemVer + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + lazy val guessFalse : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (_, _, _) => false @@ -290,9 +302,25 @@ object EvictionWarning { var binaryIncompatibleEvictionExists = false def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => - options.guessCompatible( - (r.module, p.winner map { _.module }, module.scalaModuleInfo) - ) + val winnerOpt = p.winner map { _.module } + val extraAttributes = (p.winner match { + case Some(r) => r.extraAttributes + case _ => Map.empty + }) ++ (winnerOpt match { + case Some(w) => w.extraAttributes + case _ => Map.empty + }) + val schemeOpt = VersionSchemes.extractFromExtraAttributes(extraAttributes) + val f = (winnerOpt, schemeOpt) match { + case (Some(_), Some(VersionSchemes.EarlySemVer)) => + EvictionWarningOptions.guessEarlySemVer + case (Some(_), Some(VersionSchemes.SemVerSpec)) => + EvictionWarningOptions.guessSemVer + case (Some(_), Some(VersionSchemes.PackVer)) => + EvictionWarningOptions.guessSecondSegment + case _ => options.guessCompatible(_) + } + f((r.module, winnerOpt, module.scalaModuleInfo)) } pairs foreach { case p if isScalaArtifact(module, p.organization, p.name) => diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 2437466cc..c8bef483d 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -167,9 +167,19 @@ object VersionNumber { * Also API compatibility is expected even when the first segment is zero. */ object SecondSegment extends VersionNumberCompatibility { + def name: String = "Second Segment Variant" + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = + PackVer.isCompatible(v1, v2) + } + + /** A variant of SemVar that seems to be common among the Scala libraries. + * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. + * Also API compatibility is expected even when the first segment is zero. + */ + object PackVer extends VersionNumberCompatibility { import SemVer._ - def name: String = "Second Segment Variant" + def name: String = "Package Versioning Policy" def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) @@ -182,6 +192,69 @@ object VersionNumber { } } } + + /** A variant of SemVar that enforces API compatibility when the first segment is zero. + */ + object EarlySemVer extends VersionNumberCompatibility { + import SemVer._ + + def name: String = "Early Semantic Versioning" + + /* Quotes of parts of the rules in the SemVer Spec relevant to compatibility checking: + * + * Rule 2: + * > A normal version number MUST take the form X.Y.Z + * + * Rule 6: + * > Patch version Z (x.y.Z | x > 0) MUST be incremented if only backwards compatible bug fixes are introduced. + * + * Rule 7: + * > Minor version Y (x.Y.z | x > 0) MUST be incremented if new, backwards compatible functionality is introduced. + * + * Rule 8: + * > Major version X (X.y.z | X > 0) MUST be incremented if any backwards incompatible changes are introduced. + * + * Rule 9: + * > A pre-release version MAY be denoted by appending a hyphen and a series of + * > dot separated identifiers immediately following the patch version. + * > Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + * > Identifiers MUST NOT be empty. + * > Numeric identifiers MUST NOT include leading zeroes. + * > Pre-release versions have a lower precedence than the associated normal version. + * > A pre-release version indicates that the version is unstable and might not satisfy the + * > intended compatibility requirements as denoted by its associated normal version. + * > Examples: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92. + * + * Rule 10: + * > Build metadata MAY be denoted by appending a plus sign and a series of + * > dot separated identifiers immediately following the patch or pre-release version. + * > Identifiers MUST comprise only ASCII alphanumerics and hyphen [0-9A-Za-z-]. + * > Identifiers MUST NOT be empty. + * > Build metadata SHOULD be ignored when determining version precedence. + * > Thus two versions that differ only in the build metadata, have the same precedence. + * > Examples: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85. + * + * Rule 10 means that build metadata is never considered for compatibility + * we'll enforce this immediately by dropping them from both versions + * Rule 2 we enforce with custom extractors. + * Rule 6, 7 & 8 means version compatibility is determined by comparing the two X values + * Rule 9.. + * Dale thinks means pre-release versions are fully equals checked.. + * Eugene thinks means pre-releases before 1.0.0 are not compatible, if not they are.. + * Rule 4 is modified in this variant. + */ + def isCompatible(v1: VersionNumber, v2: VersionNumber): Boolean = + doIsCompat(dropBuildMetadata(v1), dropBuildMetadata(v2)) + + private[this] def doIsCompat(v1: VersionNumber, v2: VersionNumber): Boolean = + (v1, v2) match { + case (NormalVersion(0, _, 0), NormalVersion(0, _, 0)) => v1 == v2 + case (NormalVersion(0, y1, _), NormalVersion(0, y2, _)) => y1 == y2 + case (NormalVersion(_, 0, 0), NormalVersion(_, 0, 0)) => v1 == v2 // R9 maybe? + case (NormalVersion(x1, _, _), NormalVersion(x2, _, _)) => x1 == x2 // R6, R7 & R8 + case _ => false + } + } } trait VersionNumberCompatibility { diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index eab52f6c9..7a7038fba 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -4,7 +4,7 @@ import org.scalatest.{ FreeSpec, Inside, Matchers } // This is a specification to check VersionNumber and VersionNumberCompatibility. class VersionNumberSpec extends FreeSpec with Matchers with Inside { - import VersionNumber.{ SemVer, SecondSegment } + import VersionNumber.{ EarlySemVer, SemVer, PackVer } version("1") { v => assertParsesTo(v, Seq(1), Seq(), Seq()) @@ -28,10 +28,15 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "2.0.0", SemVer) assertIsNotCompatibleWith(v, "1.0.0-M1", SemVer) - assertIsCompatibleWith(v, "1.0.1", SecondSegment) - assertIsNotCompatibleWith(v, "1.1.1", SecondSegment) - assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) - assertIsNotCompatibleWith(v, "1.0.0-M1", SecondSegment) + assertIsCompatibleWith(v, "1.0.1", EarlySemVer) + assertIsCompatibleWith(v, "1.1.1", EarlySemVer) + assertIsNotCompatibleWith(v, "2.0.0", EarlySemVer) + assertIsNotCompatibleWith(v, "1.0.0-M1", EarlySemVer) + + assertIsCompatibleWith(v, "1.0.1", PackVer) + assertIsNotCompatibleWith(v, "1.1.1", PackVer) + assertIsNotCompatibleWith(v, "2.0.0", PackVer) + assertIsNotCompatibleWith(v, "1.0.0-M1", PackVer) } version("1.0.0.0") { v => @@ -49,9 +54,13 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "0.12.1", SemVer) assertIsNotCompatibleWith(v, "0.12.1-M1", SemVer) - assertIsNotCompatibleWith(v, "0.12.0-RC1", SecondSegment) - assertIsCompatibleWith(v, "0.12.1", SecondSegment) - assertIsCompatibleWith(v, "0.12.1-M1", SecondSegment) + assertIsNotCompatibleWith(v, "0.12.0-RC1", EarlySemVer) + assertIsCompatibleWith(v, "0.12.1", EarlySemVer) + assertIsCompatibleWith(v, "0.12.1-M1", EarlySemVer) + + assertIsNotCompatibleWith(v, "0.12.0-RC1", PackVer) + assertIsCompatibleWith(v, "0.12.1", PackVer) + assertIsCompatibleWith(v, "0.12.1-M1", PackVer) } version("0.1.0-SNAPSHOT") { v => @@ -62,9 +71,13 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertIsNotCompatibleWith(v, "0.1.0", SemVer) assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SemVer) - assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", SecondSegment) - assertIsNotCompatibleWith(v, "0.1.0", SecondSegment) - assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", SecondSegment) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", EarlySemVer) + assertIsNotCompatibleWith(v, "0.1.0", EarlySemVer) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", EarlySemVer) + + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT", PackVer) + assertIsNotCompatibleWith(v, "0.1.0", PackVer) + assertIsCompatibleWith(v, "0.1.0-SNAPSHOT+001", PackVer) } version("0.1.0-M1") { v => @@ -86,7 +99,7 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) assertIsCompatibleWith(v, "2.0.0", SemVer) - assertIsNotCompatibleWith(v, "2.0.0", SecondSegment) + assertIsNotCompatibleWith(v, "2.0.0", PackVer) } version("20140115000117-b3a-sources") { v => @@ -187,9 +200,10 @@ class VersionNumberSpec extends FreeSpec with Matchers with Inside { ) = { val prefix = if (expectOutcome) "should" else "should NOT" val compatibilityStrategy = vnc match { - case SemVer => "SemVer" - case SecondSegment => "SecondSegment" - case _ => val s = vnc.name; if (s contains " ") s""""$s"""" else s + case SemVer => "SemVer" + case PackVer => "PackVer" + case EarlySemVer => "EarlySemVer" + case _ => val s = vnc.name; if (s contains " ") s""""$s"""" else s } s"$prefix be $compatibilityStrategy compatible with $v2" in { vnc.isCompatible(VersionNumber(v1.value), VersionNumber(v2)) shouldBe expectOutcome From fa0f85955240fb8567e721ab734b8fc4b5351df9 Mon Sep 17 00:00:00 2001 From: izharahmd Date: Sun, 13 Sep 2020 18:22:48 +0530 Subject: [PATCH 0883/1030] retry with backoff while publishing --- .../librarymanagement/LMSysProp.scala | 2 + .../librarymanagement/IvyActions.scala | 11 ++++- .../internal/librarymanagement/IvyUtil.scala | 44 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala index d2a28d3eb..58ac20824 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -60,4 +60,6 @@ object LMSysProp { } lazy val useGigahorse: Boolean = getOrFalse("sbt.gigahorse") + lazy val maxPublishAttempts: Int = java.lang.Integer.getInteger("sbt.repository.publish.attempts", 3) + } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index ffa2f733e..09e8b1e6b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -25,6 +25,7 @@ import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfigurat import syntax._ import InternalDefaults._ import UpdateClassifiersUtil._ +import sbt.internal.librarymanagement.IvyUtil.TransientNetworkException object IvyActions { @@ -497,8 +498,14 @@ object IvyActions { checkFilesPresent(artifacts) try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - for ((artifact, file) <- artifacts) - resolver.publish(artifact, file, overwrite) + artifacts.foreach { + case (artifact, file) => + IvyUtil.retryWithBackoff( + resolver.publish(artifact, file, overwrite), + TransientNetworkException.apply, + maxAttempts = LMSysProp.maxPublishAttempts + ) + } resolver.commitPublishTransaction() } catch { case e: Throwable => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala index 6c4622d90..181e49d89 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala @@ -1,6 +1,50 @@ package sbt.internal.librarymanagement +import java.io.IOException +import java.net.{ SocketException, SocketTimeoutException } + +import scala.annotation.tailrec +import scala.util.{ Failure, Success, Try } + private[sbt] object IvyUtil { def separate[A, B](l: Seq[Either[A, B]]): (Seq[A], Seq[B]) = (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) + + @tailrec + final def retryWithBackoff[T]( + f: => T, + predicate: Throwable => Boolean, + maxAttempts: Int, + retry: Int = 0 + ): T = { + // Using Try helps in catching NonFatal exceptions only + Try { + f + } match { + case Success(value) => value + case Failure(e) if predicate(e) && retry < (maxAttempts - 1) => + // max 8s backoff + val backoff = math.min(math.pow(2d, retry.toDouble).toLong * 1000L, 8000L) + Thread.sleep(backoff) + retryWithBackoff(f, predicate, maxAttempts, retry + 1) + case Failure(e) => throw e + } + } + + object TransientNetworkException { + private val _r = """.*HTTP response code: (503|429).*""".r + + @inline private def check(s: String): Boolean = { + if (s == null) return false + + _r.pattern.matcher(s).matches() + } + + def apply(t: Throwable): Boolean = t match { + case _: SocketException | _: SocketTimeoutException => true + case e: IOException if check(e.getMessage) => true + case _ => false + } + } + } From 39090fa0d3466e7b471c17986747439b0d4266cb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 21 Sep 2020 22:29:08 -0400 Subject: [PATCH 0884/1030] Formatting --- .../main/scala/sbt/internal/librarymanagement/LMSysProp.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala index 58ac20824..209e0cd11 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/LMSysProp.scala @@ -60,6 +60,7 @@ object LMSysProp { } lazy val useGigahorse: Boolean = getOrFalse("sbt.gigahorse") - lazy val maxPublishAttempts: Int = java.lang.Integer.getInteger("sbt.repository.publish.attempts", 3) + lazy val maxPublishAttempts: Int = + java.lang.Integer.getInteger("sbt.repository.publish.attempts", 3) } From 07e3815261a478a68b0c377e24c179d4e9124457 Mon Sep 17 00:00:00 2001 From: izharahmd Date: Tue, 29 Sep 2020 19:10:42 +0530 Subject: [PATCH 0885/1030] retry publish on all 5XX errors --- .../internal/librarymanagement/IvyUtil.scala | 8 ++- .../librarymanagement/IvyUtilSpec.scala | 66 +++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala index 181e49d89..c3437b595 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala @@ -31,8 +31,14 @@ private[sbt] object IvyUtil { } } + /** + * Currently transient network errors are defined as: + * - a network timeout + * - all server errors (response code 5xx) + * - rate limiting (response code 429) + */ object TransientNetworkException { - private val _r = """.*HTTP response code: (503|429).*""".r + private val _r = """.*HTTP response code: (5\d{2}|408|429).*""".r @inline private def check(s: String): Boolean = { if (s == null) return false diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala new file mode 100644 index 000000000..6924d739a --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala @@ -0,0 +1,66 @@ +package sbt.internal.librarymanagement + +import java.io.IOException + +import org.scalatest.FunSuite +import sbt.internal.librarymanagement.IvyUtil._ + +class IvyUtilSpec extends FunSuite { + test("503 should be a TransientNetworkException") { + val statusCode503Exception = + new IOException("Server returned HTTP response code: 503 for URL:") + assert(TransientNetworkException(statusCode503Exception)) + } + + test("500 should be a TransientNetworkException") { + val statusCode500Exception = + new IOException("Server returned HTTP response code: 500 for URL:") + assert(TransientNetworkException(statusCode500Exception)) + } + + test("408 should be a TransientNetworkException") { + val statusCode408Exception = + new IOException("Server returned HTTP response code: 408 for URL:") + assert(TransientNetworkException(statusCode408Exception)) + } + + test("429 should be a TransientNetworkException") { + val statusCode429Exception = + new IOException(" Server returned HTTP response code: 429 for URL:") + assert(TransientNetworkException(statusCode429Exception)) + } + + test("404 should not be a TransientNetworkException") { + val statusCode404Exception = + new IOException("Server returned HTTP response code: 404 for URL:") + assert(!TransientNetworkException(statusCode404Exception)) + } + + test("IllegalArgumentException should not be a TransientNetworkException") { + val illegalArgumentException = new IllegalArgumentException() + assert(!TransientNetworkException(illegalArgumentException)) + } + + test("it should retry for 3 attempts") { + var i = 0 + def f: Int = { + i += 1 + if (i < 3) throw new RuntimeException() else i + } + // exception predicate retries on all exceptions for this test + val result = retryWithBackoff(f, _ => true, maxAttempts = 3) + assert(result == 3) + } + + test("it should fail after maxAttempts") { + var i = 0 + def f: Int = { + i += 1 + throw new RuntimeException() + } + intercept[RuntimeException] { + retryWithBackoff(f, _ => true, maxAttempts = 3) + } + assert(i == 3) + } +} From f63adb4a8ac8adaad09f528b042cf3b28835010d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 4 Oct 2020 12:42:46 -0400 Subject: [PATCH 0886/1030] Util 1.4.0 --- build.sbt | 3 ++- .../internal/librarymanagement/IvyCache.scala | 27 ------------------- .../DMSerializationSpec.scala | 2 +- project/Dependencies.scala | 4 +-- project/build.properties | 2 +- project/plugins.sbt | 2 +- 6 files changed, 7 insertions(+), 33 deletions(-) diff --git a/build.sbt b/build.sbt index f6fd5c8e6..3fe9fff8f 100644 --- a/build.sbt +++ b/build.sbt @@ -16,7 +16,7 @@ ThisBuild / version := { else old } } - +ThisBuild / versionScheme := Some("early-semver") ThisBuild / organization := "org.scala-sbt" ThisBuild / bintrayPackage := "librarymanagement" ThisBuild / homepage := Some(url("https://github.com/sbt/librarymanagement")) @@ -338,6 +338,7 @@ lazy val lmIvy = (project in file("ivy")) exclude[DirectMissingMethodProblem]( "sbt.internal.librarymanagement.CustomPomParser.versionRangeFlag" ), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.FixedParser*"), ), ) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 9e8f28aa8..397f2e8d7 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -20,10 +20,6 @@ import sbt.librarymanagement._ import sbt.librarymanagement.ivy.{ InlineIvyConfiguration, IvyPaths } import sbt.util.Logger -import sjsonnew.shaded.scalajson.ast.unsafe._ -import scala.collection.mutable -import jawn.{ SupportParser, MutableFacade } - class NotInCache(val id: ModuleID, cause: Throwable) extends RuntimeException(NotInCache(id, cause), cause) { def this(id: ModuleID) = this(id, null) @@ -134,26 +130,3 @@ private class FileDownloader extends ResourceDownloader { sys.error("Could not move temporary file " + part + " to final location " + dest) } } - -object FixedParser extends SupportParser[JValue] { - implicit val facade: MutableFacade[JValue] = - new MutableFacade[JValue] { - def jnull() = JNull - def jfalse() = JFalse - def jtrue() = JTrue - def jnum(s: String) = JNumber(s) - def jint(s: String) = JNumber(s) - def jstring(s: String) = JString(s) - def jarray(vs: mutable.ArrayBuffer[JValue]) = JArray(vs.toArray) - def jobject(vs: mutable.Map[String, JValue]) = { - val array = new Array[JField](vs.size) - var i = 0 - vs.foreach { - case (key, value) => - array(i) = JField(key, value) - i += 1 - } - JObject(array) - } - } -} diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index ace394002..8ffd3ed1f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -98,5 +98,5 @@ object DMSerializationSpec extends BasicTestSuite { } implicit val isoString: IsoString[JValue] = - IsoString.iso(CompactPrinter.apply, FixedParser.parseUnsafe) + IsoString.iso(CompactPrinter.apply, Parser.parseUnsafe) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b6137bd8e..fcb7ecbbc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -7,8 +7,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.4.0-M2") - private val utilVersion = nightlyVersion.getOrElse("1.3.3") + private val ioVersion = nightlyVersion.getOrElse("1.4.0") + private val utilVersion = nightlyVersion.getOrElse("1.4.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/build.properties b/project/build.properties index 06703e34d..ea3a73ab1 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.9 +sbt.version=1.4.0-RC2 diff --git a/project/plugins.sbt b/project/plugins.sbt index 837b191e2..f2c5eaec0 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,7 +3,7 @@ addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.4.6") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.0") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From 388b4c20b58bc464bf0cfb1870cd961393651262 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 8 Nov 2020 18:51:05 -0500 Subject: [PATCH 0887/1030] Preparatory GitHub Actions This runs existing actions and then echoes hello --- .github/workflows/ci.yml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..ecbdf8a0c --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: CI +on: + pull_request: + push: + +jobs: + test: + strategy: + matrix: + include: + - os: ubuntu-latest + java: 8 + jobtype: 1 + - os: ubuntu-latest + java: 11 + jobtype: 1 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout + uses: actions/checkout@v1 + - name: Setup + uses: olafurpg/setup-scala@v10 + with: + java-version: "adopt@1.${{ matrix.java }}" + - name: Coursier cache + uses: coursier/cache-action@v5 + - name: Cache sbt + uses: actions/cache@v1 + with: + path: ~/.sbt + key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} + - name: Build and test + run: echo hello GitHub From 7583ef5f7716a00adc01c21020552d9645defef4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 8 Nov 2020 19:04:16 -0500 Subject: [PATCH 0888/1030] Migrate to GitHub Actions --- .github/workflows/ci.yml | 18 +++++++++++- .travis.yml | 59 ---------------------------------------- 2 files changed, 17 insertions(+), 60 deletions(-) delete mode 100644 .travis.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ecbdf8a0c..458788d42 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,8 @@ jobs: java: 11 jobtype: 1 runs-on: ${{ matrix.os }} + env: + JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout uses: actions/checkout@v1 @@ -30,4 +32,18 @@ jobs: path: ~/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Build and test - run: echo hello GitHub + run: | + case ${{ matrix.jobtype }} in + 1) + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies test packagedArtifacts + ;; + *) + echo unknown jobtype + exit 1 + esac + rm -rf "$HOME/.ivy2/local" + find $HOME/Library/Caches/Coursier/v1 -name "ivydata-*.properties" -delete || true + find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete || true + find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete || true + find $HOME/.cache/coursier/v1 -name "ivydata-*.properties" -delete || true + find $HOME/.sbt -name "*.lock" -delete || true diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index d06d8f6c1..000000000 --- a/.travis.yml +++ /dev/null @@ -1,59 +0,0 @@ -dist: xenial -group: stable - -language: scala - -scala: - - 2.12.10 - -env: - global: - - secure: D9Ckfxq/5n+41REwuPBwb0CHRVSPtCJRN+N1FWNFjUnfCHZQCeclP8Ydp9ql/fZxICG8rnCOI5XW0j2YeAiR+abpQNmQ42pKMEjNT0VQDZ0I1lQfiDL071Kj+ui9AH+TqAvBT011u72ML52iDfV0WaL/Skf1Noh0lXc+IscRI56OLRv+YU5n5aNZhXon6AZHU11rRCg4aMwaHr+U9ISSUXc6OtJeFC/SAYNUNYEOZwTOJ4Y2+VrKAmKuIZ2jjkMF13eKMzXw5g+u8V3AmOpIm1RiyS2dAgAoc+r2ucF9RUMsfiZIF0XBu65iv9hZP5m0q11n6IFEKC9bpLsTYCAwX2MgVayoHvDQv1gkL/cA1gkqmf0Kkx3oc33aYLgsCydj2Lbg/myKD+GeHxr5WhyeSEee3Bwj+KGNwvjfcaPEECCor6yilKGdIsuYbfHzu8B8moNjwH7ui5f5w/1xuWrdaSA23LOIYbhP+2rM894JIYNNt5vlMLoYMzmC9N1E/qyBRYSdfMr+Uh8qI+j85hkKKgEffSu9f55IH6bk6Lq08Nc4d64KXUISDNJj59MrJcadatsS2vp+u39zR/iIewW4a017bAFfv57AJb6SwLdvASG+psFH8MRPD6xYPZKNw4Al/4YMc+oXONplSXyOu/jQYjSfK9tyvJwpoY7tLh6vEBc= - -matrix: - include: - - env: - - ADOPTOPENJDK=11 - - env: - - ADOPTOPENJDK=8 - -before_install: - # adding $HOME/.sdkman to cache would create an empty directory, which interferes with the initial installation - - "[[ -d $HOME/.sdkman/bin/ ]] || rm -rf $HOME/.sdkman/" - - curl -sL https://get.sdkman.io | bash - - echo sdkman_auto_answer=true > $HOME/.sdkman/etc/config - - echo sdkman_auto_selfupdate=true >> $HOME/.sdkman/etc/config - - source "$HOME/.sdkman/bin/sdkman-init.sh" - -install: - - sdk install java $(sdk list java | grep -o "$ADOPTOPENJDK\.[0-9\.]*hs-adpt" | head -1) || true - - bin/fixpreloaded.sh - - unset JAVA_HOME - - java -Xmx32m -version - # detect sbt version from project/build.properties - - export TRAVIS_SBT=$(grep sbt.version= project/build.properties | sed -e 's/sbt.version=//g' ) && echo "sbt $TRAVIS_SBT" - # - export TRAVIS_SBT=1.3.3 - - sdk install sbt $TRAVIS_SBT || true - # override Travis CI's SBT_OPTS - - unset SBT_OPTS - - export JAVA_OPTS="-Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M" - -script: sbt -Dfile.encoding=UTF8 - ++$TRAVIS_SCALA_VERSION! - mimaReportBinaryIssues - scalafmtCheckAll - whitesourceCheckPolicies - test - packagedArtifacts # ensure that all artifacts for publish package without failure - -before_cache: - # - find $HOME/.ivy2/local -name "*-LM-SNAPSHOT*" -exec rm -r "{}" \; - - find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete - - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete - - find $HOME/.sbt -name "*.lock" -delete - -cache: - directories: - - $HOME/.ivy2/cache - - $HOME/.sbt/boot - - $HOME/.sdkman From 796ab41db0d90bb35ef83e4e46f0d1bb19f10a3c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 9 Nov 2020 14:16:48 -0500 Subject: [PATCH 0889/1030] sbt-extras uses different environment variable name --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 458788d42..e1826f816 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,7 +16,9 @@ jobs: jobtype: 1 runs-on: ${{ matrix.os }} env: + # define Java options for both official sbt and sbt-extras JAVA_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M + JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout uses: actions/checkout@v1 From b7d4614f540fe024c04b1f1c82ce88cd288dc983 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 9 Nov 2020 14:30:11 -0500 Subject: [PATCH 0890/1030] Use HOME --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e1826f816..11c60e597 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,7 +31,7 @@ jobs: - name: Cache sbt uses: actions/cache@v1 with: - path: ~/.sbt + path: $HOME/.sbt key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - name: Build and test run: | From f8f9ed0c677d0584201263d69e8d4a653b29d8ab Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 14 Nov 2020 12:31:34 -0500 Subject: [PATCH 0891/1030] Nightly setup --- build.sbt | 33 +++++++++++++++++++++------------ project/Dependencies.scala | 3 ++- project/build.properties | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/build.sbt b/build.sbt index 3fe9fff8f..1157395d7 100644 --- a/build.sbt +++ b/build.sbt @@ -7,15 +7,6 @@ val _ = { sys.props += ("line.separator" -> "\n") } -ThisBuild / version := { - val old = (ThisBuild / version).value - nightlyVersion match { - case Some(v) => v - case _ => - if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" - else old - } -} ThisBuild / versionScheme := Some("early-semver") ThisBuild / organization := "org.scala-sbt" ThisBuild / bintrayPackage := "librarymanagement" @@ -375,11 +366,29 @@ def customCommands: Seq[Setting[_]] = Seq( } ) +ThisBuild / version := { + val old = (ThisBuild / version).value + nightlyVersion match { + case Some(v) => v + case _ => + if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + else old + } +} +def githubPackageRegistry: Option[Resolver] = + sys.env.get("RELEASE_GITHUB_PACKAGE_REGISTRY") map { repo => + s"GitHub Package Registry ($repo)" at s"https://maven.pkg.github.com/$repo" + } ThisBuild / publishTo := { val old = (ThisBuild / publishTo).value - sys.props.get("sbt.build.localmaven") match { - case Some(path) => Some(MavenCache("local-maven", file(path))) - case _ => old + githubPackageRegistry orElse old +} +ThisBuild / resolvers ++= githubPackageRegistry.toList +ThisBuild / credentials ++= { + sys.env.get("GITHUB_TOKEN") match { + case Some(token) => + List(Credentials("GitHub Package Registry", "maven.pkg.github.com", "unused", token)) + case _ => Nil } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index fcb7ecbbc..f4dc77eb2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,8 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.10" - def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") + def nightlyVersion: Option[String] = + sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.4.0") private val utilVersion = nightlyVersion.getOrElse("1.4.0") diff --git a/project/build.properties b/project/build.properties index ea3a73ab1..c19c768d6 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.0-RC2 +sbt.version=1.4.2 From 349a4134e5d9122cd87bf29d4bc70619ae6b8c3c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 15 Nov 2020 00:58:52 -0500 Subject: [PATCH 0892/1030] Use Bintray for nightly --- build.sbt | 50 +++++++++++++--------------------- project/DatatypeConfig.scala | 12 ++++---- project/HouseRulesPlugin.scala | 4 ++- project/Util.scala | 10 ++++--- 4 files changed, 34 insertions(+), 42 deletions(-) diff --git a/build.sbt b/build.sbt index 1157395d7..62640cfb8 100644 --- a/build.sbt +++ b/build.sbt @@ -7,9 +7,18 @@ val _ = { sys.props += ("line.separator" -> "\n") } +ThisBuild / version := { + val old = (ThisBuild / version).value + nightlyVersion match { + case Some(v) => v + case _ => + if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + else old + } +} ThisBuild / versionScheme := Some("early-semver") ThisBuild / organization := "org.scala-sbt" -ThisBuild / bintrayPackage := "librarymanagement" +ThisBuild / bintrayPackage := sys.env.get("BINTRAY_PACKAGE").getOrElse("librarymanagement") ThisBuild / homepage := Some(url("https://github.com/sbt/librarymanagement")) ThisBuild / description := "Library management module for sbt" ThisBuild / scmInfo := { @@ -238,11 +247,16 @@ lazy val lmCore = (project in file("core")) exclude[ReversedMissingMethodProblem]( "sbt.librarymanagement.MavenRepository.allowInsecureProtocol" ), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateURLRepository"), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateMavenRepo"), - exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.ResolverFunctions.validateArtifact"), + exclude[IncompatibleResultTypeProblem]( + "sbt.librarymanagement.ResolverFunctions.validateURLRepository" + ), + exclude[IncompatibleResultTypeProblem]( + "sbt.librarymanagement.ResolverFunctions.validateMavenRepo" + ), + exclude[IncompatibleResultTypeProblem]( + "sbt.librarymanagement.ResolverFunctions.validateArtifact" + ), exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"), - ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -366,32 +380,6 @@ def customCommands: Seq[Setting[_]] = Seq( } ) -ThisBuild / version := { - val old = (ThisBuild / version).value - nightlyVersion match { - case Some(v) => v - case _ => - if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" - else old - } -} -def githubPackageRegistry: Option[Resolver] = - sys.env.get("RELEASE_GITHUB_PACKAGE_REGISTRY") map { repo => - s"GitHub Package Registry ($repo)" at s"https://maven.pkg.github.com/$repo" - } -ThisBuild / publishTo := { - val old = (ThisBuild / publishTo).value - githubPackageRegistry orElse old -} -ThisBuild / resolvers ++= githubPackageRegistry.toList -ThisBuild / credentials ++= { - sys.env.get("GITHUB_TOKEN") match { - case Some(token) => - List(Credentials("GitHub Package Registry", "maven.pkg.github.com", "unused", token)) - case _ => Nil - } -} - inThisBuild( Seq( whitesourceProduct := "Lightbend Reactive Platform", diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index 774f77ee5..e87492601 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -44,12 +44,12 @@ object DatatypeConfig { case "sbt.librarymanagement.CrossVersion" => { _ => "sbt.librarymanagement.CrossVersionFormats" :: - "sbt.librarymanagement.DisabledFormats" :: - "sbt.librarymanagement.BinaryFormats" :: - "sbt.librarymanagement.ConstantFormats" :: - "sbt.librarymanagement.PatchFormats" :: - "sbt.librarymanagement.FullFormats" :: - Nil + "sbt.librarymanagement.DisabledFormats" :: + "sbt.librarymanagement.BinaryFormats" :: + "sbt.librarymanagement.ConstantFormats" :: + "sbt.librarymanagement.PatchFormats" :: + "sbt.librarymanagement.FullFormats" :: + Nil } // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index 8c8958c4f..f204ee310 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -1,3 +1,5 @@ +package lmbuild + import sbt._ import Keys._ import bintray.BintrayPlugin @@ -12,7 +14,7 @@ object HouseRulesPlugin extends AutoPlugin { lazy val baseBuildSettings: Seq[Def.Setting[_]] = Seq( bintrayOrganization := Some("sbt"), - bintrayRepository := "maven-releases", + bintrayRepository := sys.env.get("BINTRAY_REPOSITORY").getOrElse("maven-releases"), ) lazy val baseSettings: Seq[Def.Setting[_]] = Seq( diff --git a/project/Util.scala b/project/Util.scala index 3b1ead60a..172b36423 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -16,10 +16,12 @@ object Util { lastCompilation.map(_.getStartTime) getOrElse 0L } - def generateVersionFile(version: String, - dir: File, - s: TaskStreams, - analysis: CompileAnalysis): Seq[File] = { + def generateVersionFile( + version: String, + dir: File, + s: TaskStreams, + analysis: CompileAnalysis + ): Seq[File] = { import java.util.{ Date, TimeZone } val formatter = new java.text.SimpleDateFormat("yyyyMMdd'T'HHmmss") formatter.setTimeZone(TimeZone.getTimeZone("GMT")) From 8b12c2bfa6a89c2962258b6435ad757110c9e71b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erwan=20Queff=C3=A9lec?= Date: Sun, 22 Nov 2020 09:41:25 +0100 Subject: [PATCH 0893/1030] Update Ivy to the latest version --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f4dc77eb2..186ffe67b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -42,7 +42,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-839fad1cdc07cf6fc81364d74c323867230432ad" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-fbc4f586aeeb1591710b14eb4f41b94880dcd745" val sbtV = "1.0" val scalaV = "2.12" From f1ede7cd0655e859ea0708d5268d66b308acf538 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 16 Dec 2020 14:52:30 +0100 Subject: [PATCH 0894/1030] Add Scala 3 binary versioning --- .../cross/CrossVersionUtil.scala | 21 ++++++++++--- .../librarymanagement/CrossVersionTest.scala | 31 +++++++++++++++++-- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index c95f035f1..8cd43fe55 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -1,6 +1,8 @@ package sbt.internal.librarymanagement package cross +import sbt.librarymanagement.ScalaArtifacts + object CrossVersionUtil { val trueString = "true" val falseString = "false" @@ -8,7 +10,6 @@ object CrossVersionUtil { val noneString = "none" val disabledString = "disabled" val binaryString = "binary" - val TransitionDottyVersion = "" // Dotty always respects binary compatibility val TransitionScalaVersion = "2.10" // ...but scalac doesn't until Scala 2.10 val TransitionSbtVersion = "0.12" @@ -22,8 +23,9 @@ object CrossVersionUtil { private val longPattern = """\d{1,19}""" private val basicVersion = raw"""($longPattern)\.($longPattern)\.($longPattern)""" private val ReleaseV = raw"""$basicVersion(-\d+)?""".r - private val BinCompatV = raw"""$basicVersion-bin(-.*)?""".r + private val BinCompatV = raw"""$basicVersion(-\w+)?-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r + private val MilestonV = raw"""$basicVersion(-M\d+)""".r private val NonReleaseV_n = raw"""$basicVersion([-\w]*)""".r // 0-n word suffixes, with leading dashes private val NonReleaseV_1 = raw"""$basicVersion(-\w+)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r @@ -61,7 +63,7 @@ object CrossVersionUtil { */ private[sbt] def scalaApiVersion(v: String): Option[(Long, Long)] = v match { case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) - case BinCompatV(x, y, _, _) => Some((x.toLong, y.toLong)) + case BinCompatV(x, y, _, _, _) => Some((x.toLong, y.toLong)) case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toLong, y.toLong)) case _ => None } @@ -72,9 +74,18 @@ object CrossVersionUtil { case _ => None } + private[sbt] def binaryScala3Version(full: String): String = full match { + case ReleaseV(maj, _, _, _) => maj + case CandidateV(maj, min, _, _) if min.toLong > 0 => maj + case MilestonV(maj, min, _, _) if min.toLong > 0 => maj + case BinCompatV(maj, min, patch, stage, _) => binaryScala3Version(s"$maj.$min.$patch$stage") + case _ => full + } + def binaryScalaVersion(full: String): String = { - val cutoff = if (full.startsWith("0.")) TransitionDottyVersion else TransitionScalaVersion - binaryVersionWithApi(full, cutoff)(scalaApiVersion) + if (ScalaArtifacts.isScala3(full)) binaryScala3Version(full) + else + binaryVersionWithApi(full, TransitionScalaVersion)(scalaApiVersion) // Scala 2 binary version } def binarySbtVersion(full: String): String = diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 5ba8d8b72..5864a4012 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -207,8 +207,35 @@ class CrossVersionTest extends UnitSpec { it should "for 2.20170314093845.0-87654321 return 2.20170314093845" in { binaryScalaVersion("2.20170314093845.0-87654321") shouldBe "2.20170314093845" } - it should "for Dotty 0.1.1 return 0.1" in { - binaryScalaVersion("0.1.1") shouldBe "0.1" + it should "for 3.0.0-M2 return 3.0.0-M2" in { + binaryScalaVersion("3.0.0-M2") shouldBe "3.0.0-M2" + } + it should "for 3.0.0-M3-bin-SNAPSHOT return 3.0.0-M3" in { + binaryScalaVersion("3.0.0-M3-bin-SNAPSHOT") shouldBe "3.0.0-M3" + } + it should "for 3.0.0-M3-bin-20201215-cbe50b3-NIGHTLY return 3.0.0-M3" in { + binaryScalaVersion("3.0.0-M3-bin-20201215-cbe50b3-NIGHTLY") shouldBe "3.0.0-M3" + } + it should "for 3.0.0-RC1 return 3.0.0-RC1" in { + binaryScalaVersion("3.0.0-RC1") shouldBe "3.0.0-RC1" + } + + // Not set in stone but 3 is the favorite candidate so far + // (see https://github.com/lampepfl/dotty/issues/10244) + it should "for 3.0.0 return 3" in { + binaryScalaVersion("3.0.0") shouldBe "3" + } + it should "for 3.1.0-M1 return 3" in { + binaryScalaVersion("3.1.0-M1") shouldBe "3" + } + it should "for 3.1.0-RC1-bin-SNAPSHOT return 3" in { + binaryScalaVersion("3.1.0-RC1-bin-SNAPSHOT") shouldBe "3" + } + it should "for 3.1.0-RC1 return 3" in { + binaryScalaVersion("3.1.0-RC1") shouldBe "3" + } + it should "for 3.1.0 return 3" in { + binaryScalaVersion("3.1.0") shouldBe "3" } private def patchVersion(fullVersion: String) = From 48b2a7a0a1f7eb773853f93853e8b7bfd009b901 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 16 Dec 2020 14:52:49 +0100 Subject: [PATCH 0895/1030] Add Scala 3 artifacts --- .../librarymanagement/ScalaArtifacts.scala | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index e0b1b6be5..2d25f86d1 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -8,27 +8,46 @@ object ScalaArtifacts { val ActorsID = "scala-actors" val ScalapID = "scalap" val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) - val DottyIDPrefix = "dotty" - def dottyID(binaryVersion: String): String = s"${DottyIDPrefix}_${binaryVersion}" + val Scala3LibraryID = "scala3-library" + val Scala3CompilerID = "scala3-compiler" - def libraryDependency(version: String): ModuleID = ModuleID(Organization, LibraryID, version) + def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.") + + def libraryIds(version: String): Array[String] = { + if (isScala3(version)) + Array(Scala3LibraryID, LibraryID) + else Array(LibraryID) + } + + def compilerId(version: String): String = { + if (isScala3(version)) Scala3CompilerID + else CompilerID + } + + def libraryDependency(version: String): ModuleID = libraryDependency(Organization, version) + + def libraryDependency(org: String, version: String): ModuleID = { + if (isScala3(version)) + ModuleID(org, Scala3LibraryID, version).withCrossVersion(CrossVersion.binary) + else + ModuleID(org, LibraryID, version) + } private[sbt] def toolDependencies( org: String, - version: String, - isDotty: Boolean = false + version: String ): Seq[ModuleID] = - if (isDotty) + if (isScala3(version)) Seq( - ModuleID(org, DottyIDPrefix, version) + ModuleID(org, Scala3CompilerID, version) .withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) .withCrossVersion(CrossVersion.binary) ) else Seq( - scalaToolDependency(org, ScalaArtifacts.CompilerID, version), - scalaToolDependency(org, ScalaArtifacts.LibraryID, version) + scalaToolDependency(org, CompilerID, version), + scalaToolDependency(org, LibraryID, version) ) private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = From 24f85fd18c226ebfd374d2633a721dc968b43adb Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 18 Dec 2020 16:55:36 +0100 Subject: [PATCH 0896/1030] Adapt ScalaOverride to Scala 3 --- .../librarymanagement/ScalaArtifacts.scala | 32 +++- .../librarymanagement/IvyScalaUtil.scala | 51 +++--- .../librarymanagement/ScalaOverrideTest.scala | 167 +++++++++++++++--- 3 files changed, 198 insertions(+), 52 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index 2d25f86d1..dc667a4c8 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -1,16 +1,30 @@ package sbt.librarymanagement object ScalaArtifacts { - val Organization = "org.scala-lang" - val LibraryID = "scala-library" - val CompilerID = "scala-compiler" - val ReflectID = "scala-reflect" - val ActorsID = "scala-actors" - val ScalapID = "scalap" - val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) + final val Organization = "org.scala-lang" + final val LibraryID = "scala-library" + final val CompilerID = "scala-compiler" + final val ReflectID = "scala-reflect" + final val ActorsID = "scala-actors" + final val ScalapID = "scalap" + final val Artifacts = Vector(LibraryID, CompilerID, ReflectID, ActorsID, ScalapID) - val Scala3LibraryID = "scala3-library" - val Scala3CompilerID = "scala3-compiler" + final val Scala3LibraryID = "scala3-library" + final val Scala3CompilerID = "scala3-compiler" + final val Scala3InterfacesID = "scala3-interfaces" + final val TastyCoreID = "tasty-core" + + private[sbt] final val Scala3LibraryPrefix = Scala3LibraryID + "_" + private[sbt] final val Scala3CompilerPrefix = Scala3CompilerID + "_" + private[sbt] final val TastyCorePrefix = TastyCoreID + "_" + + def isScala2Artifact(name: String): Boolean = { + name == LibraryID || name == CompilerID || name == ReflectID || name == ActorsID || name == ScalapID + } + def isScala3Artifact(name: String): Boolean = { + name.startsWith(Scala3LibraryPrefix) || name.startsWith(Scala3CompilerPrefix) || + name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID + } def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.") diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index e318eb6c2..2a4e4a27f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -12,7 +12,7 @@ import org.apache.ivy.plugins.matcher.ExactPatternMatcher import org.apache.ivy.plugins.namespace.NamespaceTransformer import sbt.util.Logger import sbt.librarymanagement.ScalaArtifacts._ -import sbt.librarymanagement.{ ScalaModuleInfo, CrossVersion, Configuration } +import sbt.librarymanagement.{ Configuration, CrossVersion, ScalaModuleInfo } object IvyScalaUtil { @@ -48,38 +48,43 @@ object IvyScalaUtil { scalaVersionConfigs0: Vector[String] ) extends DependencyDescriptorMediator { private[this] val scalaVersionConfigs = scalaVersionConfigs0.toSet + private val binaryVersion = CrossVersion.binaryScalaVersion(scalaVersion) def mediate(dd: DependencyDescriptor): DependencyDescriptor = { // Mediate only for the dependencies in scalaVersion configurations. https://github.com/sbt/sbt/issues/2786 def configQualifies: Boolean = - (dd.getModuleConfigurations exists { scalaVersionConfigs }) + dd.getModuleConfigurations exists { scalaVersionConfigs } // Do not rewrite the dependencies of Scala dependencies themselves, this prevents bootstrapping // a Scala compiler using another Scala compiler. def dependeeQualifies: Boolean = - dd.getParentRevisionId == null || ( - dd.getParentRevisionId.getName match { - case _ @(CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) => - false - case _ => - true - } - ) + dd.getParentRevisionId == null || + !isScala2Artifact(dd.getParentRevisionId.getName) || + !isScala3Artifact(dd.getParentRevisionId.getName) + + def matchBinaryVersion(version: String): Boolean = + CrossVersion.binaryScalaVersion(version) == binaryVersion + val transformer = new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid - else - mrid.getName match { - case name @ (CompilerID | LibraryID | ReflectID | ActorsID | ScalapID) - if configQualifies && dependeeQualifies => - ModuleRevisionId.newInstance( - scalaOrganization, - name, - mrid.getBranch, - scalaVersion, - mrid.getQualifiedExtraAttributes - ) - case _ => mrid - } + else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && + configQualifies && + dependeeQualifies) { + // do not override the binary incompatible Scala version because: + // - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library + // - the Scala 2 TASTy reader can consume the Scala 3 artifacts + val newScalaVersion = + if (matchBinaryVersion(mrid.getRevision)) scalaVersion + else mrid.getRevision + + ModuleRevisionId.newInstance( + scalaOrganization, + mrid.getName, + mrid.getBranch, + newScalaVersion, + mrid.getQualifiedExtraAttributes + ) + } else mrid } def isIdentity: Boolean = false diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index d9ed46cf3..37a82432f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -11,10 +11,13 @@ import verify.BasicTestSuite object ScalaOverrideTest extends BasicTestSuite { val OtherOrgID = "other.org" - def check(org0: String, version0: String)(org1: String, name1: String, version1: String) = { - val scalaConfigs = Configurations.default.toVector filter { Configurations.underScalaVersion } map { - _.name - } + private val scalaConfigs = + Configurations.default.filter(Configurations.underScalaVersion).map(_.name) + + def checkOrgAndVersion( + org0: String, + version0: String + )(org1: String, name1: String, version1: String): Unit = { val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) val mrid = ModuleRevisionId.newInstance(org1, name1, version1) @@ -25,8 +28,36 @@ object ScalaOverrideTest extends BasicTestSuite { assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version0)) } - test("""OverrideScalaMediator should override compiler version""") { - check(Organization, "2.11.8")( + def checkOnlyOrg( + org0: String, + version0: String + )(org1: String, name1: String, version1: String): Unit = { + val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) + + val mrid = ModuleRevisionId.newInstance(org1, name1, version1) + val dd = new DefaultDependencyDescriptor(mrid, false) + dd.addDependencyConfiguration("compile", "compile") + + val res = osm.mediate(dd) + assert(res.getDependencyRevisionId == ModuleRevisionId.newInstance(org0, name1, version1)) + } + + def checkNoOverride( + org0: String, + version0: String + )(org1: String, name1: String, version1: String): Unit = { + val osm = new OverrideScalaMediator(org0, version0, scalaConfigs) + + val mrid = ModuleRevisionId.newInstance(org1, name1, version1) + val dd = new DefaultDependencyDescriptor(mrid, false) + dd.addDependencyConfiguration("compile", "compile") + + val res = osm.mediate(dd) + assert(res.getDependencyRevisionId == mrid) + } + + test("OverrideScalaMediator should override compiler version") { + checkOrgAndVersion(Organization, "2.11.8")( Organization, CompilerID, "2.11.9" @@ -34,7 +65,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override library version") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( Organization, LibraryID, "2.11.8" @@ -42,7 +73,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override reflect version") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( Organization, ReflectID, "2.11.7" @@ -50,7 +81,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override actors version") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( Organization, ActorsID, "2.11.6" @@ -58,7 +89,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override scalap version") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( Organization, ScalapID, "2.11.5" @@ -66,7 +97,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override default compiler organization") { - check(OtherOrgID, "2.11.8")( + checkOrgAndVersion(OtherOrgID, "2.11.8")( Organization, CompilerID, "2.11.9" @@ -74,7 +105,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override default library organization") { - check(OtherOrgID, "2.11.8")( + checkOrgAndVersion(OtherOrgID, "2.11.8")( Organization, LibraryID, "2.11.8" @@ -82,7 +113,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override default reflect organization") { - check(OtherOrgID, "2.11.8")( + checkOrgAndVersion(OtherOrgID, "2.11.8")( Organization, ReflectID, "2.11.7" @@ -90,7 +121,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override default actors organization") { - check(OtherOrgID, "2.11.8")( + checkOrgAndVersion(OtherOrgID, "2.11.8")( Organization, ActorsID, "2.11.6" @@ -98,7 +129,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override default scalap organization") { - check(OtherOrgID, "2.11.8")( + checkOrgAndVersion(OtherOrgID, "2.11.8")( Organization, ScalapID, "2.11.5" @@ -106,7 +137,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override custom compiler organization") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( OtherOrgID, CompilerID, "2.11.9" @@ -114,7 +145,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override custom library organization") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( OtherOrgID, LibraryID, "2.11.8" @@ -122,7 +153,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override custom reflect organization") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( OtherOrgID, ReflectID, "2.11.7" @@ -130,7 +161,7 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override custom actors organization") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( OtherOrgID, ActorsID, "2.11.6" @@ -138,10 +169,106 @@ object ScalaOverrideTest extends BasicTestSuite { } test("it should override custom scalap organization") { - check(Organization, "2.11.8")( + checkOrgAndVersion(Organization, "2.11.8")( OtherOrgID, ScalapID, "2.11.5" ) } + + test("it should override Scala 3 compiler version") { + checkOrgAndVersion(Organization, "3.1.0")( + Organization, + Scala3CompilerPrefix + "3", + "3.0.0" + ) + } + + test("it should override Scala 3 library version") { + checkOrgAndVersion(Organization, "3.1.0")( + Organization, + Scala3LibraryPrefix + "3", + "3.0.0" + ) + } + + test("it should override Scala 3 interfaces version") { + checkOrgAndVersion(Organization, "3.1.0")( + Organization, + Scala3InterfacesID, + "3.0.0" + ) + } + + test("it should override TASTy core version") { + checkOrgAndVersion(Organization, "3.1.0")( + Organization, + TastyCorePrefix + "3", + "3.0.0" + ) + } + + test("it should not override Scala 2 library version when using Scala 3") { + checkNoOverride(Organization, "3.1.0")( + Organization, + LibraryID, + "2.13.4" + ) + } + + test("it should not override TASTy core version when using Scala 2") { + checkNoOverride(Organization, "2.13.4")( + Organization, + TastyCorePrefix + "3", + "3.0.0" + ) + } + + test("it should override default Scala 3 compiler organization") { + checkOrgAndVersion(OtherOrgID, "3.1.0")( + Organization, + Scala3CompilerPrefix + "3", + "3.0.0" + ) + } + + test("it should override default Scala 3 library organization") { + checkOrgAndVersion(OtherOrgID, "3.1.0")( + Organization, + Scala3LibraryPrefix + "3", + "3.0.0" + ) + } + + test("it should override default Scala 3 interfaces organization") { + checkOrgAndVersion(OtherOrgID, "3.1.0")( + Organization, + Scala3InterfacesID, + "3.0.0" + ) + } + + test("it should override default Scala 3 TASTy core organization") { + checkOrgAndVersion(OtherOrgID, "3.1.0")( + Organization, + TastyCorePrefix + "3", + "3.0.0" + ) + } + + test("it should override default Scala 2 library organization when in Scala 3") { + checkOnlyOrg(OtherOrgID, "3.1.0")( + Organization, + LibraryID, + "2.13.4" + ) + } + + test("it should override default TASTy core organization when in Scala 2") { + checkOnlyOrg(OtherOrgID, "2.13.4")( + Organization, + TastyCorePrefix + "3", + "3.0.0" + ) + } } From 2308d0a3a7d411122c5f60b3f454748fabc9a716 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 19 Dec 2020 17:08:24 -0500 Subject: [PATCH 0897/1030] Fixes match error when using withDottyCompat Fixes https://github.com/sbt/sbt/issues/6210 scodec-bits is published with pvp versionScheme (nice), this means that we should just evaluate the version portion for pvp-ness, but I was using `guessSecondSegment` that checks for Scala suffix. That's mistake 1. `guessSecondSegment` assumes that the Scala suffix uses the given ScalaModuleInfo, but with 2.13-3 sandwich we can't assume this. In the reported case, Scala module is 3.0.0-M3 but scodec-bits uses 2.13. So that's mistake 2. This attempts to correct both the mistakes. 1. Instead of `guessSecondSegment`, this adds a simpler `evalPvp` function. 2. `guessSecondSegment` just looks for `_2.` or `_3` and ignores the Scala module. --- .../librarymanagement/EvictionWarning.scala | 21 +++++++++++++++---- .../EvictionWarningSpec.scala | 18 ++++++++++++++++ project/build.properties | 2 +- 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index e8dff4e6f..1ac9d7039 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -98,12 +98,25 @@ object EvictionWarningOptions { lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessSbtOne orElse guessSecondSegment orElse guessSemVer orElse guessFalse + private def isNameScalaSuffixed(name: String): Boolean = + name.contains("_2.") || name.contains("_3") || name.contains("_4") + + /** A partial function that checks if given m2 is suffixed, and use pvp to evaluate. */ lazy val guessSecondSegment : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { - case (m1, Some(m2), Some(scalaModuleInfo)) - if m2.name.endsWith("_" + scalaModuleInfo.scalaFullVersion) || m2.name.endsWith( - "_" + scalaModuleInfo.scalaBinaryVersion - ) => + case (m1, Some(m2), Some(_)) if isNameScalaSuffixed(m2.name) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.SecondSegment + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + + /** A partial function that checks two versions match pvp. */ + private[sbt] lazy val evalPvp + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (m1, Some(m2), _) => (m1.revision, m2.revision) match { case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => VersionNumber.SecondSegment diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 925bdb599..09975ba5f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -283,6 +283,24 @@ object EvictionWarningSpec extends BaseIvySpecification { ) } + test("Comparing 2.13 libraries with pvp under Scala 3.0.0-M3 should work") { + val m1 = "org.scodec" % "scodec-bits_2.13" % "1.1.21" + val m2 = "org.scodec" % "scodec-bits_2.13" % "1.1.22" + assert( + EvictionWarningOptions + .evalPvp((m1, Option(m2), Option(dummyScalaModuleInfo("3.0.0-M3")))) + ) + } + + test("Comparing 2.13 libraries with guessSecondSegment under Scala 3.0.0-M3 should work") { + val m1 = "org.scodec" % "scodec-bits_2.13" % "1.1.21" + val m2 = "org.scodec" % "scodec-bits_2.13" % "1.1.22" + assert( + EvictionWarningOptions + .guessSecondSegment((m1, Option(m2), Option(dummyScalaModuleInfo("3.0.0-M3")))) + ) + } + def akkaActor214 = ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary def akkaActor230 = diff --git a/project/build.properties b/project/build.properties index c19c768d6..c06db1bb2 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.2 +sbt.version=1.4.5 From dc0d873f7bb5d9151d080d3ba8c7b380096f5229 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 20 Dec 2020 16:58:50 -0500 Subject: [PATCH 0898/1030] Use evalPvp Follow-up on https://github.com/sbt/librarymanagement/pull/352 --- core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 1ac9d7039..754186fcd 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -330,7 +330,7 @@ object EvictionWarning { case (Some(_), Some(VersionSchemes.SemVerSpec)) => EvictionWarningOptions.guessSemVer case (Some(_), Some(VersionSchemes.PackVer)) => - EvictionWarningOptions.guessSecondSegment + EvictionWarningOptions.evalPvp case _ => options.guessCompatible(_) } f((r.module, winnerOpt, module.scalaModuleInfo)) From 5f2f6ac161adeaf27aac8bcf35bd4b302ff339b6 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 20 Dec 2020 19:33:00 -0500 Subject: [PATCH 0899/1030] Fix Ivy parsing of versionScheme --- .../scala/sbt/internal/librarymanagement/CustomPomParser.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 591e3e881..514843cf4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -67,12 +67,13 @@ object CustomPomParser { /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX val ApiURLKey = SbtPomExtraProperties.POM_API_KEY + val VersionSchemeKey = SbtPomExtraProperties.VERSION_SCHEME_KEY val SbtVersionKey = PomExtraDependencyAttributes.SbtVersionKey val ScalaVersionKey = PomExtraDependencyAttributes.ScalaVersionKey val ExtraAttributesKey = PomExtraDependencyAttributes.ExtraAttributesKey private[this] val unqualifiedKeys = - Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey) + Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey, VersionSchemeKey) // packagings that should be jars, but that Ivy doesn't handle as jars // TODO - move this elsewhere. From aac1edb4262af5725411d06fabbacc1cfb853fed Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 20 Dec 2020 19:34:03 -0500 Subject: [PATCH 0900/1030] Add Strict and Always support --- .../librarymanagement/VersionSchemes.scala | 4 +++- .../librarymanagement/EvictionWarning.scala | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala index 7e2179f34..b8a5b1293 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -17,10 +17,12 @@ private[sbt] object VersionSchemes { final val EarlySemVer = "early-semver" final val SemVerSpec = "semver-spec" final val PackVer = "pvp" + final val Strict = "strict" + final val Always = "always" def validateScheme(value: String): Unit = value match { - case EarlySemVer | SemVerSpec | PackVer => () + case EarlySemVer | SemVerSpec | PackVer | Strict | Always => () case "semver" => sys.error( s"""'semver' is ambiguous. diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 754186fcd..e0519d981 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -161,10 +161,26 @@ object EvictionWarningOptions { } } + lazy val guessStrict + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (m1, Some(m2), _) => + (m1.revision, m2.revision) match { + case (VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) => + VersionNumber.Strict + .isCompatible(VersionNumber(ns1, ts1, es1), VersionNumber(ns2, ts2, es2)) + case _ => false + } + } + lazy val guessFalse : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { case (_, _, _) => false } + + lazy val guessTrue + : PartialFunction[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = { + case (_, _, _) => true + } } final class EvictionPair private[sbt] ( @@ -325,6 +341,10 @@ object EvictionWarning { }) val schemeOpt = VersionSchemes.extractFromExtraAttributes(extraAttributes) val f = (winnerOpt, schemeOpt) match { + case (Some(_), Some(VersionSchemes.Always)) => + EvictionWarningOptions.guessTrue + case (Some(_), Some(VersionSchemes.Strict)) => + EvictionWarningOptions.guessStrict case (Some(_), Some(VersionSchemes.EarlySemVer)) => EvictionWarningOptions.guessEarlySemVer case (Some(_), Some(VersionSchemes.SemVerSpec)) => From 9297139f6a406835b4e755447eccf48ae0063234 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 20 Dec 2020 19:35:15 -0500 Subject: [PATCH 0901/1030] Implement EvictionError Ref https://eed3si9n.com/enforcing-semver-with-sbt-strict-update This adds EvictionError, a replacement for EvictionWarning. The problem with the current eviction warning is that it has too many false positives. Using the versionScheme information that could be supplied by the library authors and/or the build users, this eliminates the guessing work. At which point, we can fail the resolution. --- .../sbt/librarymanagement/EvictionError.scala | 151 ++++++++++++++++++ .../librarymanagement/EvictionErrorSpec.scala | 116 ++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 core/src/main/scala/sbt/librarymanagement/EvictionError.scala create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala new file mode 100644 index 000000000..09a767bad --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -0,0 +1,151 @@ +package sbt +package librarymanagement + +import scala.collection.mutable +import sbt.internal.librarymanagement.VersionSchemes +import sbt.util.ShowLines + +object EvictionError { + def apply( + report: UpdateReport, + module: ModuleDescriptor, + schemes: Seq[ModuleID], + ): EvictionError = { + val options = EvictionWarningOptions.full + val evictions = EvictionWarning.buildEvictions(options, report) + processEvictions(module, options, evictions, schemes) + } + private[sbt] def processEvictions( + module: ModuleDescriptor, + options: EvictionWarningOptions, + reports: Seq[OrganizationArtifactReport], + schemes: Seq[ModuleID], + ): EvictionError = { + val directDependencies = module.directDependencies + val pairs = reports map { detail => + val evicteds = detail.modules filter { _.evicted } + val winner = (detail.modules filterNot { _.evicted }).headOption + new EvictionPair( + detail.organization, + detail.name, + winner, + evicteds, + true, + options.showCallers + ) + } + val incompatibleEvictions: mutable.ListBuffer[(EvictionPair, String)] = mutable.ListBuffer() + val sbvOpt = module.scalaModuleInfo.map(_.scalaBinaryVersion) + val userDefinedSchemes: Map[(String, String), String] = Map(schemes flatMap { s => + val organization = s.organization + VersionSchemes.validateScheme(s.revision) + val versionScheme = s.revision + (s.crossVersion, sbvOpt) match { + case (_: Binary, Some("2.13")) => + List( + (s.organization, s"${s.name}_2.13") -> versionScheme, + (s.organization, s"${s.name}_3") -> versionScheme + ) + case (_: Binary, Some(sbv)) if sbv.startsWith("3.0") || sbv == "3" => + List( + (s.organization, s"${s.name}_$sbv") -> versionScheme, + (s.organization, s"${s.name}_2.13") -> versionScheme + ) + case (_: Binary, Some(sbv)) => + List((s.organization, s"${s.name}_$sbv") -> versionScheme) + case _ => + List((s.organization, s.name) -> versionScheme) + } + }: _*) + def calculateCompatible(p: EvictionPair): (Boolean, String) = { + val winnerOpt = p.winner map { _.module } + val extraAttributes = (p.winner match { + case Some(r) => r.extraAttributes + case _ => Map.empty + }) ++ (winnerOpt match { + case Some(w) => w.extraAttributes + case _ => Map.empty + }) + // prioritize user-defined version scheme to allow overriding the real scheme + val schemeOpt = userDefinedSchemes + .get((p.organization, p.name)) + .orElse(userDefinedSchemes.get((p.organization, "*"))) + .orElse(VersionSchemes.extractFromExtraAttributes(extraAttributes)) + .orElse(userDefinedSchemes.get(("*", "*"))) + val f = (winnerOpt, schemeOpt) match { + case (Some(_), Some(VersionSchemes.Always)) => + EvictionWarningOptions.guessTrue + case (Some(_), Some(VersionSchemes.Strict)) => + EvictionWarningOptions.guessStrict + case (Some(_), Some(VersionSchemes.EarlySemVer)) => + EvictionWarningOptions.guessEarlySemVer + case (Some(_), Some(VersionSchemes.SemVerSpec)) => + EvictionWarningOptions.guessSemVer + case (Some(_), Some(VersionSchemes.PackVer)) => + EvictionWarningOptions.evalPvp + case _ => EvictionWarningOptions.guessTrue + } + (p.evicteds forall { r => + f((r.module, winnerOpt, module.scalaModuleInfo)) + }, schemeOpt.getOrElse("?")) + } + pairs foreach { + case p if p.winner.isDefined => + // don't report on a transitive eviction that does not have a winner + // https://github.com/sbt/sbt/issues/4946 + if (p.winner.isDefined) { + val r = calculateCompatible(p) + if (!r._1) { + incompatibleEvictions += (p -> r._2) + } + } + case _ => () + } + new EvictionError( + incompatibleEvictions.toList, + ) + } + + implicit val evictionErrorLines: ShowLines[EvictionError] = ShowLines { a: EvictionError => + a.toLines + } +} + +final class EvictionError private[sbt] ( + val incompatibleEvictions: Seq[(EvictionPair, String)], +) { + def run(): Unit = + if (incompatibleEvictions.nonEmpty) { + sys.error(toLines.mkString("\n")) + } + + def toLines: List[String] = { + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" + out += "" + incompatibleEvictions.foreach({ + case (a, scheme) => + val revs = a.evicteds map { _.module.revision } + val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") + } + } + } + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} ($scheme) is selected over ${revsStr}" + case _ => " is evicted for all versions" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") + out ++= lines + }) + out.toList + } +} diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala new file mode 100644 index 000000000..76edf91f9 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -0,0 +1,116 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ +import sbt.internal.librarymanagement.cross.CrossVersionUtil +import sbt.librarymanagement.syntax._ + +object EvictionErrorSpec extends BaseIvySpecification { + // This is a specification to check the eviction errors + + import sbt.util.ShowLines._ + + test("Eviction error should detect binary incompatible Scala libraries") { + val deps = Vector(`scala2.10.4`, `akkaActor2.1.4`, `akkaActor2.3.0`) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert(EvictionError(report, m, oldAkkaPvp).incompatibleEvictions.size == 1) + } + + test("it should print out message about the eviction") { + val deps = Vector(`scala2.10.4`, `akkaActor2.1.4`, `akkaActor2.3.0`) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionError(report, m, oldAkkaPvp).lines == + List( + "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.0 (pvp) is selected over 2.1.4", + "\t +- com.example:foo:0.1.0 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should print out message including the transitive dependencies") { + val deps = Vector(`scala2.10.4`, `bananaSesame0.4`, `akkaRemote2.3.4`) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionError(report, m, oldAkkaPvp).lines == + List( + "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 (pvp) is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "" + ) + ) + } + + test("it should detect Semantic Versioning violations") { + val deps = Vector(`scala2.13.3`, `http4s0.21.11`, `cats-effect3.0.0-M4`) + val m = module(defaultModuleId, deps, Some("2.13.3")) + val report = ivyUpdate(m) + assert( + EvictionError(report, m, Nil).lines == + List( + "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* org.typelevel:cats-effect_2.13:3.0.0-M4 (early-semver) is selected over {2.0.0, 2.2.0}", + "\t +- com.example:foo:0.1.0 (depends on 3.0.0-M4)", + "\t +- co.fs2:fs2-core_2.13:2.4.5 (depends on 2.2.0)", + "\t +- org.http4s:http4s-core_2.13:0.21.11 (depends on 2.2.0)", + "\t +- io.chrisdavenport:vault_2.13:2.0.0 (depends on 2.0.0)", + "\t +- io.chrisdavenport:unique_2.13:2.0.0 (depends on 2.0.0)", + "" + ) + ) + } + + test("it should selectively allow opt-out from the error") { + val deps = Vector(`scala2.13.3`, `http4s0.21.11`, `cats-effect3.0.0-M4`) + val m = module(defaultModuleId, deps, Some("2.13.3")) + val report = ivyUpdate(m) + val overrideRules = List("org.typelevel" %% "cats-effect" % "always") + assert(EvictionError(report, m, overrideRules).incompatibleEvictions.isEmpty) + } + + // older Akka was on pvp + def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") + + lazy val `akkaActor2.1.4` = + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + lazy val `akkaActor2.3.0` = + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + lazy val `scala2.10.4` = + ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) + lazy val `scala2.13.3` = + ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) + lazy val `bananaSesame0.4` = + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + lazy val `akkaRemote2.3.4` = + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + lazy val `http4s0.21.11` = + ("org.http4s" %% "http4s-blaze-server" % "0.21.11").withConfigurations(Some("compile")) + // https://repo1.maven.org/maven2/org/typelevel/cats-effect_2.13/3.0.0-M4/cats-effect_2.13-3.0.0-M4.pom + // is published with early-semver + lazy val `cats-effect3.0.0-M4` = + ("org.typelevel" %% "cats-effect" % "3.0.0-M4").withConfigurations(Some("compile")) + lazy val `cats-parse0.1.0` = + ("org.typelevel" %% "cats-parse" % "0.1.0").withConfigurations(Some("compile")) + lazy val `cats-parse0.2.0` = + ("org.typelevel" %% "cats-parse" % "0.2.0").withConfigurations(Some("compile")) + + def dummyScalaModuleInfo(v: String): ScalaModuleInfo = + ScalaModuleInfo( + scalaFullVersion = v, + scalaBinaryVersion = CrossVersionUtil.binaryScalaVersion(v), + configurations = Vector.empty, + checkExplicit = true, + filterImplicit = false, + overrideScalaVersion = true + ) +} From 65b4130e6bcb07cefca4880afa2859e72179e54a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 21 Dec 2020 13:47:50 +0000 Subject: [PATCH 0902/1030] Update plugins.sbt --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index f2c5eaec0..d72359f9e 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,7 +3,7 @@ addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.0") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From 997ce66a1a800930e48b870bac1e6ca083548cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 21 Dec 2020 17:43:24 +0000 Subject: [PATCH 0903/1030] regen contraband --- .../internal/librarymanagement/ConfigurationReportLite.scala | 4 ++-- .../sbt/internal/librarymanagement/SemComparator.scala | 4 ++-- .../sbt/internal/librarymanagement/SemSelAndChunk.scala | 4 ++-- .../sbt/internal/librarymanagement/UpdateReportLite.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/Artifact.scala | 4 ++-- .../sbt/librarymanagement/ArtifactTypeFilter.scala | 4 ++-- .../main/contraband-scala/sbt/librarymanagement/Caller.scala | 4 ++-- .../sbt/librarymanagement/ChainedResolver.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/Checksum.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/ConfigRef.scala | 4 ++-- .../sbt/librarymanagement/ConfigurationReport.scala | 4 ++-- .../sbt/librarymanagement/ConflictManager.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/Developer.scala | 4 ++-- .../sbt/librarymanagement/FileConfiguration.scala | 4 ++-- .../sbt/librarymanagement/FileRepository.scala | 4 ++-- .../sbt/librarymanagement/GetClassifiersConfiguration.scala | 4 ++-- .../sbt/librarymanagement/GetClassifiersModule.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/InclExclRule.scala | 4 ++-- .../sbt/librarymanagement/IvyFileConfiguration.scala | 4 ++-- .../sbt/librarymanagement/KeyFileAuthentication.scala | 4 ++-- .../sbt/librarymanagement/MakePomConfiguration.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/MavenCache.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/MavenRepo.scala | 4 ++-- .../sbt/librarymanagement/MavenRepository.scala | 4 ++-- .../sbt/librarymanagement/ModuleConfiguration.scala | 4 ++-- .../sbt/librarymanagement/ModuleDescriptorConfiguration.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/ModuleID.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/ModuleInfo.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/ModuleReport.scala | 4 ++-- .../sbt/librarymanagement/ModuleSettings.scala | 4 ++-- .../sbt/librarymanagement/OrganizationArtifactReport.scala | 4 ++-- .../sbt/librarymanagement/PasswordAuthentication.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/Patterns.scala | 4 ++-- .../sbt/librarymanagement/PatternsBasedRepository.scala | 4 ++-- .../sbt/librarymanagement/PomConfiguration.scala | 4 ++-- .../sbt/librarymanagement/PublishConfiguration.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/Resolver.scala | 4 ++-- .../sbt/librarymanagement/RetrieveConfiguration.scala | 4 ++-- .../sbt/librarymanagement/ScalaModuleInfo.scala | 4 ++-- .../main/contraband-scala/sbt/librarymanagement/ScmInfo.scala | 4 ++-- .../sbt/librarymanagement/SemanticSelector.scala | 4 ++-- .../sbt/librarymanagement/SftpRepository.scala | 4 ++-- .../sbt/librarymanagement/SshAuthentication.scala | 4 ++-- .../sbt/librarymanagement/SshBasedRepository.scala | 4 ++-- .../sbt/librarymanagement/SshConnection.scala | 4 ++-- .../sbt/librarymanagement/SshRepository.scala | 4 ++-- .../sbt/librarymanagement/URLRepository.scala | 4 ++-- .../sbt/librarymanagement/UpdateConfiguration.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/UpdateReport.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/UpdateStats.scala | 4 ++-- .../sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala | 4 ++-- .../sbt/librarymanagement/ivy/InlineIvyConfiguration.scala | 4 ++-- .../sbt/librarymanagement/ivy/IvyConfiguration.scala | 4 ++-- .../contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala | 4 ++-- 54 files changed, 108 insertions(+), 108 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala index b9a9c46f3..d277f7ca2 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/ConfigurationReportLite.scala @@ -10,10 +10,10 @@ final class ConfigurationReportLite private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ConfigurationReportLite => (this.configuration == x.configuration) && (this.details == x.details) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.ConfigurationReportLite".##) + configuration.##) + details.##) } diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala index fda56f608..2baccd6b9 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala @@ -21,10 +21,10 @@ final class SemComparator private ( } -override def equals(o: Any): Boolean = o match { +override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SemComparator => (this.op == x.op) && (this.major == x.major) && (this.minor == x.minor) && (this.patch == x.patch) && (this.tags == x.tags) case _ => false -} +}) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.SemComparator".##) + op.##) + major.##) + minor.##) + patch.##) + tags.##) } diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala index 3b8ab91a8..820fc3231 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemSelAndChunk.scala @@ -9,10 +9,10 @@ final class SemSelAndChunk private ( def matches(version: sbt.librarymanagement.VersionNumber): Boolean = comparators.forall(_.matches(version)) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SemSelAndChunk => (this.comparators == x.comparators) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (17 + "sbt.internal.librarymanagement.SemSelAndChunk".##) + comparators.##) } diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala index 948280532..f5040d97f 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/UpdateReportLite.scala @@ -9,10 +9,10 @@ final class UpdateReportLite private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: UpdateReportLite => (this.configurations == x.configurations) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (17 + "sbt.internal.librarymanagement.UpdateReportLite".##) + configurations.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 86d7a218c..24764d0cb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -18,10 +18,10 @@ final class Artifact private ( private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Artifact".##) + name.##) + `type`.##) + extension.##) + classifier.##) + configurations.##) + url.##) + extraAttributes.##) + checksum.##) + allowInsecureProtocol.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala index fbdbc8dc7..6d9676e75 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactTypeFilter.scala @@ -17,10 +17,10 @@ final class ArtifactTypeFilter private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ArtifactTypeFilter => (this.types == x.types) && (this.inverted == x.inverted) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.ArtifactTypeFilter".##) + types.##) + inverted.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala index 074740502..30b0b9372 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Caller.scala @@ -15,10 +15,10 @@ final class Caller private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Caller => (this.caller == x.caller) && (this.callerConfigurations == x.callerConfigurations) && (this.callerExtraAttributes == x.callerExtraAttributes) && (this.isForceDependency == x.isForceDependency) && (this.isChangingDependency == x.isChangingDependency) && (this.isTransitiveDependency == x.isTransitiveDependency) && (this.isDirectlyForceDependency == x.isDirectlyForceDependency) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Caller".##) + caller.##) + callerConfigurations.##) + callerExtraAttributes.##) + isForceDependency.##) + isChangingDependency.##) + isTransitiveDependency.##) + isDirectlyForceDependency.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala index 3fe0ce544..b91c5db8e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolver.scala @@ -10,10 +10,10 @@ final class ChainedResolver private ( private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = !resolvers.forall(!_.validateProtocol(logger)) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ChainedResolver => (this.name == x.name) && (this.resolvers == x.resolvers) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.ChainedResolver".##) + name.##) + resolvers.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala index fafa5e340..13676bc3d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Checksum.scala @@ -10,10 +10,10 @@ final class Checksum private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Checksum => (this.digest == x.digest) && (this.`type` == x.`type`) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.Checksum".##) + digest.##) + `type`.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala index 383c5e772..bc926aaab 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala @@ -13,10 +13,10 @@ final class ConfigRef private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ConfigRef => (this.name == x.name) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (17 + "sbt.librarymanagement.ConfigRef".##) + name.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala index 379a090fa..99b421dd7 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReport.scala @@ -17,10 +17,10 @@ final class ConfigurationReport private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ConfigurationReport => (this.configuration == x.configuration) && (this.modules == x.modules) && (this.details == x.details) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ConfigurationReport".##) + configuration.##) + modules.##) + details.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala index 3779a9801..cef310494 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConflictManager.scala @@ -12,10 +12,10 @@ final class ConflictManager private ( private def this(name: String) = this(name, "*", "*") - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ConflictManager => (this.name == x.name) && (this.organization == x.organization) && (this.module == x.module) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ConflictManager".##) + name.##) + organization.##) + module.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index eb12f67f2..fc52d4e7b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -12,10 +12,10 @@ final class Developer private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Developer => (this.id == x.id) && (this.name == x.name) && (this.email == x.email) && (this.url == x.url) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Developer".##) + id.##) + name.##) + email.##) + url.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala index 26be3bbca..daf2e6d3c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileConfiguration.scala @@ -11,10 +11,10 @@ final class FileConfiguration private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: FileConfiguration => (this.isLocal == x.isLocal) && (this.isTransactional == x.isTransactional) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.FileConfiguration".##) + isLocal.##) + isTransactional.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala index ceb376bdf..ca1fb7b7c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepository.scala @@ -13,10 +13,10 @@ final class FileRepository private ( this(name, patterns, configuration) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: FileRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.configuration == x.configuration) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.FileRepository".##) + name.##) + patterns.##) + configuration.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala index dfcc0a031..85deb700c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfiguration.scala @@ -13,10 +13,10 @@ final class GetClassifiersConfiguration private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: GetClassifiersConfiguration => (this.module == x.module) && (this.excludes == x.excludes) && (this.updateConfiguration == x.updateConfiguration) && (this.sourceArtifactTypes == x.sourceArtifactTypes) && (this.docArtifactTypes == x.docArtifactTypes) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.GetClassifiersConfiguration".##) + module.##) + excludes.##) + updateConfiguration.##) + sourceArtifactTypes.##) + docArtifactTypes.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala index 57459661d..dfdaa72c1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModule.scala @@ -13,10 +13,10 @@ final class GetClassifiersModule private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: GetClassifiersModule => (this.id == x.id) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.dependencies == x.dependencies) && (this.configurations == x.configurations) && (this.classifiers == x.classifiers) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.GetClassifiersModule".##) + id.##) + scalaModuleInfo.##) + dependencies.##) + configurations.##) + classifiers.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala index 65bbf0308..23da54f26 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRule.scala @@ -22,10 +22,10 @@ final class InclExclRule private ( private def this() = this("*", "*", "*", Vector.empty, sbt.librarymanagement.Disabled()) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: InclExclRule => (this.organization == x.organization) && (this.name == x.name) && (this.artifact == x.artifact) && (this.configurations == x.configurations) && (this.crossVersion == x.crossVersion) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.InclExclRule".##) + organization.##) + name.##) + artifact.##) + configurations.##) + crossVersion.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala index 4413ba31a..0611fbabf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfiguration.scala @@ -12,10 +12,10 @@ final class IvyFileConfiguration private ( private def this(file: java.io.File, autoScalaTools: Boolean) = this(false, None, file, autoScalaTools) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: IvyFileConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.IvyFileConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala index 824315201..7366734e7 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/KeyFileAuthentication.scala @@ -11,10 +11,10 @@ final class KeyFileAuthentication private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: KeyFileAuthentication => (this.user == x.user) && (this.keyfile == x.keyfile) && (this.password == x.password) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.KeyFileAuthentication".##) + user.##) + keyfile.##) + password.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala index 5ff0e386e..320fe3722 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MakePomConfiguration.scala @@ -16,10 +16,10 @@ final class MakePomConfiguration private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: MakePomConfiguration => (this.file == x.file) && (this.moduleInfo == x.moduleInfo) && (this.configurations == x.configurations) && (this.extra == x.extra) && (this.process == x.process) && (this.filterRepositories == x.filterRepositories) && (this.allRepositories == x.allRepositories) && (this.includeTypes == x.includeTypes) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MakePomConfiguration".##) + file.##) + moduleInfo.##) + configurations.##) + extra.##) + process.##) + filterRepositories.##) + allRepositories.##) + includeTypes.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala index aac4cf776..dc69f0abe 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenCache.scala @@ -18,10 +18,10 @@ final class MavenCache private ( override def allowInsecureProtocol: Boolean = false private def this(name: String, root: String, rootFile: java.io.File) = this(name, root, true, rootFile) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: MavenCache => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) && (this.rootFile == x.rootFile) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenCache".##) + name.##) + root.##) + localIfFile.##) + rootFile.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala index 32ce0d0ab..b8fa71575 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepo.scala @@ -16,10 +16,10 @@ final class MavenRepo private ( private def this(name: String, root: String) = this(name, root, true, false) private def this(name: String, root: String, localIfFile: Boolean) = this(name, root, localIfFile, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: MavenRepo => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) && (this._allowInsecureProtocol == x._allowInsecureProtocol) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepo".##) + name.##) + root.##) + localIfFile.##) + _allowInsecureProtocol.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala index 73623d6e5..7618f2b02 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/MavenRepository.scala @@ -19,10 +19,10 @@ abstract class MavenRepository( def this(name: String, root: String) = this(name, root, true) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: MavenRepository => (this.name == x.name) && (this.root == x.root) && (this.localIfFile == x.localIfFile) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.MavenRepository".##) + name.##) + root.##) + localIfFile.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala index 9953ac698..7b4075929 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfiguration.scala @@ -12,10 +12,10 @@ final class ModuleConfiguration private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleConfiguration => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.resolver == x.resolver) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleConfiguration".##) + organization.##) + name.##) + revision.##) + resolver.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala index 5a093be12..11d51997d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfiguration.scala @@ -19,10 +19,10 @@ final class ModuleDescriptorConfiguration private ( private def this(module: sbt.librarymanagement.ModuleID, moduleInfo: sbt.librarymanagement.ModuleInfo) = this(false, None, module, moduleInfo, Vector.empty, Vector.empty, Vector.empty, scala.xml.NodeSeq.Empty, sbt.librarymanagement.Configurations.default, Option(sbt.librarymanagement.Configurations.Compile), sbt.librarymanagement.ConflictManager.default) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleDescriptorConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.module == x.module) && (this.moduleInfo == x.moduleInfo) && (this.dependencies == x.dependencies) && (this.overrides == x.overrides) && (this.excludes == x.excludes) && (this.ivyXML == x.ivyXML) && (this.configurations == x.configurations) && (this.defaultConfiguration == x.defaultConfiguration) && (this.conflictManager == x.conflictManager) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleDescriptorConfiguration".##) + validate.##) + scalaModuleInfo.##) + module.##) + moduleInfo.##) + dependencies.##) + overrides.##) + excludes.##) + ivyXML.##) + configurations.##) + defaultConfiguration.##) + conflictManager.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index 144e5058a..49ef7ff34 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -21,10 +21,10 @@ final class ModuleID private ( private def this(organization: String, name: String, revision: String) = this(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleID => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.configurations == x.configurations) && (this.isChanging == x.isChanging) && (this.isTransitive == x.isTransitive) && (this.isForce == x.isForce) && (this.explicitArtifacts == x.explicitArtifacts) && (this.inclusions == x.inclusions) && (this.exclusions == x.exclusions) && (this.extraAttributes == x.extraAttributes) && (this.crossVersion == x.crossVersion) && (this.branchName == x.branchName) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index a86e285d1..383a144eb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -18,10 +18,10 @@ final class ModuleInfo private ( private def this(nameFormal: String) = this(nameFormal, "", None, None, Vector.empty, "", None, None, Vector.empty) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleInfo => (this.nameFormal == x.nameFormal) && (this.description == x.description) && (this.homepage == x.homepage) && (this.startYear == x.startYear) && (this.licenses == x.licenses) && (this.organizationName == x.organizationName) && (this.organizationHomepage == x.organizationHomepage) && (this.scmInfo == x.scmInfo) && (this.developers == x.developers) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleInfo".##) + nameFormal.##) + description.##) + homepage.##) + startYear.##) + licenses.##) + organizationName.##) + organizationHomepage.##) + scmInfo.##) + developers.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala index 372468f1d..2c3386942 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReport.scala @@ -30,10 +30,10 @@ final class ModuleReport private ( private def this(module: sbt.librarymanagement.ModuleID, artifacts: Vector[scala.Tuple2[sbt.librarymanagement.Artifact, java.io.File]], missingArtifacts: Vector[sbt.librarymanagement.Artifact]) = this(module, artifacts, missingArtifacts, None, None, None, None, false, None, None, None, None, Map.empty, None, None, Vector.empty, Vector.empty, Vector.empty) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleReport => (this.module == x.module) && (this.artifacts == x.artifacts) && (this.missingArtifacts == x.missingArtifacts) && (this.status == x.status) && (this.publicationDate == x.publicationDate) && (this.resolver == x.resolver) && (this.artifactResolver == x.artifactResolver) && (this.evicted == x.evicted) && (this.evictedData == x.evictedData) && (this.evictedReason == x.evictedReason) && (this.problem == x.problem) && (this.homepage == x.homepage) && (this.extraAttributes == x.extraAttributes) && (this.isDefault == x.isDefault) && (this.branch == x.branch) && (this.configurations == x.configurations) && (this.licenses == x.licenses) && (this.callers == x.callers) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleReport".##) + module.##) + artifacts.##) + missingArtifacts.##) + status.##) + publicationDate.##) + resolver.##) + artifactResolver.##) + evicted.##) + evictedData.##) + evictedReason.##) + problem.##) + homepage.##) + extraAttributes.##) + isDefault.##) + branch.##) + configurations.##) + licenses.##) + callers.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala index e210651b6..5fac9f2f3 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettings.scala @@ -11,10 +11,10 @@ abstract class ModuleSettings( def this() = this(false, None) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ModuleSettings => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleSettings".##) + validate.##) + scalaModuleInfo.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala index 693134253..83624f2c8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReport.scala @@ -22,10 +22,10 @@ final class OrganizationArtifactReport private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: OrganizationArtifactReport => (this.organization == x.organization) && (this.name == x.name) && (this.modules == x.modules) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.OrganizationArtifactReport".##) + organization.##) + name.##) + modules.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala index fb4c1bf1b..56a07dc60 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PasswordAuthentication.scala @@ -10,10 +10,10 @@ final class PasswordAuthentication private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: PasswordAuthentication => (this.user == x.user) && (this.password == x.password) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.PasswordAuthentication".##) + user.##) + password.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala index 609fc59d4..a87caca63 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Patterns.scala @@ -13,10 +13,10 @@ final class Patterns private ( private def this() = this(Vector.empty, Vector.empty, true, false, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Patterns => (this.ivyPatterns == x.ivyPatterns) && (this.artifactPatterns == x.artifactPatterns) && (this.isMavenCompatible == x.isMavenCompatible) && (this.descriptorOptional == x.descriptorOptional) && (this.skipConsistencyCheck == x.skipConsistencyCheck) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.Patterns".##) + ivyPatterns.##) + artifactPatterns.##) + isMavenCompatible.##) + descriptorOptional.##) + skipConsistencyCheck.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala index 3ddc7b1cc..494baf2e4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepository.scala @@ -12,10 +12,10 @@ abstract class PatternsBasedRepository( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: PatternsBasedRepository => (this.name == x.name) && (this.patterns == x.patterns) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.PatternsBasedRepository".##) + name.##) + patterns.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala index 8359588b6..441ce8b64 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfiguration.scala @@ -12,10 +12,10 @@ final class PomConfiguration private ( private def this(file: java.io.File, autoScalaTools: Boolean) = this(false, None, file, autoScalaTools) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: PomConfiguration => (this.validate == x.validate) && (this.scalaModuleInfo == x.scalaModuleInfo) && (this.file == x.file) && (this.autoScalaTools == x.autoScalaTools) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.PomConfiguration".##) + validate.##) + scalaModuleInfo.##) + file.##) + autoScalaTools.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala index 6391c8c3e..63864882c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfiguration.scala @@ -17,10 +17,10 @@ final class PublishConfiguration private ( private def this() = this(true, None, None, None, None, Vector(), Vector("sha1", "md5"), None, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: PublishConfiguration => (this.publishMavenStyle == x.publishMavenStyle) && (this.deliverIvyPattern == x.deliverIvyPattern) && (this.status == x.status) && (this.configurations == x.configurations) && (this.resolverName == x.resolverName) && (this.artifacts == x.artifacts) && (this.checksums == x.checksums) && (this.logging == x.logging) && (this.overwrite == x.overwrite) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.PublishConfiguration".##) + publishMavenStyle.##) + deliverIvyPattern.##) + status.##) + configurations.##) + resolverName.##) + artifacts.##) + checksums.##) + logging.##) + overwrite.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala index f4a7c9627..13c57e0d6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Resolver.scala @@ -11,10 +11,10 @@ abstract class Resolver( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Resolver => (this.name == x.name) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (17 + "sbt.librarymanagement.Resolver".##) + name.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala index 7daf0d5f0..1aa3a2e22 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/RetrieveConfiguration.scala @@ -13,10 +13,10 @@ final class RetrieveConfiguration private ( private def this() = this(None, None, false, None) private def this(retrieveDirectory: Option[java.io.File], outputPattern: Option[String]) = this(retrieveDirectory, outputPattern, false, None) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: RetrieveConfiguration => (this.retrieveDirectory == x.retrieveDirectory) && (this.outputPattern == x.outputPattern) && (this.sync == x.sync) && (this.configurationsToRetrieve == x.configurationsToRetrieve) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.RetrieveConfiguration".##) + retrieveDirectory.##) + outputPattern.##) + sync.##) + configurationsToRetrieve.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index c8b8ee745..772d7b9ee 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -16,10 +16,10 @@ final class ScalaModuleInfo private ( private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ScalaModuleInfo => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 837f9e11a..4fadcae1f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -12,10 +12,10 @@ final class ScmInfo private ( private def this(browseUrl: java.net.URL, connection: String) = this(browseUrl, connection, None) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ScmInfo => (this.browseUrl == x.browseUrl) && (this.connection == x.connection) && (this.devConnection == x.devConnection) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScmInfo".##) + browseUrl.##) + connection.##) + devConnection.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala index 4faf5ff19..ca5386b34 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala @@ -63,10 +63,10 @@ final class SemanticSelector private ( def matches(versionNumber: VersionNumber): Boolean = selectors.exists(_.matches(versionNumber)) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SemanticSelector => (this.selectors == x.selectors) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (17 + "sbt.librarymanagement.SemanticSelector".##) + selectors.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala index f79ae577a..b20a2f25b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepository.scala @@ -13,10 +13,10 @@ final class SftpRepository private ( this(name, patterns, connection) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SftpRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SftpRepository".##) + name.##) + patterns.##) + connection.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala index e85c1454f..eaeb29bf5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshAuthentication.scala @@ -9,10 +9,10 @@ abstract class SshAuthentication() extends Serializable { -override def equals(o: Any): Boolean = o match { +override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case _: SshAuthentication => true case _ => false -} +}) override def hashCode: Int = { 37 * (17 + "sbt.librarymanagement.SshAuthentication".##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala index ef5e743a1..ec3af1b7a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepository.scala @@ -13,10 +13,10 @@ abstract class SshBasedRepository( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SshBasedRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshBasedRepository".##) + name.##) + patterns.##) + connection.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala index 796cdb961..68161ac8c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnection.scala @@ -11,10 +11,10 @@ final class SshConnection private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SshConnection => (this.authentication == x.authentication) && (this.hostname == x.hostname) && (this.port == x.port) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshConnection".##) + authentication.##) + hostname.##) + port.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala index a71e2bd5d..0c7a4c5ef 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepository.scala @@ -14,10 +14,10 @@ final class SshRepository private ( this(name, patterns, connection, publishPermissions) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: SshRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.connection == x.connection) && (this.publishPermissions == x.publishPermissions) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.SshRepository".##) + name.##) + patterns.##) + connection.##) + publishPermissions.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala index 9acb17c40..6bdb70fd2 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/URLRepository.scala @@ -11,10 +11,10 @@ final class URLRepository private ( private[sbt] override def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateURLRepository(this, logger) private def this(name: String, patterns: sbt.librarymanagement.Patterns) = this(name, patterns, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: URLRepository => (this.name == x.name) && (this.patterns == x.patterns) && (this.allowInsecureProtocol == x.allowInsecureProtocol) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.URLRepository".##) + name.##) + patterns.##) + allowInsecureProtocol.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala index f1fd781fc..69b7e6968 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfiguration.scala @@ -25,10 +25,10 @@ final class UpdateConfiguration private ( private def this() = this(None, false, sbt.librarymanagement.UpdateLogging.Default, sbt.librarymanagement.LogicalClock.unknown, None, None, false, false) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: UpdateConfiguration => (this.retrieveManaged == x.retrieveManaged) && (this.missingOk == x.missingOk) && (this.logging == x.logging) && (this.logicalClock == x.logicalClock) && (this.metadataDirectory == x.metadataDirectory) && (this.artifactFilter == x.artifactFilter) && (this.offline == x.offline) && (this.frozen == x.frozen) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateConfiguration".##) + retrieveManaged.##) + missingOk.##) + logging.##) + logicalClock.##) + metadataDirectory.##) + artifactFilter.##) + offline.##) + frozen.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index fd5f22a72..0e3c68f1a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -20,10 +20,10 @@ final class UpdateReport private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: UpdateReport => (this.cachedDescriptor == x.cachedDescriptor) && (this.configurations == x.configurations) && (this.stats == x.stats) && (this.stamps == x.stamps) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateReport".##) + cachedDescriptor.##) + configurations.##) + stats.##) + stamps.##) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala index 96e408316..a2ea73ced 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateStats.scala @@ -12,10 +12,10 @@ final class UpdateStats private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: UpdateStats => (this.resolveTime == x.resolveTime) && (this.downloadTime == x.downloadTime) && (this.downloadSize == x.downloadSize) && (this.cached == x.cached) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.UpdateStats".##) + resolveTime.##) + downloadTime.##) + downloadSize.##) + cached.##) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala index c5068c2aa..d99050794 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfiguration.scala @@ -14,10 +14,10 @@ final class ExternalIvyConfiguration private ( private def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, None, Vector()) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ExternalIvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.baseDirectory == x.baseDirectory) && (this.uri == x.uri) && (this.extraResolvers == x.extraResolvers) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.ExternalIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + baseDirectory.##) + uri.##) + extraResolvers.##) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala index f528b84b4..5455978f7 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfiguration.scala @@ -18,10 +18,10 @@ final class InlineIvyConfiguration private ( private def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions(), None, sbt.librarymanagement.Resolver.defaults, Vector.empty, Vector.empty, sbt.librarymanagement.ivy.IvyDefaults.defaultChecksums, false, None) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: InlineIvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) && (this.paths == x.paths) && (this.resolvers == x.resolvers) && (this.otherResolvers == x.otherResolvers) && (this.moduleConfigurations == x.moduleConfigurations) && (this.checksums == x.checksums) && (this.managedChecksums == x.managedChecksums) && (this.resolutionCacheDir == x.resolutionCacheDir) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.InlineIvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) + paths.##) + resolvers.##) + otherResolvers.##) + moduleConfigurations.##) + checksums.##) + managedChecksums.##) + resolutionCacheDir.##) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala index 8a1fd621d..c515b3747 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfiguration.scala @@ -12,10 +12,10 @@ abstract class IvyConfiguration( def this() = this(None, None, sbt.librarymanagement.ivy.UpdateOptions()) - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: IvyConfiguration => (this.lock == x.lock) && (this.log == x.log) && (this.updateOptions == x.updateOptions) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.IvyConfiguration".##) + lock.##) + log.##) + updateOptions.##) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index 866e50825..574369bb0 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -10,10 +10,10 @@ final class IvyPaths private ( - override def equals(o: Any): Boolean = o match { + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: IvyPaths => (this.baseDirectory == x.baseDirectory) && (this.ivyHome == x.ivyHome) case _ => false - } + }) override def hashCode: Int = { 37 * (37 * (37 * (17 + "sbt.librarymanagement.ivy.IvyPaths".##) + baseDirectory.##) + ivyHome.##) } From 51d64c7eefabe5aff33476b03bdfaeb6bc85a670 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 23 Dec 2020 14:56:49 +0100 Subject: [PATCH 0904/1030] Add scala3doc artifact --- .../ConfigurationExtra.scala | 1 + .../librarymanagement/ScalaArtifacts.scala | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index d15297198..7431e8950 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -48,6 +48,7 @@ object Configurations { lazy val Pom = Configuration.of("Pom", "pom") lazy val ScalaTool = Configuration.of("ScalaTool", "scala-tool").hide + lazy val ScalaDocTool = Configuration.of("ScalaDocTool", "scala-doc-tool").hide lazy val CompilerPlugin = Configuration.of("CompilerPlugin", "plugin").hide lazy val Component = Configuration.of("Component", "component").hide diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index dc667a4c8..18eb70fbe 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -13,17 +13,20 @@ object ScalaArtifacts { final val Scala3CompilerID = "scala3-compiler" final val Scala3InterfacesID = "scala3-interfaces" final val TastyCoreID = "tasty-core" + final val Scala3DocID = "scala3doc" private[sbt] final val Scala3LibraryPrefix = Scala3LibraryID + "_" private[sbt] final val Scala3CompilerPrefix = Scala3CompilerID + "_" private[sbt] final val TastyCorePrefix = TastyCoreID + "_" + private[sbt] final val Scala3DocPrefix = Scala3DocID + "_" def isScala2Artifact(name: String): Boolean = { name == LibraryID || name == CompilerID || name == ReflectID || name == ActorsID || name == ScalapID } def isScala3Artifact(name: String): Boolean = { name.startsWith(Scala3LibraryPrefix) || name.startsWith(Scala3CompilerPrefix) || - name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID + name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID || + name.startsWith(Scala3DocPrefix) } def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.") @@ -48,6 +51,18 @@ object ScalaArtifacts { ModuleID(org, LibraryID, version) } + private[sbt] def docToolDependencies( + org: String, + version: String + ): Seq[ModuleID] = + if (isScala3(version)) { + Seq( + ModuleID(org, Scala3DocID, version) + .withConfigurations(Some(Configurations.ScalaDocTool.name + "->default(compile)")) + .withCrossVersion(CrossVersion.binary) + ) + } else Seq.empty + private[sbt] def toolDependencies( org: String, version: String @@ -60,11 +75,11 @@ object ScalaArtifacts { ) else Seq( - scalaToolDependency(org, CompilerID, version), - scalaToolDependency(org, LibraryID, version) + scala2ToolDependency(org, CompilerID, version), + scala2ToolDependency(org, LibraryID, version) ) - private[this] def scalaToolDependency(org: String, id: String, version: String): ModuleID = + private[this] def scala2ToolDependency(org: String, id: String, version: String): ModuleID = ModuleID(org, id, version).withConfigurations( Some(Configurations.ScalaTool.name + "->default,optional(default)") ) From ec34dd71a3d8bbf557e525186131d6f0f1962847 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 30 Dec 2020 15:01:08 +0100 Subject: [PATCH 0905/1030] Add scala3-tasty-inspector artifact --- .../src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index 18eb70fbe..01e2ffe34 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -14,11 +14,13 @@ object ScalaArtifacts { final val Scala3InterfacesID = "scala3-interfaces" final val TastyCoreID = "tasty-core" final val Scala3DocID = "scala3doc" + final val Scala3TastyInspectorID = "scala3-tasty-inspector" private[sbt] final val Scala3LibraryPrefix = Scala3LibraryID + "_" private[sbt] final val Scala3CompilerPrefix = Scala3CompilerID + "_" private[sbt] final val TastyCorePrefix = TastyCoreID + "_" private[sbt] final val Scala3DocPrefix = Scala3DocID + "_" + private[sbt] final val Scala3TastyInspectorPrefix = Scala3TastyInspectorID + "_" def isScala2Artifact(name: String): Boolean = { name == LibraryID || name == CompilerID || name == ReflectID || name == ActorsID || name == ScalapID @@ -26,7 +28,7 @@ object ScalaArtifacts { def isScala3Artifact(name: String): Boolean = { name.startsWith(Scala3LibraryPrefix) || name.startsWith(Scala3CompilerPrefix) || name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID || - name.startsWith(Scala3DocPrefix) + name.startsWith(Scala3DocPrefix) || name.startsWith(Scala3TastyInspectorPrefix) } def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.") From 5942ccbe1f8d62890824525aab8666b424055afa Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 3 Jan 2021 00:59:38 -0500 Subject: [PATCH 0906/1030] Add Scala 2.13 support --- .github/workflows/ci.yml | 2 +- build.sbt | 3 ++- .../scala/sbt/librarymanagement/EvictionError.scala | 8 ++++---- .../scala/sbt/librarymanagement/EvictionWarning.scala | 4 ++-- .../scala/sbt/librarymanagement/ModuleIDExtra.scala | 2 +- core/src/test/scala/UpdateReportSpec.scala | 5 +++-- .../sbt/internal/librarymanagement/UnitSpec.scala | 5 +++-- .../scala/sbt/librarymanagement/ConfigMacroTest.scala | 5 +++-- .../sbt/librarymanagement/SemanticSelectorSpec.scala | 5 +++-- .../sbt/librarymanagement/VersionNumberSpec.scala | 6 ++++-- .../internal/librarymanagement/CustomPomParser.scala | 4 ++-- .../sbt/internal/librarymanagement/IvyActions.scala | 2 +- .../sbt/internal/librarymanagement/IvyRetrieve.scala | 2 +- .../ivyint/IvyCredentialsLookup.scala | 10 +++++----- .../mavenint/PomExtraDependencyAttributes.scala | 2 +- .../sbt/internal/librarymanagement/IvyUtilSpec.scala | 4 ++-- project/Dependencies.scala | 5 +++-- 17 files changed, 41 insertions(+), 33 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 11c60e597..6f16581f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: run: | case ${{ matrix.jobtype }} in 1) - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies test packagedArtifacts + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies +test +packagedArtifacts ;; *) echo unknown jobtype diff --git a/build.sbt b/build.sbt index 62640cfb8..9a93044f7 100644 --- a/build.sbt +++ b/build.sbt @@ -54,7 +54,8 @@ def commonSettings: Seq[Setting[_]] = Def.settings( case sv if sv.startsWith("2.10") => old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") - case _ => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + case sv if sv.startsWith("2.12") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + case _ => old } }, inCompileAndTest( diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 09a767bad..ee9be4629 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -59,11 +59,11 @@ object EvictionError { }: _*) def calculateCompatible(p: EvictionPair): (Boolean, String) = { val winnerOpt = p.winner map { _.module } - val extraAttributes = (p.winner match { - case Some(r) => r.extraAttributes + val extraAttributes = ((p.winner match { + case Some(r) => r.extraAttributes.toMap case _ => Map.empty - }) ++ (winnerOpt match { - case Some(w) => w.extraAttributes + }): collection.immutable.Map[String, String]) ++ (winnerOpt match { + case Some(w) => w.extraAttributes.toMap case _ => Map.empty }) // prioritize user-defined version scheme to allow overriding the real scheme diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index e0519d981..926e93529 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -332,10 +332,10 @@ object EvictionWarning { def guessCompatible(p: EvictionPair): Boolean = p.evicteds forall { r => val winnerOpt = p.winner map { _.module } - val extraAttributes = (p.winner match { + val extraAttributes = ((p.winner match { case Some(r) => r.extraAttributes case _ => Map.empty - }) ++ (winnerOpt match { + }): collection.immutable.Map[String, String]) ++ (winnerOpt match { case Some(w) => w.extraAttributes case _ => Map.empty }) diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 40db9def1..f98f46aae 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -63,7 +63,7 @@ private[librarymanagement] abstract class ModuleIDExtra { /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ def extraDependencyAttributes: Map[String, String] = - extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)) + extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)).toMap @deprecated( "Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", diff --git a/core/src/test/scala/UpdateReportSpec.scala b/core/src/test/scala/UpdateReportSpec.scala index 12d7e70ca..d12d76585 100644 --- a/core/src/test/scala/UpdateReportSpec.scala +++ b/core/src/test/scala/UpdateReportSpec.scala @@ -2,9 +2,10 @@ package sbt.librarymanagement import java.io.File -import org.scalatest._ +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -class UpdateReportSpec extends FlatSpec with Matchers { +class UpdateReportSpec extends AnyFlatSpec with Matchers { "UpdateReport.toString" should "have a nice toString" in { assert(updateReport.toString === s""" |Update report: diff --git a/core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala b/core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala index 238e018e9..c656812d0 100644 --- a/core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala +++ b/core/src/test/scala/sbt/internal/librarymanagement/UnitSpec.scala @@ -2,6 +2,7 @@ package sbt package internal package librarymanagement -import org.scalatest._ +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers -abstract class UnitSpec extends FlatSpec with Matchers +abstract class UnitSpec extends AnyFlatSpec with Matchers diff --git a/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala b/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala index 85d798a21..1bb5d7a16 100644 --- a/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ConfigMacroTest.scala @@ -1,9 +1,10 @@ package sbt.librarymanagement import sbt.librarymanagement.Configurations.config -import org.scalatest._ +import org.scalatest.funspec.AnyFunSpec +import org.scalatest.matchers.should.Matchers -class ConfigMacroTest extends FunSpec with Matchers { +class ConfigMacroTest extends AnyFunSpec with Matchers { describe("Configurations.config") { it("should validate the ID in compile time") { """val A = config("a")""" should compile diff --git a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala index f7bf4f5bf..411554260 100644 --- a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala @@ -1,8 +1,9 @@ package sbt.librarymanagement -import org.scalatest.{ FreeSpec, Matchers } +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers -class SemanticSelectorSpec extends FreeSpec with Matchers { +class SemanticSelectorSpec extends AnyFreeSpec with Matchers { semsel("<=1.2.3") { sel => assertMatches(sel, "1.2.3") assertMatches(sel, "1.2-beta") diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 7a7038fba..a8691089e 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -1,9 +1,11 @@ package sbt.librarymanagement -import org.scalatest.{ FreeSpec, Inside, Matchers } +import org.scalatest.Inside +import org.scalatest.freespec.AnyFreeSpec +import org.scalatest.matchers.should.Matchers // This is a specification to check VersionNumber and VersionNumberCompatibility. -class VersionNumberSpec extends FreeSpec with Matchers with Inside { +class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { import VersionNumber.{ EarlySemVer, SemVer, PackVer } version("1") { v => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 514843cf4..e81ef45cd 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -154,7 +154,7 @@ object CustomPomParser { (propertyAttributes - ExtraAttributesKey) map { case (k, v) => ("e:" + k, v) } private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = - m.filterKeys(unqualifiedKeys) + m.filterKeys(unqualifiedKeys).toMap private[this] def addExtra( properties: Map[String, String], @@ -182,7 +182,7 @@ object CustomPomParser { def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include - }) + }).toMap def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = PomExtraDependencyAttributes.writeDependencyExtra(s) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 09e8b1e6b..41f82ab6d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -237,7 +237,7 @@ object IvyActions { }.toMap def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = - mods groupBy (grouping) mapValues (_.map(_.revision).toSet) + mods.groupBy(grouping).mapValues(_.map(_.revision).toSet).toMap def addExcluded( report: UpdateReport, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 67ebaa521..a6d2604ce 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -231,7 +231,7 @@ object IvyRetrieve { reports(report) map configurationReport, updateStats(report), Map.empty - ) recomputeStamps () + ).recomputeStamps() def updateStats(report: ResolveReport): UpdateStats = UpdateStats(report.getResolveTime, report.getDownloadTime, report.getDownloadSize, false) def configurationReport(confReport: ConfigurationResolveReport): ConfigurationReport = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index e2e119123..4d1e92420 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -47,20 +47,20 @@ private[sbt] object IvyCredentialsLookup { val map = credKeyringField.get(null).asInstanceOf[java.util.HashMap[String, Any]] // make a clone of the set... (map.keySet.asScala.map { - case KeySplit(realm, host) => Realm(host, realm) - case host => Host(host) - })(collection.breakOut) + case KeySplit(realm, host) => (Realm(host, realm): CredentialKey) + case host => (Host(host): CredentialKey) + }).toSet } /** * A mapping of host -> realms in the ivy credentials store. */ def realmsForHost: Map[String, Set[String]] = - keyringKeys collect { + (keyringKeys collect { case x: Realm => x } groupBy { realm => realm.host } mapValues { realms => realms map (_.realm) - } + }).toMap } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index c198f046d..25ab896b1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -80,7 +80,7 @@ object PomExtraDependencyAttributes { def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = (qualifiedExtra(item) filterKeys { k => qualifiedIsExtra(k) == include - }) + }).toMap def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala index 6924d739a..7b000ae45 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyUtilSpec.scala @@ -2,10 +2,10 @@ package sbt.internal.librarymanagement import java.io.IOException -import org.scalatest.FunSuite +import org.scalatest.funsuite.AnyFunSuite import sbt.internal.librarymanagement.IvyUtil._ -class IvyUtilSpec extends FunSuite { +class IvyUtilSpec extends AnyFunSuite { test("503 should be a TransientNetworkException") { val statusCode503Exception = new IOException("Server returned HTTP response code: 503 for URL:") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 186ffe67b..597789c67 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,7 +3,8 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.10" + val scala212 = "2.12.12" + val scala213 = "2.13.4" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -51,7 +52,7 @@ object Dependencies { val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" - val scalaTest = "org.scalatest" %% "scalatest" % "3.0.6-SNAP5" + val scalaTest = "org.scalatest" %% "scalatest" % "3.2.0" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "0.1.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" val sjsonnew = Def.setting { From 2b1806ae2511015a89539aacb0c4afc2d2064a04 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 8 Jan 2021 18:06:49 +0100 Subject: [PATCH 0907/1030] Add for3Use2_13 and for2_13Use3 --- .../LibraryManagementCodec.scala | 2 + .../sbt/librarymanagement/CrossVersion.scala | 140 +++++++++++++++++- .../librarymanagement/CrossVersionExtra.scala | 40 +++++ .../librarymanagement/CrossVersionTest.scala | 25 ++++ .../DMSerializationSpec.scala | 8 + project/DatatypeConfig.scala | 2 + 6 files changed, 214 insertions(+), 3 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index 06f3bfa22..fc918b42b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -19,6 +19,8 @@ trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigurationFormats diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala index 4ab1b6446..e447cb6a7 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersion.scala @@ -172,6 +172,82 @@ object Full { def apply(prefix: String, suffix: String): Full = new Full(prefix, suffix) } +/** + * Similar to Binary except that if the binary version is 3 + * (or if it is of the form 3.0.0-x) it uses 2.13 instead. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the binary version is "3", + * the module is cross-versioned with "foo_2.13_bar". + */ +final class For3Use2_13 private (val prefix: String, val suffix: String) + extends sbt.librarymanagement.CrossVersion() + with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: For3Use2_13 => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.librarymanagement.For3Use2_13".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "For3Use2_13(" + prefix + ", " + suffix + ")" + } + private[this] def copy(prefix: String = prefix, suffix: String = suffix): For3Use2_13 = { + new For3Use2_13(prefix, suffix) + } + def withPrefix(prefix: String): For3Use2_13 = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): For3Use2_13 = { + copy(suffix = suffix) + } +} +object For3Use2_13 { + + def apply(): For3Use2_13 = new For3Use2_13() + def apply(prefix: String, suffix: String): For3Use2_13 = new For3Use2_13(prefix, suffix) +} + +/** + * Similar to Binary except that if the binary version is 2.13 + * it uses 3 instead. + * For example, if `prefix = "foo_"` and `suffix = "_bar"` and the binary version is "2.13", + * the module is cross-versioned with "foo_3_bar". + */ +final class For2_13Use3 private (val prefix: String, val suffix: String) + extends sbt.librarymanagement.CrossVersion() + with Serializable { + + private def this() = this("", "") + + override def equals(o: Any): Boolean = o match { + case x: For2_13Use3 => (this.prefix == x.prefix) && (this.suffix == x.suffix) + case _ => false + } + override def hashCode: Int = { + 37 * (37 * (37 * (17 + "sbt.librarymanagement.For3Use2_13".##) + prefix.##) + suffix.##) + } + override def toString: String = { + "For3Use2_13(" + prefix + ", " + suffix + ")" + } + private[this] def copy(prefix: String = prefix, suffix: String = suffix): For2_13Use3 = { + new For2_13Use3(prefix, suffix) + } + def withPrefix(prefix: String): For2_13Use3 = { + copy(prefix = prefix) + } + def withSuffix(suffix: String): For2_13Use3 = { + copy(suffix = suffix) + } +} +object For2_13Use3 { + + def apply(): For2_13Use3 = new For2_13Use3() + def apply(prefix: String, suffix: String): For2_13Use3 = new For2_13Use3(prefix, suffix) +} + trait DisabledFormats { self: sjsonnew.BasicJsonProtocol => implicit lazy val DisabledFormat: JsonFormat[sbt.librarymanagement.Disabled] = new JsonFormat[sbt.librarymanagement.Disabled] { @@ -324,22 +400,80 @@ trait FullFormats { self: sjsonnew.BasicJsonProtocol => } } +trait For3Use2_13Formats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val For3Use2_13Format: JsonFormat[sbt.librarymanagement.For3Use2_13] = + new JsonFormat[sbt.librarymanagement.For3Use2_13] { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.For3Use2_13 = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.For3Use2_13(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.For3Use2_13, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } + } +} + +trait For2_13Use3Formats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val For2_13Use3Format: JsonFormat[sbt.librarymanagement.For2_13Use3] = + new JsonFormat[sbt.librarymanagement.For2_13Use3] { + override def read[J]( + jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.For2_13Use3 = { + jsOpt match { + case Some(js) => + unbuilder.beginObject(js) + val prefix = unbuilder.readField[String]("prefix") + val suffix = unbuilder.readField[String]("suffix") + unbuilder.endObject() + sbt.librarymanagement.For2_13Use3(prefix, suffix) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.For2_13Use3, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("prefix", obj.prefix) + builder.addField("suffix", obj.suffix) + builder.endObject() + } + } +} + trait CrossVersionFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats - with sbt.librarymanagement.FullFormats => + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats => implicit lazy val CrossVersionFormat: JsonFormat[CrossVersion] = { - val format = flatUnionFormat6[ + val format = flatUnionFormat8[ CrossVersion, Disabled, Disabled.type, Binary, Constant, Patch, - Full + Full, + For3Use2_13, + For2_13Use3 ]("type") // This is a hand-crafted formatter to avoid Disabled$ showing up in JSON new JsonFormat[CrossVersion] { diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 43a46073f..6e8ff00d6 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -17,10 +17,14 @@ private[librarymanagement] abstract class CrossVersionFunctions { final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full final val Patch = sbt.librarymanagement.Patch + final val For3Use2_13 = sbt.librarymanagement.For3Use2_13 + final val For2_13Use3 = sbt.librarymanagement.For2_13Use3 type Binary = sbt.librarymanagement.Binary type Constant = sbt.librarymanagement.Constant type Full = sbt.librarymanagement.Full type Patch = sbt.librarymanagement.Patch + type For3Use2_13 = sbt.librarymanagement.For3Use2_13 + type For2_13Use3 = sbt.librarymanagement.For2_13Use3 /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion @@ -57,6 +61,32 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def patch: CrossVersion = Patch() + /** + * Cross-versions a module with the binary version but + * if the binary version is 3 (or of the form 3.0.0-x), cross-versions it with 2.13 instead + */ + def for3Use2_13: CrossVersion = For3Use2_13() + + /** + * Cross-versions a module with the binary version but + * if the binary version is 3 (or of the form 3.0.0-x), cross-versions it with 2.13 instead + * Always prepend `prefix` and append `suffix` + */ + def for3Use2_13With(prefix: String, suffix: String): CrossVersion = For3Use2_13(prefix, suffix) + + /** + * Cross-versions a module with the binary version but + * if the binary version is 2.13 cross-versions it with 3 instead + */ + def for2_13Use3: CrossVersion = For2_13Use3() + + /** + * Cross-versions a module with the binary version but + * if the binary version is 2.13 cross-versions it with 3 instead + * Always prepend `prefix` and append `suffix` + */ + def for2_13Use3With(prefix: String, suffix: String): CrossVersion = For2_13Use3(prefix, suffix) + private[sbt] def patchFun(fullVersion: String): String = { val BinCompatV = """(\d+)\.(\d+)\.(\d+)(-\w+)??-bin(-.*)?""".r fullVersion match { @@ -83,6 +113,16 @@ private[librarymanagement] abstract class CrossVersionFunctions { case c: Constant => append(c.value) case _: Patch => append(patchFun(fullVersion)) case f: Full => append(f.prefix + fullVersion + f.suffix) + case c: For3Use2_13 => + val compat = + if (binaryVersion == "3" || binaryVersion.startsWith("3.0.0")) "2.13" + else binaryVersion + append(c.prefix + compat + c.suffix) + case c: For2_13Use3 => + val compat = + if (binaryVersion == "2.13") "3" + else binaryVersion + append(c.prefix + compat + c.suffix) } /** Constructs the cross-version function defined by `module` and `is`, if one is configured. */ diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 5864a4012..8f8f0e5b1 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -279,4 +279,29 @@ class CrossVersionTest extends UnitSpec { "CrossVersion.constant" should "have structural equality" in { CrossVersion.constant("duck") shouldBe CrossVersion.constant("duck") } + + "CrossVersion.for3Use2_13" should "have structural equality" in { + CrossVersion.for3Use2_13 shouldBe CrossVersion.for3Use2_13 + CrossVersion.for3Use2_13With("_sjs1", "") shouldBe CrossVersion.for3Use2_13With("_sjs1", "") + } + it should "use the cross version 2.13 instead of 3" in { + CrossVersion(CrossVersion.for3Use2_13, "3.0.0", "3").map(_("artefact")) shouldBe Some( + "artefact_2.13" + ) + } + it should "use the cross version 2.13 instead of 3.0.0-M3" in { + CrossVersion(CrossVersion.for3Use2_13, "3.0.0-M3", "3.0.0-M3").map(_("artefact")) shouldBe Some( + "artefact_2.13" + ) + } + + "CrossVersion.for2_13Use3" should "have structural equality" in { + CrossVersion.for2_13Use3 shouldBe CrossVersion.for2_13Use3 + CrossVersion.for2_13Use3With("_sjs1", "") shouldBe CrossVersion.for2_13Use3With("_sjs1", "") + } + it should "use the cross version 3 instead of 2.13" in { + CrossVersion(CrossVersion.for2_13Use3, "2.13.4", "2.13").map(_("artefact")) shouldBe Some( + "artefact_3" + ) + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 8ffd3ed1f..86cf43322 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -18,6 +18,14 @@ object DMSerializationSpec extends BasicTestSuite { roundtripStr(CrossVersion.binary: CrossVersion) } + test("CrossVersion.for3Use2_13 should roundtrip") { + roundtripStr(CrossVersion.for3Use2_13: CrossVersion) + } + + test("CrossVersion.for2_13Use3 with prefix should roundtrip") { + roundtripStr(CrossVersion.for2_13Use3With("_sjs1", ""): CrossVersion) + } + test("CrossVersion.Disabled should roundtrip") { roundtrip(Disabled(): CrossVersion) } diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index e87492601..dbd1ba8ce 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -49,6 +49,8 @@ object DatatypeConfig { "sbt.librarymanagement.ConstantFormats" :: "sbt.librarymanagement.PatchFormats" :: "sbt.librarymanagement.FullFormats" :: + "sbt.librarymanagement.For3Use2_13Formats" :: + "sbt.librarymanagement.For2_13Use3Formats" :: Nil } From 417a30f8dbf25a7923a196eceb7f56764254e6bb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 17 Jan 2021 04:18:49 -0500 Subject: [PATCH 0908/1030] Update to Scala 2.12.13 + 2.13.4 --- build.sbt | 9 +++------ .../scala/example/tests/CrossVersionCompatTest.scala | 4 ++-- project/Dependencies.scala | 5 ++--- project/build.properties | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/build.sbt b/build.sbt index 9a93044f7..93bb4b693 100644 --- a/build.sbt +++ b/build.sbt @@ -54,8 +54,9 @@ def commonSettings: Seq[Setting[_]] = Def.settings( case sv if sv.startsWith("2.10") => old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") - case sv if sv.startsWith("2.12") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") - case _ => old + case sv if sv.startsWith("2.12") => + old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + case _ => old } }, inCompileAndTest( @@ -119,10 +120,6 @@ lazy val lmCore = (project in file("core")) scalaCheck % Test, scalaVerify % Test, ), - libraryDependencies ++= (scalaVersion.value match { - case v if v.startsWith("2.12.") => List(compilerPlugin(silencerPlugin)) - case _ => List() - }), libraryDependencies += scalaXml, resourceGenerators in Compile += Def .task( diff --git a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala index 8aa136e8c..ab5f47633 100644 --- a/core/src/test/scala/example/tests/CrossVersionCompatTest.scala +++ b/core/src/test/scala/example/tests/CrossVersionCompatTest.scala @@ -2,9 +2,9 @@ package example.tests import sbt.librarymanagement.{ CrossVersion, Disabled } import verify.BasicTestSuite -import com.github.ghik.silencer.silent +import scala.annotation.nowarn -@silent +@nowarn object CrossVersionCompatTest extends BasicTestSuite { test("CrossVersion.Disabled is typed to be Disabled") { assert(CrossVersion.Disabled match { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 597789c67..4dcecc8c6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,13 +3,13 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.12" + val scala212 = "2.12.13" val scala213 = "2.13.4" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.4.0") + private val ioVersion = nightlyVersion.getOrElse("1.5.0-M1") private val utilVersion = nightlyVersion.getOrElse("1.4.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -63,5 +63,4 @@ object Dependencies { } val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" - val silencerPlugin = "com.github.ghik" %% "silencer-plugin" % "1.4.1" } diff --git a/project/build.properties b/project/build.properties index c06db1bb2..d91c272d4 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.5 +sbt.version=1.4.6 From 7b45fc594f7122741bdf0805420ce259ce0eefb3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 17 Jan 2021 06:00:12 -0500 Subject: [PATCH 0909/1030] Contraband files --- .../sbt/librarymanagement/InclExclRuleFormats.scala | 2 +- .../sbt/librarymanagement/ModuleIDFormats.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala index a6a4bcd2d..837b478e9 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/InclExclRuleFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => +trait InclExclRuleFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sjsonnew.BasicJsonProtocol => implicit lazy val InclExclRuleFormat: JsonFormat[sbt.librarymanagement.InclExclRule] = new JsonFormat[sbt.librarymanagement.InclExclRule] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.InclExclRule = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala index f09a501cc..b1c27558d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sjsonnew.BasicJsonProtocol => +trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = new JsonFormat[sbt.librarymanagement.ModuleID] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { __jsOpt match { From 12d46e3fce736033b2099d53b849e0224bfc0886 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 23 Jan 2021 15:38:53 -0500 Subject: [PATCH 0910/1030] Make ModuleID#cross(...) preserve existing prefix Fixes https://github.com/sbt/sbt/issues/6280 sbt-platform-deps implements `%%%` operator in https://github.com/portable-scala/sbt-platform-deps/blob/v1.0.0/src/main/scala/org/portablescala/sbtplatformdeps/PlatformDepsBuilders.scala#L36-L43 by setting the prefix field on `sbt.librarymanagement.Binary(...)`. Currently `.cross(...)` would wipe this out, so `%%%` and `cross(CrossVersion.for3Use2_13)` do not compose. This changes the implementation of `.cross(...)` so it can be chained together and it will try to preserve the prefix (and suffix) values from the existing `crossVersion` values. This should fix the 2.13-3.x sandwich on Scala.JS and Scala Native. --- .../librarymanagement/CrossVersionExtra.scala | 22 +++++++-- .../sbt/librarymanagement/ModuleIDExtra.scala | 24 +++++++++- .../sbt/librarymanagement/ModuleIdTest.scala | 46 +++++++++++++------ project/Dependencies.scala | 2 +- 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 6e8ff00d6..a37a52d7c 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -17,14 +17,10 @@ private[librarymanagement] abstract class CrossVersionFunctions { final val Constant = sbt.librarymanagement.Constant final val Full = sbt.librarymanagement.Full final val Patch = sbt.librarymanagement.Patch - final val For3Use2_13 = sbt.librarymanagement.For3Use2_13 - final val For2_13Use3 = sbt.librarymanagement.For2_13Use3 type Binary = sbt.librarymanagement.Binary type Constant = sbt.librarymanagement.Constant type Full = sbt.librarymanagement.Full type Patch = sbt.librarymanagement.Patch - type For3Use2_13 = sbt.librarymanagement.For3Use2_13 - type For2_13Use3 = sbt.librarymanagement.For2_13Use3 /** The first `major.minor` Scala version that the Scala binary version should be used for cross-versioning instead of the full version. */ val TransitionScalaVersion = CrossVersionUtil.TransitionScalaVersion @@ -87,6 +83,24 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def for2_13Use3With(prefix: String, suffix: String): CrossVersion = For2_13Use3(prefix, suffix) + private[sbt] def getPrefixSuffix(value: CrossVersion): (String, String) = + value match { + case (_: Disabled | _: Constant | _: Patch) => ("", "") + case b: Binary => (b.prefix, b.suffix) + case f: Full => (f.prefix, f.suffix) + case c: For3Use2_13 => (c.prefix, c.suffix) + case c: For2_13Use3 => (c.prefix, c.suffix) + } + + private[sbt] def setPrefixSuffix(value: CrossVersion, p: String, s: String): CrossVersion = + value match { + case (_: Disabled | _: Constant | _: Patch) => value + case b: Binary => b.withPrefix(p).withSuffix(s) + case f: Full => f.withPrefix(p).withSuffix(s) + case c: For3Use2_13 => c.withPrefix(p).withSuffix(s) + case c: For2_13Use3 => c.withPrefix(p).withSuffix(s) + } + private[sbt] def patchFun(fullVersion: String): String = { val BinCompatV = """(\d+)\.(\d+)\.(\d+)(-\w+)??-bin(-.*)?""".r fullVersion match { diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index f98f46aae..c5191467c 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -71,8 +71,28 @@ private[librarymanagement] abstract class ModuleIDExtra { ) def cross(v: Boolean): ModuleID = cross(if (v) CrossVersion.binary else Disabled()) - /** Specifies the cross-version behavior for this module. See [CrossVersion] for details.*/ - def cross(v: CrossVersion): ModuleID = withCrossVersion(v) + /** + * Specifies the cross-version behavior for this module. See [CrossVersion] for details. + * Unlike `withCrossVersion(...)`, `cross(...)` will preserve the prefix and suffix + * values from the existing `crossVersion` value. + * + * {{{ + * ModuleID("com.example", "foo", "1.0") + * .cross(CrossVersion.binaryWith("sjs1_", "")) + * .cross(CrossVersion.for3Use2_13) + * }}} + * + * This allows `.cross(...)` to play well with `%%%` operator provided by sbt-platform-deps. + */ + def cross(v: CrossVersion): ModuleID = + withCrossVersion(CrossVersion.getPrefixSuffix(this.crossVersion) match { + case ("", "") => v + case (prefix, suffix) => + CrossVersion.getPrefixSuffix(v) match { + case ("", "") => CrossVersion.setPrefixSuffix(v, prefix, suffix) + case _ => v + } + }) // () required for chaining /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ diff --git a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala index 1698f317a..1c962aac2 100644 --- a/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ModuleIdTest.scala @@ -1,31 +1,49 @@ package sbt.librarymanagement -import sbt.internal.librarymanagement.UnitSpec import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter, Parser } -class ModuleIdTest extends UnitSpec { - val expectedJson = - """{"organization":"com.acme","name":"foo","revision":"1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}""" - "Module Id" should "return cross-disabled module id as equal to a copy" in { - ModuleID("com.acme", "foo", "1") shouldBe ModuleID("com.acme", "foo", "1") +object ModuleIdTest extends verify.BasicTestSuite { + test("Module Id should return cross-disabled module id as equal to a copy") { + assert(ModuleID("com.acme", "foo", "1") == ModuleID("com.acme", "foo", "1")) } - it should "return cross-full module id as equal to a copy" in { - (ModuleID("com.acme", "foo", "1") cross CrossVersion.full) shouldBe - (ModuleID("com.acme", "foo", "1") cross CrossVersion.full) + + test("it should return cross-full module id as equal to a copy") { + assert( + ModuleID("com.acme", "foo", "1").cross(CrossVersion.full) == + ModuleID("com.acme", "foo", "1").cross(CrossVersion.full) + ) } - it should "return cross-binary module id as equal to a copy" in { - (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) shouldBe - (ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) + + test("it should return cross-binary module id as equal to a copy") { + assert( + ModuleID("com.acme", "foo", "1").cross(CrossVersion.binary) == + ModuleID("com.acme", "foo", "1").cross(CrossVersion.binary) + ) } - it should "format itself into JSON" in { + + test("it should format itself into JSON") { import LibraryManagementCodec._ val json = Converter.toJson(ModuleID("com.acme", "foo", "1")).get assert(CompactPrinter(json) == expectedJson) } - it should "thaw back from JSON" in { + + test("it should thaw back from JSON") { import LibraryManagementCodec._ val json = Parser.parseUnsafe(expectedJson) val m = Converter.fromJsonUnsafe[ModuleID](json) assert(m == ModuleID("com.acme", "foo", "1")) } + + test("cross(...) should compose prefix with the existing value") { + assert( + ModuleID("com.acme", "foo", "1") + .cross(CrossVersion.binaryWith("sjs1_", "")) + .cross(CrossVersion.for3Use2_13) + == + ModuleID("com.acme", "foo", "1").cross(CrossVersion.for3Use2_13With("sjs1_", "")) + ) + } + + def expectedJson = + """{"organization":"com.acme","name":"foo","revision":"1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}""" } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 4dcecc8c6..6e8de8452 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -53,7 +53,7 @@ object Dependencies { val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" val scalaTest = "org.scalatest" %% "scalatest" % "3.2.0" - val scalaVerify = "com.eed3si9n.verify" %% "verify" % "0.1.0" + val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value From 3a9b0303f80e076268d2d484122959a5b7097f30 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 14 Feb 2021 13:21:53 -0500 Subject: [PATCH 0911/1030] Follow up on scala3doc rename Ref https://github.com/sbt/sbt/issues/6307 Ref https://github.com/lampepfl/dotty/pull/11289 --- .../librarymanagement/ScalaArtifacts.scala | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index 01e2ffe34..82c454e24 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -13,12 +13,14 @@ object ScalaArtifacts { final val Scala3CompilerID = "scala3-compiler" final val Scala3InterfacesID = "scala3-interfaces" final val TastyCoreID = "tasty-core" + final val ScaladocID = "scaladoc" final val Scala3DocID = "scala3doc" final val Scala3TastyInspectorID = "scala3-tasty-inspector" private[sbt] final val Scala3LibraryPrefix = Scala3LibraryID + "_" private[sbt] final val Scala3CompilerPrefix = Scala3CompilerID + "_" private[sbt] final val TastyCorePrefix = TastyCoreID + "_" + private[sbt] final val ScaladocPrefix = ScaladocID + "_" private[sbt] final val Scala3DocPrefix = Scala3DocID + "_" private[sbt] final val Scala3TastyInspectorPrefix = Scala3TastyInspectorID + "_" @@ -26,13 +28,22 @@ object ScalaArtifacts { name == LibraryID || name == CompilerID || name == ReflectID || name == ActorsID || name == ScalapID } def isScala3Artifact(name: String): Boolean = { - name.startsWith(Scala3LibraryPrefix) || name.startsWith(Scala3CompilerPrefix) || - name.startsWith(TastyCorePrefix) || name == Scala3InterfacesID || - name.startsWith(Scala3DocPrefix) || name.startsWith(Scala3TastyInspectorPrefix) + name.startsWith(Scala3LibraryPrefix) || + name.startsWith(Scala3CompilerPrefix) || + name.startsWith(TastyCorePrefix) || + name == Scala3InterfacesID || + name.startsWith(ScaladocPrefix) || + name.startsWith(Scala3DocPrefix) || + name.startsWith(Scala3TastyInspectorPrefix) } def isScala3(scalaVersion: String): Boolean = scalaVersion.startsWith("3.") + private[sbt] def isScala3M123(scalaVersion: String): Boolean = + (scalaVersion == "3.0.0-M1") || + (scalaVersion == "3.0.0-M2") || + (scalaVersion == "3.0.0-M3") + def libraryIds(version: String): Array[String] = { if (isScala3(version)) Array(Scala3LibraryID, LibraryID) @@ -57,13 +68,19 @@ object ScalaArtifacts { org: String, version: String ): Seq[ModuleID] = - if (isScala3(version)) { + if (isScala3M123(version)) Seq( ModuleID(org, Scala3DocID, version) .withConfigurations(Some(Configurations.ScalaDocTool.name + "->default(compile)")) .withCrossVersion(CrossVersion.binary) ) - } else Seq.empty + else if (isScala3(version)) + Seq( + ModuleID(org, ScaladocID, version) + .withConfigurations(Some(Configurations.ScalaDocTool.name + "->default(compile)")) + .withCrossVersion(CrossVersion.binary) + ) + else Seq.empty private[sbt] def toolDependencies( org: String, From dc0b682d7ee1ed03fc3f21d9bd0a533ce9fd2d3b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 Feb 2021 04:49:36 -0500 Subject: [PATCH 0912/1030] Implement assumedVersionScheme Ref https://github.com/sbt/sbt/issues/6302 Ref https://github.com/sbt/sbt/issues/6301 Apparently some users are interested in keeping the eviction warning feature, so here's an option to bring guessing back. --- .../librarymanagement/VersionSchemes.scala | 13 ++- .../sbt/librarymanagement/EvictionError.scala | 80 +++++++++++++------ .../librarymanagement/EvictionWarning.scala | 2 +- .../librarymanagement/EvictionErrorSpec.scala | 19 +++++ 4 files changed, 87 insertions(+), 27 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala index b8a5b1293..e214cc377 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -10,7 +10,7 @@ package internal package librarymanagement import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties -import sbt.librarymanagement.ModuleID +import sbt.librarymanagement.{ EvictionWarningOptions, ModuleID, ScalaModuleInfo } // See APIMappings.scala private[sbt] object VersionSchemes { @@ -42,4 +42,15 @@ private[sbt] object VersionSchemes { def extractFromExtraAttributes(extraAttributes: Map[String, String]): Option[String] = extraAttributes.get(SbtPomExtraProperties.VERSION_SCHEME_KEY) + + def evalFunc( + scheme: String + ): Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = + scheme match { + case EarlySemVer => EvictionWarningOptions.guessEarlySemVer + case SemVerSpec => EvictionWarningOptions.guessSemVer + case PackVer => EvictionWarningOptions.evalPvp + case Strict => EvictionWarningOptions.guessStrict + case Always => EvictionWarningOptions.guessTrue + } } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index ee9be4629..aaf926dec 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -3,23 +3,47 @@ package librarymanagement import scala.collection.mutable import sbt.internal.librarymanagement.VersionSchemes -import sbt.util.ShowLines +import sbt.util.{ Level, ShowLines } +import EvictionWarningOptions.isNameScalaSuffixed object EvictionError { def apply( report: UpdateReport, module: ModuleDescriptor, schemes: Seq[ModuleID], + ): EvictionError = { + apply(report, module, schemes, "always", "always", Level.Debug) + } + + def apply( + report: UpdateReport, + module: ModuleDescriptor, + schemes: Seq[ModuleID], + assumedVersionScheme: String, + assumedVersionSchemeJava: String, + assumedEvictionErrorLevel: Level.Value, ): EvictionError = { val options = EvictionWarningOptions.full val evictions = EvictionWarning.buildEvictions(options, report) - processEvictions(module, options, evictions, schemes) + processEvictions( + module, + options, + evictions, + schemes, + assumedVersionScheme, + assumedVersionSchemeJava, + assumedEvictionErrorLevel, + ) } + private[sbt] def processEvictions( module: ModuleDescriptor, options: EvictionWarningOptions, reports: Seq[OrganizationArtifactReport], schemes: Seq[ModuleID], + assumedVersionScheme: String, + assumedVersionSchemeJava: String, + assumedEvictionErrorLevel: Level.Value, ): EvictionError = { val directDependencies = module.directDependencies val pairs = reports map { detail => @@ -35,6 +59,7 @@ object EvictionError { ) } val incompatibleEvictions: mutable.ListBuffer[(EvictionPair, String)] = mutable.ListBuffer() + val assumedIncompatEvictions: mutable.ListBuffer[(EvictionPair, String)] = mutable.ListBuffer() val sbvOpt = module.scalaModuleInfo.map(_.scalaBinaryVersion) val userDefinedSchemes: Map[(String, String), String] = Map(schemes flatMap { s => val organization = s.organization @@ -57,7 +82,8 @@ object EvictionError { List((s.organization, s.name) -> versionScheme) } }: _*) - def calculateCompatible(p: EvictionPair): (Boolean, String) = { + + def calculateCompatible(p: EvictionPair): (Boolean, String, Boolean, String) = { val winnerOpt = p.winner map { _.module } val extraAttributes = ((p.winner match { case Some(r) => r.extraAttributes.toMap @@ -73,36 +99,34 @@ object EvictionError { .orElse(VersionSchemes.extractFromExtraAttributes(extraAttributes)) .orElse(userDefinedSchemes.get(("*", "*"))) val f = (winnerOpt, schemeOpt) match { - case (Some(_), Some(VersionSchemes.Always)) => - EvictionWarningOptions.guessTrue - case (Some(_), Some(VersionSchemes.Strict)) => - EvictionWarningOptions.guessStrict - case (Some(_), Some(VersionSchemes.EarlySemVer)) => - EvictionWarningOptions.guessEarlySemVer - case (Some(_), Some(VersionSchemes.SemVerSpec)) => - EvictionWarningOptions.guessSemVer - case (Some(_), Some(VersionSchemes.PackVer)) => - EvictionWarningOptions.evalPvp - case _ => EvictionWarningOptions.guessTrue + case (Some(_), Some(scheme)) => VersionSchemes.evalFunc(scheme) + case _ => EvictionWarningOptions.guessTrue } + val scheme = + if (isNameScalaSuffixed(p.name)) assumedVersionScheme + else assumedVersionSchemeJava + val guess = VersionSchemes.evalFunc(scheme) (p.evicteds forall { r => f((r.module, winnerOpt, module.scalaModuleInfo)) - }, schemeOpt.getOrElse("?")) + }, schemeOpt.getOrElse("?"), p.evicteds forall { r => + guess((r.module, winnerOpt, module.scalaModuleInfo)) + }, scheme) } pairs foreach { + // don't report on a transitive eviction that does not have a winner + // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => - // don't report on a transitive eviction that does not have a winner - // https://github.com/sbt/sbt/issues/4946 - if (p.winner.isDefined) { - val r = calculateCompatible(p) - if (!r._1) { - incompatibleEvictions += (p -> r._2) - } + val r = calculateCompatible(p) + if (!r._1) { + incompatibleEvictions += (p -> r._2) + } else if (!r._3) { + assumedIncompatEvictions += (p -> r._4) } case _ => () } new EvictionError( incompatibleEvictions.toList, + assumedIncompatEvictions.toList, ) } @@ -113,17 +137,22 @@ object EvictionError { final class EvictionError private[sbt] ( val incompatibleEvictions: Seq[(EvictionPair, String)], + val assumedIncompatibleEvictions: Seq[(EvictionPair, String)], ) { def run(): Unit = if (incompatibleEvictions.nonEmpty) { sys.error(toLines.mkString("\n")) } - def toLines: List[String] = { + def toLines: List[String] = toLines(incompatibleEvictions, false) + + def toAssumedLines: List[String] = toLines(assumedIncompatibleEvictions, true) + + def toLines(evictions: Seq[(EvictionPair, String)], assumed: Boolean): List[String] = { val out: mutable.ListBuffer[String] = mutable.ListBuffer() out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" - incompatibleEvictions.foreach({ + evictions.foreach({ case (a, scheme) => val revs = a.evicteds map { _.module.revision } val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" @@ -138,8 +167,9 @@ final class EvictionError private[sbt] ( } } } + val que = if (assumed) "?" else "" val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme) is selected over ${revsStr}" + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 926e93529..d646303e4 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -98,7 +98,7 @@ object EvictionWarningOptions { lazy val defaultGuess: Function1[(ModuleID, Option[ModuleID], Option[ScalaModuleInfo]), Boolean] = guessSbtOne orElse guessSecondSegment orElse guessSemVer orElse guessFalse - private def isNameScalaSuffixed(name: String): Boolean = + private[sbt] def isNameScalaSuffixed(name: String): Boolean = name.contains("_2.") || name.contains("_3") || name.contains("_4") /** A partial function that checks if given m2 is suffixed, and use pvp to evaluate. */ diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index 76edf91f9..a6b97c99e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -3,6 +3,7 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.internal.librarymanagement.cross.CrossVersionUtil import sbt.librarymanagement.syntax._ +import sbt.util.Level object EvictionErrorSpec extends BaseIvySpecification { // This is a specification to check the eviction errors @@ -50,6 +51,24 @@ object EvictionErrorSpec extends BaseIvySpecification { ) } + test("it should be able to emulate eviction warnings") { + val deps = Vector(`scala2.10.4`, `bananaSesame0.4`, `akkaRemote2.3.4`) + val m = module(defaultModuleId, deps, Some("2.10.4")) + val report = ivyUpdate(m) + assert( + EvictionError(report, m, Nil, "pvp", "early-semver", Level.Warn).toAssumedLines == + List( + "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:", + "", + "\t* com.typesafe.akka:akka-actor_2.10:2.3.4 (pvp?) is selected over 2.1.4", + "\t +- com.typesafe.akka:akka-remote_2.10:2.3.4 (depends on 2.3.4)", + "\t +- org.w3:banana-rdf_2.10:0.4 (depends on 2.1.4)", + "\t +- org.w3:banana-sesame_2.10:0.4 (depends on 2.1.4)", + "" + ) + ) + } + test("it should detect Semantic Versioning violations") { val deps = Vector(`scala2.13.3`, `http4s0.21.11`, `cats-effect3.0.0-M4`) val m = module(defaultModuleId, deps, Some("2.13.3")) From 3132647ac1bfd04b47344af16e14670a57b0666b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20Mass=C3=A9?= Date: Sat, 6 Mar 2021 22:42:32 -0500 Subject: [PATCH 0913/1030] Fix sbt/sbt#6362 --- .../librarymanagement/ivy/Credentials.scala | 10 +++++-- .../librarymanagement/CredentialsSpec.scala | 28 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 7ebc4521d..df8614525 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -47,9 +47,13 @@ object Credentials { .headOption .toRight(keys.head + " not specified in credentials file: " + path) - IvyUtil.separate(List(RealmKeys, HostKeys, UserKeys, PasswordKeys).map(get)) match { - case (Nil, List(realm, host, user, pass)) => - Right(new DirectCredentials(realm, host, user, pass)) + IvyUtil.separate(List(HostKeys, UserKeys, PasswordKeys).map(get)) match { + case (Nil, List(host, user, pass)) => + IvyUtil.separate(List(RealmKeys).map(get)) match { + case (_, List(realm)) => Right(new DirectCredentials(realm, host, user, pass)) + case _ => Right(new DirectCredentials(null, host, user, pass)) + } + case (errors, _) => Left(errors.mkString("\n")) } } else diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala new file mode 100644 index 000000000..7c2386cb8 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -0,0 +1,28 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement.ivy.Credentials + +import java.io.File +import java.nio.file.Files + +import org.scalatest.funsuite.AnyFunSuite + +class CredentialsSpec extends AnyFunSuite { + + test("load credential file without authentication") { + val credentialsFile = File.createTempFile("credentials", "tmp") + + val content = + """|host=example.org + |user=username + |password=password""".stripMargin + + Files.write(credentialsFile.toPath(), content.getBytes()) + + val Right(credentials) = Credentials.loadCredentials(credentialsFile) + + assert(credentials.realm == null) + + credentialsFile.delete() + } +} From 956e8483f53e4228aa84b93199356f16189aa3f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guillaume=20Mass=C3=A9?= Date: Mon, 8 Mar 2021 23:19:55 -0500 Subject: [PATCH 0914/1030] Dont quote realm if it's null in Credentials.toString --- .../sbt/librarymanagement/ivy/Credentials.scala | 8 +++++++- .../internal/librarymanagement/CredentialsSpec.scala | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index df8614525..ef2766480 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -88,5 +88,11 @@ final class DirectCredentials( val userName: String, val passwd: String ) extends Credentials { - override def toString = s"""DirectCredentials("$realm", "$host", "$userName", ****)""" + override def toString = { + val dq = '"' + val r = + if (realm == null) "null" + else dq + realm + dq + s"""DirectCredentials($r, "$host", "$userName", ****)""" + } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala index 7c2386cb8..e546f9758 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -25,4 +25,16 @@ class CredentialsSpec extends AnyFunSuite { credentialsFile.delete() } + + test("DirectCredentials.toString") { + assert( + Credentials(realm = null, host = "example.org", userName = "username", passwd = "password").toString == + """DirectCredentials(null, "example.org", "username", ****)""" + ) + + assert( + Credentials(realm = "realm", host = "example.org", userName = "username", passwd = "password").toString == + """DirectCredentials("realm", "example.org", "username", ****)""" + ) + } } From d39d6a6186a2b5f8bedc31e7ceff95d2b1206150 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 21 Feb 2021 14:09:52 -0500 Subject: [PATCH 0915/1030] crossScalaVersions --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 93bb4b693..4451c86ea 100644 --- a/build.sbt +++ b/build.sbt @@ -46,7 +46,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), - crossScalaVersions := Seq(scala212), + crossScalaVersions := Seq(scala212, scala213), resolvers += Resolver.sonatypeRepo("public"), scalacOptions := { val old = scalacOptions.value From 7f6bbafb9b38e44cb98d57e4f6da6bcbf8da7226 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 14 Mar 2021 23:57:13 -0400 Subject: [PATCH 0916/1030] Remove sbt-bintray --- build.sbt | 6 +++++- project/HouseRulesPlugin.scala | 12 +----------- project/plugins.sbt | 3 +-- 3 files changed, 7 insertions(+), 14 deletions(-) diff --git a/build.sbt b/build.sbt index 4451c86ea..804682182 100644 --- a/build.sbt +++ b/build.sbt @@ -18,7 +18,6 @@ ThisBuild / version := { } ThisBuild / versionScheme := Some("early-semver") ThisBuild / organization := "org.scala-sbt" -ThisBuild / bintrayPackage := sys.env.get("BINTRAY_PACKAGE").getOrElse("librarymanagement") ThisBuild / homepage := Some(url("https://github.com/sbt/librarymanagement")) ThisBuild / description := "Library management module for sbt" ThisBuild / scmInfo := { @@ -32,6 +31,11 @@ ThisBuild / developers := List( Developer("eed3si9n", "Eugene Yokota", "@eed3si9n", url("http://eed3si9n.com/")), Developer("dwijnand", "Dale Wijnand", "@dwijnand", url("https://github.com/dwijnand")), ) +ThisBuild / pomIncludeRepository := (_ => false) // drop repos other than Maven Central from POM +ThisBuild / publishTo := { + val nexus = "https://oss.sonatype.org/" + Some("releases" at nexus + "service/local/staging/deploy/maven2") +} ThisBuild / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index f204ee310..b71b74434 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -2,24 +2,14 @@ package lmbuild import sbt._ import Keys._ -import bintray.BintrayPlugin -import bintray.BintrayPlugin.autoImport._ object HouseRulesPlugin extends AutoPlugin { - override def requires = plugins.JvmPlugin && BintrayPlugin + override def requires = plugins.JvmPlugin override def trigger = allRequirements - override def buildSettings: Seq[Def.Setting[_]] = baseBuildSettings override def projectSettings: Seq[Def.Setting[_]] = baseSettings - lazy val baseBuildSettings: Seq[Def.Setting[_]] = Seq( - bintrayOrganization := Some("sbt"), - bintrayRepository := sys.env.get("BINTRAY_REPOSITORY").getOrElse("maven-releases"), - ) - lazy val baseSettings: Seq[Def.Setting[_]] = Seq( - bintrayPackage := (ThisBuild / bintrayPackage).value, - bintrayRepository := (ThisBuild / bintrayRepository).value, scalacOptions ++= Seq("-encoding", "utf8"), scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint"), scalacOptions += "-language:higherKinds", diff --git a/project/plugins.sbt b/project/plugins.sbt index d72359f9e..ce812048d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,5 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") -addSbtPlugin("org.foundweekends" % "sbt-bintray" % "0.5.6") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.0.1") +addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") From fd9e1cd92985c8c798851667408d12285ed718cc Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 18 Mar 2021 15:15:11 +0100 Subject: [PATCH 0917/1030] No binary scala warning if 3 and 2.13 --- .../sbt/internal/librarymanagement/IvyScalaUtil.scala | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 2a4e4a27f..98e8b6721 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -144,7 +144,13 @@ object IvyScalaUtil { val depBinaryVersion = CrossVersion.binaryScalaVersion(id.getRevision) def isScalaLangOrg = id.getOrganisation == scalaOrganization def isScalaArtifact = scalaArtifacts.contains[String](id.getName) - def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion + + def hasBinVerMismatch = + depBinaryVersion != scalaBinaryVersion && + // scala 2.13 is compatible with scala 3.x + Seq(depBinaryVersion, scalaBinaryVersion) + .forall(bv => bv.startsWith("3") || bv.startsWith("2.13")) + def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) From fe33ed19de748d4f8ea876778855e3b7b94ab433 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 22 Mar 2021 02:30:00 -0400 Subject: [PATCH 0918/1030] Fix binary Scala warning, take 2 Ref https://github.com/sbt/librarymanagement/pull/372 --- .../scala/sbt/internal/librarymanagement/IvyScalaUtil.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 98e8b6721..3ea763301 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -148,7 +148,7 @@ object IvyScalaUtil { def hasBinVerMismatch = depBinaryVersion != scalaBinaryVersion && // scala 2.13 is compatible with scala 3.x - Seq(depBinaryVersion, scalaBinaryVersion) + !Seq(depBinaryVersion, scalaBinaryVersion) .forall(bv => bv.startsWith("3") || bv.startsWith("2.13")) def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } From c98e51418faa0cad784c71c96952a935232ec309 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 30 Mar 2021 17:50:50 +0200 Subject: [PATCH 0919/1030] Fix binary version of 3.0.1-RC1 --- .../librarymanagement/cross/CrossVersionUtil.scala | 10 +++++----- .../scala/sbt/librarymanagement/CrossVersionTest.scala | 9 +++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 8cd43fe55..15e7bb9bb 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -75,11 +75,11 @@ object CrossVersionUtil { } private[sbt] def binaryScala3Version(full: String): String = full match { - case ReleaseV(maj, _, _, _) => maj - case CandidateV(maj, min, _, _) if min.toLong > 0 => maj - case MilestonV(maj, min, _, _) if min.toLong > 0 => maj - case BinCompatV(maj, min, patch, stage, _) => binaryScala3Version(s"$maj.$min.$patch$stage") - case _ => full + case ReleaseV(maj, _, _, _) => maj + case CandidateV(maj, min, patch, _) if min.toLong > 0 || patch.toLong > 0 => maj + case MilestonV(maj, min, patch, _) if min.toLong > 0 || patch.toLong > 0 => maj + case BinCompatV(maj, min, patch, stage, _) => binaryScala3Version(s"$maj.$min.$patch$stage") + case _ => full } def binaryScalaVersion(full: String): String = { diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 8f8f0e5b1..05e849520 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -237,6 +237,15 @@ class CrossVersionTest extends UnitSpec { it should "for 3.1.0 return 3" in { binaryScalaVersion("3.1.0") shouldBe "3" } + it should "for 3.0.1-RC1 return 3" in { + binaryScalaVersion("3.0.1-RC1") shouldBe "3" + } + it should "for 3.0.1-M1 return 3" in { + binaryScalaVersion("3.0.1-M1") shouldBe "3" + } + it should "for 3.0.1-RC1-bin-SNAPSHOT return 3" in { + binaryScalaVersion("3.0.1-RC1") shouldBe "3" + } private def patchVersion(fullVersion: String) = CrossVersion(CrossVersion.patch, fullVersion, "dummy") map (fn => fn("artefact")) From c43aea5e68216da8adf3a1e95542c6157784e98c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 3 Apr 2021 21:28:51 -0400 Subject: [PATCH 0920/1030] IO 1.5.0, Util 1.5.0 --- project/Dependencies.scala | 6 +++--- project/build.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 6e8de8452..0b0f4b745 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,13 +4,13 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.13" - val scala213 = "2.13.4" + val scala213 = "2.13.5" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.5.0-M1") - private val utilVersion = nightlyVersion.getOrElse("1.4.0") + private val ioVersion = nightlyVersion.getOrElse("1.5.0") + private val utilVersion = nightlyVersion.getOrElse("1.5.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion diff --git a/project/build.properties b/project/build.properties index d91c272d4..dbae93bcf 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.6 +sbt.version=1.4.9 From 5269e12e6764428c2f70446a3c81741f0c29a33c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 2 May 2021 22:18:03 -0400 Subject: [PATCH 0921/1030] Use sbt 1.5.1 --- build.sbt | 42 +++++++++++++++++++--------------- project/HouseRulesPlugin.scala | 2 +- project/build.properties | 2 +- project/plugins.sbt | 2 +- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/build.sbt b/build.sbt index 804682182..00e45416b 100644 --- a/build.sbt +++ b/build.sbt @@ -49,7 +49,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), - javacOptions in compile ++= Seq("-Xlint", "-Xlint:-serial"), + compile / javacOptions ++= Seq("-Xlint", "-Xlint:-serial"), crossScalaVersions := Seq(scala212, scala213), resolvers += Resolver.sonatypeRepo("public"), scalacOptions := { @@ -64,13 +64,13 @@ def commonSettings: Seq[Setting[_]] = Def.settings( } }, inCompileAndTest( - scalacOptions in console --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") + (console / scalacOptions) --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint") ), scalafmtOnCompile := true, Test / scalafmtOnCompile := true, - publishArtifact in Compile := true, - publishArtifact in Test := false, - parallelExecution in Test := false + Compile / publishArtifact := true, + Test / publishArtifact := false, + Test / parallelExecution := false ) val mimaSettings = Def settings ( @@ -87,6 +87,8 @@ val mimaSettings = Def settings ( "1.1.4", "1.2.0", "1.3.0", + "1.4.0", + "1.5.0", ) map ( version => organization.value %% moduleName.value % version @@ -101,7 +103,7 @@ lazy val lmRoot = (project in file(".")) name := "LM Root", publish := {}, publishLocal := {}, - publishArtifact in Compile := false, + Compile / publishArtifact := false, publishArtifact := false, mimaPreviousArtifacts := Set.empty, customCommands, @@ -125,13 +127,13 @@ lazy val lmCore = (project in file("core")) scalaVerify % Test, ), libraryDependencies += scalaXml, - resourceGenerators in Compile += Def + Compile / resourceGenerators += Def .task( Util.generateVersionFile( version.value, resourceManaged.value, streams.value, - (compile in Compile).value + (Compile / compile).value ) ) .taskValue, @@ -139,14 +141,14 @@ lazy val lmCore = (project in file("core")) case v if v.startsWith("2.12.") => List("-Ywarn-unused:-locals,-explicits,-privates") case _ => List() }), - managedSourceDirectories in Compile += + Compile / managedSourceDirectories += baseDirectory.value / "src" / "main" / "contraband-scala", - sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", - contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, + Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala", + Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats, // WORKAROUND sbt/sbt#2205 include managed sources in packageSrc - mappings in (Compile, packageSrc) ++= { - val srcs = (managedSources in Compile).value - val sdirs = (managedSourceDirectories in Compile).value + Compile / packageSrc / mappings ++= { + val srcs = (Compile / managedSources).value + val sdirs = (Compile / managedSourceDirectories).value val base = baseDirectory.value (((srcs --- sdirs --- base) pair (relativeTo(sdirs) | relativeTo(base) | flat)) toSeq) }, @@ -259,6 +261,10 @@ lazy val lmCore = (project in file("core")) "sbt.librarymanagement.ResolverFunctions.validateArtifact" ), exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.cross.CrossVersionUtil.TransitionDottyVersion"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.dottyID"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.DottyIDPrefix"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.toolDependencies*"), ), ) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) @@ -275,11 +281,11 @@ lazy val lmIvy = (project in file("ivy")) scalaCheck % Test, scalaVerify % Test, ), - managedSourceDirectories in Compile += + Compile / managedSourceDirectories += baseDirectory.value / "src" / "main" / "contraband-scala", - sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala", - contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats, - scalacOptions in (Compile, console) --= + Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala", + Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats, + Compile / console / scalacOptions --= Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"), mimaSettings, mimaBinaryIssueFilters ++= Seq( diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index b71b74434..4921e09fe 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -32,7 +32,7 @@ object HouseRulesPlugin extends AutoPlugin { scalacOptions += "-Ywarn-value-discard", scalacOptions ++= "-Ywarn-unused-import".ifScala(v => 11 <= v && v <= 12).value.toList ) ++ Seq(Compile, Test).flatMap( - c => scalacOptions in (c, console) --= Seq("-Ywarn-unused-import", "-Xlint") + c => (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") ) private def scalaPartV = Def setting (CrossVersion partialVersion scalaVersion.value) diff --git a/project/build.properties b/project/build.properties index dbae93bcf..f0be67b9f 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.9 +sbt.version=1.5.1 diff --git a/project/plugins.sbt b/project/plugins.sbt index ce812048d..f55cc0ddd 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.6.1") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") From 6f87212b9fb04e943e16b8ec430cfac69e8f2b52 Mon Sep 17 00:00:00 2001 From: Amina Adewusi Date: Fri, 14 May 2021 19:39:37 +0100 Subject: [PATCH 0922/1030] Fixes sbt/sbt#6496 - bug in version parser What is the problem? sbt/sbt#6496 identifies a bug in the logic which assesses whether different versions of the same transitive dependency are binary compatible. If one of the transitive dependencies included a version with a full-stop literal, it would be parsed incorrectly and an error would be thrown to the user falsely saying that the dependencies are binary incompatible. What is the solution? This PR fixes the regex used by the parser to include full-stop literals. Is there anything else to be done? It is worth us checking the rest of the codebase in case this bug might exist in other parsers. The tests are super helpful for figuring out which strings might break the current logic. --- .../main/scala/sbt/librarymanagement/VersionNumber.scala | 2 +- .../scala/sbt/librarymanagement/VersionNumberSpec.scala | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index c8bef483d..90897351d 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -66,7 +66,7 @@ object VersionNumber { def splitDash(s: String) = splitOn(s, '-') def splitPlus(s: String) = splitOn(s, '+') map ("+" + _) - val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+)*)((?:\+.+)*)""".r + val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-[\w\.]+)*)((?:\+.+)*)""".r val NonSpaceString = """(\S+)""".r s match { diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index a8691089e..9f240f432 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -97,6 +97,13 @@ class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { assertCascadesTo(v, Seq("0.1.0-MSERVER-1", "0.1.0", "0.1")) } + version("1.1.0-DLP-7923-presigned-download-url.5") { v => + assertParsesTo(v, Seq(1, 1, 0), Seq("DLP", "7923", "presigned", "download", "url.5"), Seq()) + assertCascadesTo(v, Seq("1.1.0-DLP-7923-presigned-download-url.5", "1.1.0", "1.1")) + assertIsCompatibleWith(v, "1.0.7", EarlySemVer) + assertIsNotCompatibleWith(v, "1.0.7", PackVer) + } + version("2.10.4-20140115-000117-b3a-sources") { v => assertParsesTo(v, Seq(2, 10, 4), Seq("20140115", "000117", "b3a", "sources"), Seq()) assertCascadesTo(v, Seq("2.10.4-20140115-000117-b3a-sources", "2.10.4", "2.10")) From 0ce5142b17175bca120de8f0ec00c3df5537f701 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 May 2021 14:12:46 -0400 Subject: [PATCH 0923/1030] Apply version number parsing fix Ref #377 Apply the dotted-prerelease tag to SemComparator "A pre-release version MAY be denoted by appending a hyphen and a series of dot separated identifiers immediately following the patch version." --- .../SemanticSelectorExtra.scala | 2 +- .../sbt/librarymanagement/VersionNumber.scala | 2 +- .../SemanticSelectorSpec.scala | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index f3f28cf7a..8fafce2a0 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -148,7 +148,7 @@ private[librarymanagement] abstract class SemComparatorFunctions { (?:\.(\d+|[xX*]) (?:\.(\d+|[xX*]))? )? - )((?:-\w+)*)$ + )((?:-\w+(?:\.\w+)*)*)$ """.r protected def parse(comparator: String): SemComparator = { comparator match { diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 90897351d..8ce15c72d 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -66,7 +66,7 @@ object VersionNumber { def splitDash(s: String) = splitOn(s, '-') def splitPlus(s: String) = splitOn(s, '+') map ("+" + _) - val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-[\w\.]+)*)((?:\+.+)*)""".r + val TaggedVersion = """(\d{1,14})([\.\d{1,14}]*)((?:-\w+(?:\.\w+)*)*)((?:\+.+)*)""".r val NonSpaceString = """(\S+)""".r s match { diff --git a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala index 411554260..cce9b4ff1 100644 --- a/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/SemanticSelectorSpec.scala @@ -75,6 +75,7 @@ class SemanticSelectorSpec extends AnyFreeSpec with Matchers { semsel(">=1.2.3") { sel => assertMatches(sel, "1.2.4-beta") + assertMatches(sel, "1.2.4-beta.1") assertMatches(sel, "1.2.3") assertMatches(sel, "1.3") assertMatches(sel, "2") @@ -306,6 +307,21 @@ class SemanticSelectorSpec extends AnyFreeSpec with Matchers { assertNotMatches(sel, "1.2.2") } + semsel(">=1.2.3-beta.5") { sel => + assertMatches(sel, "1.3-alpha") + assertMatches(sel, "1.2.3") + assertMatches(sel, "1.2.3-beta.5") + assertMatches(sel, "1.2.3-beta.6-3") + assertMatches(sel, "1.2.3-beta.7") + assertMatches(sel, "1.2.3-beta.gamma") + assertMatches(sel, "1.2.4") + assertMatches(sel, "1.3") + assertNotMatches(sel, "1.2.3-alpha-3") + assertNotMatches(sel, "1.2.3-beta-1") + assertNotMatches(sel, "1.2.3-beta") + assertNotMatches(sel, "1.2.2") + } + Seq( // invalid operator "~1.2.3", @@ -339,7 +355,6 @@ class SemanticSelectorSpec extends AnyFreeSpec with Matchers { "1.0.0 - 2.0.0 || - 2.0.0", "1.0.0- 2.0.0", "1.0.0 -2.0.0", - "1.0.0-2.0.0", "-", // minor and patch versions are required for pre-release version "1.2-alpha-beta", From ae9f17c8fc6a1d1dc7a4bf602da1246b1ee58e1b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 15 May 2021 14:55:23 -0400 Subject: [PATCH 0924/1030] Permit dot in cross util version parsing Ref #377 --- .../librarymanagement/cross/CrossVersionUtil.scala | 9 +++++---- .../scala/sbt/librarymanagement/CrossVersionExtra.scala | 2 +- .../scala/sbt/librarymanagement/CrossVersionTest.scala | 9 +++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 15e7bb9bb..1bb3d8213 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -22,12 +22,13 @@ object CrossVersionUtil { private val longPattern = """\d{1,19}""" private val basicVersion = raw"""($longPattern)\.($longPattern)\.($longPattern)""" + private val tagPattern = raw"""(?:\w+(?:\.\w+)*)""" private val ReleaseV = raw"""$basicVersion(-\d+)?""".r - private val BinCompatV = raw"""$basicVersion(-\w+)?-bin(-.*)?""".r + private[sbt] val BinCompatV = raw"""$basicVersion(-$tagPattern)?-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r - private val MilestonV = raw"""$basicVersion(-M\d+)""".r - private val NonReleaseV_n = raw"""$basicVersion([-\w]*)""".r // 0-n word suffixes, with leading dashes - private val NonReleaseV_1 = raw"""$basicVersion(-\w+)""".r // 1 word suffix, after a dash + private val MilestonV = raw"""$basicVersion(-M$tagPattern)""".r + private val NonReleaseV_n = raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes + private val NonReleaseV_1 = raw"""$basicVersion(-$tagPattern)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r private[sbt] def isSbtApiCompatible(v: String): Boolean = sbtApiVersion(v).isDefined diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index a37a52d7c..9de8605ea 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -102,7 +102,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { } private[sbt] def patchFun(fullVersion: String): String = { - val BinCompatV = """(\d+)\.(\d+)\.(\d+)(-\w+)??-bin(-.*)?""".r + import sbt.internal.librarymanagement.cross.CrossVersionUtil.BinCompatV fullVersion match { case BinCompatV(x, y, z, w, _) => s"""$x.$y.$z${if (w == null) "" else w}""" case other => other diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 05e849520..454bb5403 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -138,6 +138,9 @@ class CrossVersionTest extends UnitSpec { it should "for 1.3.0-SNAPSHOT return 1.0" in { binarySbtVersion("1.3.0-SNAPSHOT") shouldBe "1.0" } + it should "for 1.3.0-A1-B1.1 return 1.0" in { + binarySbtVersion("1.3.0-A1-B1.1") shouldBe "1.0" + } it should "for 1.10.0 return 1.0" in { binarySbtVersion("1.10.0") shouldBe "1.0" } @@ -216,6 +219,9 @@ class CrossVersionTest extends UnitSpec { it should "for 3.0.0-M3-bin-20201215-cbe50b3-NIGHTLY return 3.0.0-M3" in { binaryScalaVersion("3.0.0-M3-bin-20201215-cbe50b3-NIGHTLY") shouldBe "3.0.0-M3" } + it should "for 3.0.0-M3.5-bin-20201215-cbe50b3-NIGHTLY return 3.0.0-M3" in { + binaryScalaVersion("3.0.0-M3.5-bin-20201215-cbe50b3-NIGHTLY") shouldBe "3.0.0-M3.5" + } it should "for 3.0.0-RC1 return 3.0.0-RC1" in { binaryScalaVersion("3.0.0-RC1") shouldBe "3.0.0-RC1" } @@ -268,6 +274,9 @@ class CrossVersionTest extends UnitSpec { it should "for 2.11.8-RC1-bin-extra return 2.11.8-RC1" in { patchVersion("2.11.8-RC1-bin-extra") shouldBe Some("artefact_2.11.8-RC1") } + it should "for 2.11.8-X1.5-bin-extra return 2.11.8-X1.5" in { + patchVersion("2.11.8-X1.5-bin-extra") shouldBe Some("artefact_2.11.8-X1.5") + } private def constantVersion(value: String) = CrossVersion(CrossVersion.constant(value), "dummy1", "dummy2") map (fn => fn("artefact")) From 0cc4397bf9c3f2dc037bc6a3aeaed97c2dc3fdc5 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Tue, 18 May 2021 10:09:44 +0200 Subject: [PATCH 0925/1030] Use correct Sonatype releases repository --- .../scala/sbt/librarymanagement/ResolverExtra.scala | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index b5ae222b2..8626f7822 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -102,6 +102,8 @@ private[librarymanagement] abstract class ResolverFunctions { @deprecated("Renamed to SbtRepositoryRoot.", "1.0.0") val SbtPluginRepositoryRoot = SbtRepositoryRoot val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + val SonatypeReleasesRepository = + "https://oss.sonatype.org/service/local/repositories/releases/content/" val JavaNet2RepositoryName = "java.net Maven2 Repository" val JavaNet2RepositoryRoot = javanet2RepositoryRoot(useSecureResolvers) val JCenterRepositoryName = "jcenter" @@ -132,7 +134,7 @@ private[librarymanagement] abstract class ResolverFunctions { // obsolete: kept only for launcher compatibility private[sbt] val ScalaToolsReleasesName = "Sonatype OSS Releases" private[sbt] val ScalaToolsSnapshotsName = "Sonatype OSS Snapshots" - private[sbt] val ScalaToolsReleasesRoot = SonatypeRepositoryRoot + "/releases" + private[sbt] val ScalaToolsReleasesRoot = SonatypeReleasesRepository private[sbt] val ScalaToolsSnapshotsRoot = SonatypeRepositoryRoot + "/snapshots" private[sbt] val ScalaToolsReleases = MavenRepository(ScalaToolsReleasesName, ScalaToolsReleasesRoot) @@ -152,7 +154,11 @@ private[librarymanagement] abstract class ResolverFunctions { ivyStylePatterns ) def sonatypeRepo(status: String) = - MavenRepository("sonatype-" + status, SonatypeRepositoryRoot + "/" + status) + MavenRepository( + "sonatype-" + status, + if (status == "releases") SonatypeReleasesRepository + else SonatypeRepositoryRoot + "/" + status + ) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = From 3de165c1ddab8510ee83fc223b93511d2ddd4310 Mon Sep 17 00:00:00 2001 From: Peter Janssen Date: Fri, 28 May 2021 17:12:22 +0200 Subject: [PATCH 0926/1030] Expand allowed maven repository id characters to match maven see https://github.com/apache/maven/blob/5c45b3fe22d8ec4270b2cf1016581b8927d2913d/maven-model-builder/src/main/java/org/apache/maven/model/validation/DefaultModelValidator.java#L84 --- ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 4f172ce94..a1793b20d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -504,7 +504,7 @@ class MakePom(val log: Logger) { s.toArray.map(_.asInstanceOf[DependencyResolver]) def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) - def isValidIDCharacter(c: Char) = c.isLetterOrDigit + def isValidIDCharacter(c: Char) = """\/:"<>|?*""".contains(c) private def checkID(id: String, name: String) = if (id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id def mavenRepository(repo: MavenRepository): XNode = From 93b1d2ff921eb97d80e8707437e11756f761bae8 Mon Sep 17 00:00:00 2001 From: Matthias Kurz Date: Fri, 28 May 2021 17:57:56 +0200 Subject: [PATCH 0927/1030] Scala 2.12.14 / 2.13.6 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 0b0f4b745..8edb305fb 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,8 +3,8 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.13" - val scala213 = "2.13.5" + val scala212 = "2.12.14" + val scala213 = "2.13.6" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") From 976ff440376787e63e48fce7995ea02c83a69ce7 Mon Sep 17 00:00:00 2001 From: Peter Janssen Date: Tue, 1 Jun 2021 11:18:32 +0200 Subject: [PATCH 0928/1030] Fix logic and added test --- .../sbt/internal/librarymanagement/MakePom.scala | 2 +- .../internal/librarymanagement/MakePomSpec.scala | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index a1793b20d..a030a277a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -504,7 +504,7 @@ class MakePom(val log: Logger) { s.toArray.map(_.asInstanceOf[DependencyResolver]) def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) - def isValidIDCharacter(c: Char) = """\/:"<>|?*""".contains(c) + def isValidIDCharacter(c: Char) = !"""\/:"<>|?*""".contains(c) private def checkID(id: String, name: String) = if (id.isEmpty) sys.error("Could not convert '" + name + "' to an ID") else id def mavenRepository(repo: MavenRepository): XNode = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala index 30c36e093..6b3aafd17 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MakePomSpec.scala @@ -1,6 +1,7 @@ package sbt.internal.librarymanagement import sbt.internal.util.ConsoleLogger +import sbt.librarymanagement.MavenRepository import verify.BasicTestSuite // http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html @@ -74,6 +75,18 @@ object MakePomSpec extends BasicTestSuite { beParsedAsError("foo+") } + test("repository id should not contain maven illegal repo id characters") { + val repository = mp.mavenRepository( + MavenRepository( + """repository-id-\with-/illegal:"<-chars>|?*-others~!@#$%^&`';{}[]=+_,.""", + "uri" + ) + ) + assert( + (repository \ "id").text == "repository-id-with-illegal-chars-others~!@#$%^&`';{}[]=+_,." + ) + } + val mp = new MakePom(ConsoleLogger()) def convertTo(s: String, expected: String): Unit = { assert(MakePom.makeDependencyVersion(s) == expected) From 0aa7d69ee68d32a48b21380639614a5c41fad9fd Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 5 Jul 2021 03:40:17 -0400 Subject: [PATCH 0929/1030] Fix cross-Scala suffix conflict warning Fixes https://github.com/sbt/sbt/issues/6578 Problem ------- The regex currently expects two segments like2.x or 3.x, but Scala 3 uses _3 as the cross suffix, and it's not caught. Solution -------- Change the regex. --- .../librarymanagement/ConflictWarning.scala | 2 +- .../ConflictWarningSpec.scala | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/ConflictWarningSpec.scala diff --git a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index 5fea69f37..bed999164 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -59,7 +59,7 @@ object ConflictWarning { private[this] def groupByRawName(ms: Seq[ModuleID]): Map[(String, String), Seq[ModuleID]] = ms.groupBy(m => (m.organization, dropCrossSuffix(m.name))) - private[this] val CrossSuffixPattern = """(.+)_(\d+\.\d+(?:\.\d+)?(?:-.+)?)""".r + private[this] val CrossSuffixPattern = """(.+)_(\d+(?:\.\d+)?(?:\.\d+)?(?:-.+)?)""".r private[this] def dropCrossSuffix(s: String): String = s match { case CrossSuffixPattern(raw, _) => raw case _ => s diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ConflictWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ConflictWarningSpec.scala new file mode 100644 index 000000000..bc3f05ebc --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ConflictWarningSpec.scala @@ -0,0 +1,40 @@ +package sbt.internal.librarymanagement + +import sbt.librarymanagement._ +import sbt.librarymanagement.syntax._ + +object ConflictWarningSpec extends BaseIvySpecification { + + test("it should print out message about the cross-Scala conflict") { + var found = false + val deps = Vector( + `scala2.13.6`, + `cats-effect3.1.1`, + `cats-core2.6.1`.cross(CrossVersion.for3Use2_13), + ) + val m = module(defaultModuleId, deps, Some("3.0.1-RC2")) + val report = ivyUpdate(m) + val w = ConflictWarning.default("foo") + + try { + ConflictWarning(w, report, log) + } catch { + case e: Throwable => + found = true + assert( + e.getMessage.linesIterator.toList.head + .startsWith("Conflicting cross-version suffixes in") + ) + } + if (!found) { + sys.error("conflict warning was expected, but didn't happen sbt/sbt#6578") + } + } + + lazy val `scala2.13.6` = + ModuleID("org.scala-lang", "scala-library", "2.13.6").withConfigurations(Some("compile")) + lazy val `cats-effect3.1.1` = + ("org.typelevel" %% "cats-effect" % "3.1.1").withConfigurations(Some("compile")) + lazy val `cats-core2.6.1` = + ("org.typelevel" %% "cats-core" % "2.6.1").withConfigurations(Some("compile")) +} From 37234e35ba0d597245d8656477f04f9396243b77 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 8 Jul 2021 13:14:16 +0200 Subject: [PATCH 0930/1030] Fix Scala 3 binary version - for 3.0.1-bin-nonbootstrapped it should be 3 - for 3.0.1-SNAPSHOT it should be 3 --- .../librarymanagement/cross/CrossVersionUtil.scala | 11 ++++++----- .../sbt/librarymanagement/CrossVersionTest.scala | 8 +++++++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 1bb3d8213..fe6b107cf 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -76,11 +76,12 @@ object CrossVersionUtil { } private[sbt] def binaryScala3Version(full: String): String = full match { - case ReleaseV(maj, _, _, _) => maj - case CandidateV(maj, min, patch, _) if min.toLong > 0 || patch.toLong > 0 => maj - case MilestonV(maj, min, patch, _) if min.toLong > 0 || patch.toLong > 0 => maj - case BinCompatV(maj, min, patch, stage, _) => binaryScala3Version(s"$maj.$min.$patch$stage") - case _ => full + case ReleaseV(maj, _, _, _) => maj + case NonReleaseV_n(maj, min, patch, _) if min.toLong > 0 || patch.toLong > 0 => maj + case BinCompatV(maj, min, patch, stageOrNull, _) => + val stage = if (stageOrNull != null) stageOrNull else "" + binaryScala3Version(s"$maj.$min.$patch$stage") + case _ => full } def binaryScalaVersion(full: String): String = { diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 454bb5403..d47b17c14 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -250,7 +250,13 @@ class CrossVersionTest extends UnitSpec { binaryScalaVersion("3.0.1-M1") shouldBe "3" } it should "for 3.0.1-RC1-bin-SNAPSHOT return 3" in { - binaryScalaVersion("3.0.1-RC1") shouldBe "3" + binaryScalaVersion("3.0.1-RC1-bin-SNAPSHOT") shouldBe "3" + } + it should "for 3.0.1-bin-nonbootstrapped return 3" in { + binaryScalaVersion("3.0.1-bin-SNAPSHOT") shouldBe "3" + } + it should "for 3.0.1-SNAPSHOT return 3" in { + binaryScalaVersion("3.0.1-SNAPSHOT") shouldBe "3" } private def patchVersion(fullVersion: String) = From f0aa5d312ec891e49827f0e17f5de1b0fb9b87c6 Mon Sep 17 00:00:00 2001 From: Ubaldo Pescatore Date: Thu, 12 Aug 2021 17:21:07 +0200 Subject: [PATCH 0931/1030] typo fixed. --- .../scala/sbt/internal/librarymanagement/ConvertResolver.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index e158c09da..f682a785e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -403,7 +403,7 @@ private[sbt] object ConvertResolver { | publishConfiguration := publishConfiguration.value.withOverwrite(true) | publishLocalConfiguration := publishLocalConfiguration.value.withOverwrite(true) | - |If you have a remote cache respoitory, you can enable overwriting as follows: + |If you have a remote cache repository, you can enable overwriting as follows: | pushRemoteCacheConfiguration := pushRemoteCacheConfiguration.value.withOverwrite(true) |""".stripMargin, ex From 9786906eca956e185edfbb0be23dc35d7065967e Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Fri, 17 Sep 2021 17:36:04 +0100 Subject: [PATCH 0932/1030] Avoid repeating versions in Eviction error message Rather than seeing an error like this, with the evicted version numbers being repeated many times: ``` [error] * org.scala-lang.modules:scala-java8-compat_2.13:1.0.0 (early-semver) is selected over {0.9.0, 0.9.0, 0.9.0, 0.9.0, 0.9.1, 0.9.1, 0.9.1} ``` ...I'd much rather see an error like this: ``` [error] * org.scala-lang.modules:scala-java8-compat_2.13:1.0.0 (early-semver) is selected over {0.9.0, 0.9.1} ``` --- core/src/main/scala/sbt/librarymanagement/EvictionError.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index aaf926dec..94a7f38e5 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -155,7 +155,8 @@ final class EvictionError private[sbt] ( evictions.foreach({ case (a, scheme) => val revs = a.evicteds map { _.module.revision } - val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" + val revsStr = + if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => val rev = r.module.revision From 028724ac23db942f606828ce1c9cb083b97e5f68 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 19 Sep 2021 15:29:08 -0400 Subject: [PATCH 0933/1030] Bump modules --- project/Dependencies.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 8edb305fb..d6eec7cd9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,14 +3,14 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.14" + val scala212 = "2.12.15" val scala213 = "2.13.6" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.5.0") - private val utilVersion = nightlyVersion.getOrElse("1.5.0") + private val ioVersion = nightlyVersion.getOrElse("1.6.0-M1") + private val utilVersion = nightlyVersion.getOrElse("1.6.0-M1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 3ca18987211570e628f7a66d59129a03c7e9ae45 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Wed, 17 Nov 2021 11:54:50 +0900 Subject: [PATCH 0934/1030] fix warning. prepare Scala 3 --- .../scala/sbt/internal/librarymanagement/JsonUtil.scala | 2 +- .../librarymanagement/UpdateClassifiersUtil.scala | 2 +- .../sbt/internal/librarymanagement/VersionRange.scala | 4 ++-- .../main/scala/sbt/librarymanagement/EvictionError.scala | 2 +- .../scala/sbt/librarymanagement/EvictionWarning.scala | 2 +- .../main/scala/sbt/librarymanagement/ModuleIDExtra.scala | 2 +- .../scala/sbt/librarymanagement/UnresolvedWarning.scala | 2 +- .../main/scala/sbt/internal/librarymanagement/Ivy.scala | 8 ++++---- .../scala/sbt/internal/librarymanagement/IvyActions.scala | 2 +- .../scala/sbt/internal/librarymanagement/IvyUtil.scala | 2 +- .../ivyint/CachedResolutionResolveEngine.scala | 6 +++--- .../scala/sbt/librarymanagement/ivy/Credentials.scala | 2 +- .../internal/librarymanagement/BaseIvySpecification.scala | 2 +- .../internal/librarymanagement/ManagedChecksumsSpec.scala | 2 -- 14 files changed, 19 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index 85f5c387f..e7e087537 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -15,7 +15,7 @@ private[sbt] object JsonUtil { log: Logger ): UpdateReport = { try { - val lite = CacheStore(path).read[UpdateReportLite] + val lite = CacheStore(path).read[UpdateReportLite]() fromLite(lite, cachedDescriptor) } catch { case e: Throwable => diff --git a/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala index c01e781af..9f87ff5e8 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/UpdateClassifiersUtil.scala @@ -35,7 +35,7 @@ object UpdateClassifiersUtil { classifiers: Vector[String], exclude: Map[ModuleID, Set[ConfigRef]] )(m: ModuleID): Option[ModuleID] = { - val excluded: Set[ConfigRef] = exclude getOrElse (restrictedCopy(m, false), Set.empty) + val excluded: Set[ConfigRef] = exclude.getOrElse(restrictedCopy(m, false), Set.empty) val exls = excluded map { _.name } val included = classifiers filterNot exls if (included.isEmpty) None diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index eed2eebb0..74c7ff253 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -18,7 +18,7 @@ object VersionRange { // See https://github.com/sbt/sbt/issues/2954 def stripMavenVersionRange(version: String): Option[String] = if (isVersionRange(version)) { - val noSpace = version.replaceAllLiterally(" ", "") + val noSpace = version.replace(" ", "") noSpace match { case MavenVersionSetPattern(open1, x1, comma, x2, close1, _) => // http://maven.apache.org/components/enforcer/enforcer-rules/versionRanges.html @@ -64,7 +64,7 @@ object VersionRange { val start = rev(0) val stop = rev(rev.length - 1) val mid = rev.substring(1, rev.length - 1) - (if (start == ']') "(" else start) + mid + (if (stop == '[') ")" else stop) + (if (start == ']') "(" else start.toString) + mid + (if (stop == '[') ")" else stop) case _ => revision } } catch { diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 94a7f38e5..6d0d0c274 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -130,7 +130,7 @@ object EvictionError { ) } - implicit val evictionErrorLines: ShowLines[EvictionError] = ShowLines { a: EvictionError => + implicit val evictionErrorLines: ShowLines[EvictionError] = ShowLines { (a: EvictionError) => a.toLines } } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index d646303e4..ae6c95638 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -208,7 +208,7 @@ final class EvictionPair private[sbt] ( } object EvictionPair { - implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { a: EvictionPair => + implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { (a: EvictionPair) => val revs = a.evicteds map { _.module.revision } val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index c5191467c..cb68eaf78 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -59,7 +59,7 @@ private[librarymanagement] abstract class ModuleIDExtra { /** String representation of the extra attributes, excluding any information only attributes. */ def extraString: String = - extraDependencyAttributes.map { case (k, v) => k + "=" + v } mkString ("(", ", ", ")") + extraDependencyAttributes.map { case (k, v) => k + "=" + v }.mkString("(", ", ", ")") /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ def extraDependencyAttributes: Map[String, String] = diff --git a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala index 99017ba83..d871caa83 100644 --- a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala @@ -38,7 +38,7 @@ object UnresolvedWarning { } map { case (_, p) => p } - val failedPaths = err.failed map { x: ModuleID => + val failedPaths = err.failed map { (x: ModuleID) => err.failedPaths(x).toList.reverse map { id => (id, modulePosition(id)) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index cc381573e..e45a5fcf4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -433,11 +433,11 @@ final class IvySbt( unionFormat2[IvyConfiguration, InlineIvyConfiguration, ExternalIvyConfiguration] object NullLogger extends sbt.internal.util.BasicLogger { - override def control(event: sbt.util.ControlEvent.Value, message: ⇒ String): Unit = () - override def log(level: Level.Value, message: ⇒ String): Unit = () + override def control(event: sbt.util.ControlEvent.Value, message: => String): Unit = () + override def log(level: Level.Value, message: => String): Unit = () override def logAll(events: Seq[sbt.util.LogEvent]): Unit = () - override def success(message: ⇒ String): Unit = () - override def trace(t: ⇒ Throwable): Unit = () + override def success(message: => String): Unit = () + override def trace(t: => Throwable): Unit = () } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 41f82ab6d..6d223287c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -396,7 +396,7 @@ object IvyActions { val toRetrieve: Option[Vector[ConfigRef]] = config.configurationsToRetrieve val base = getRetrieveDirectory(config.retrieveDirectory) val pattern = getRetrievePattern(config.outputPattern) - val existingFiles = PathFinder(base).allPaths.get filterNot { _.isDirectory } + val existingFiles = PathFinder(base).allPaths.get() filterNot { _.isDirectory } val toCopy = new collection.mutable.HashSet[(File, File)] val retReport = report retrieve { (conf: ConfigRef, mid, art, cached) => toRetrieve match { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala index c3437b595..04b31adab 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyUtil.scala @@ -8,7 +8,7 @@ import scala.util.{ Failure, Success, Try } private[sbt] object IvyUtil { def separate[A, B](l: Seq[Either[A, B]]): (Seq[A], Seq[B]) = - (l.flatMap(_.left.toOption), l.flatMap(_.right.toOption)) + (l.flatMap(_.left.toOption), l.flatMap(_.toOption)) @tailrec final def retryWithBackoff[T]( diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index d9cadfd81..7d94bca6d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -61,7 +61,7 @@ private[sbt] class CachedResolutionResolveCache { val maxConflictCacheSize: Int = 1024 val maxUpdateReportCacheSize: Int = 1024 - def clean(): Unit = updateReportCache.clear + def clean(): Unit = updateReportCache.clear() def directDependencies(md0: ModuleDescriptor): Vector[DependencyDescriptor] = md0.getDependencies.toVector @@ -699,11 +699,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { ) } (if (n > guard) { - warnCircular + warnCircular() result0 } else if (called.isEmpty) result0 else if (notCalled.isEmpty) { - warnCircular + warnCircular() sortModules(cs.tail, acc, extra :+ cs.head, n + 1, guard) } else sortModules(called, acc ++ notCalled, extra, 0, called.size * called.size + 1)) } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index ef2766480..458972409 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -92,7 +92,7 @@ final class DirectCredentials( val dq = '"' val r = if (realm == null) "null" - else dq + realm + dq + else s"$dq$realm$dq" s"""DirectCredentials($r, "$host", "$userName", ****)""" } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index 304412069..f6bcba917 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -102,7 +102,7 @@ trait BaseIvySpecification extends AbstractEngineSpec { } } - def cleanCache: Unit = cleanIvyCache() + def cleanCache(): Unit = cleanIvyCache() def cleanIvyCache(): Unit = IO.delete(currentTarget / "cache") override def cleanCachedResolutionCache(module: ModuleDescriptor): Unit = { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index e9e133d4c..b49c34b75 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -1,7 +1,5 @@ package sbt.internal.librarymanagement -import java.io.File - import org.apache.ivy.util.Message import sbt.librarymanagement._ import sbt.librarymanagement.ivy._ From 129b43acd2eed6b48437519c0369fa5e6296d640 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 20 Nov 2021 19:39:18 -0500 Subject: [PATCH 0935/1030] intern/flyweight ConfigRef Fixes https://github.com/sbt/sbt/issues/6721 Problem ------- ConfigRef is among the most created on heap. Solution -------- intern/flyweight it. --- .../sbt/librarymanagement/ConfigRef.scala | 36 --------- .../librarymanagement/ConfigRefFormats.scala | 27 ------- .../LibraryManagementCodec.scala | 4 +- .../main/contraband/librarymanagement.json | 18 ----- .../sbt/librarymanagement/ConfigRef.scala | 75 +++++++++++++++++++ .../librarymanagement/ConfigRefFormats.scala | 31 ++++++++ project/DatatypeConfig.scala | 4 + 7 files changed, 112 insertions(+), 83 deletions(-) delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala delete mode 100644 core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala create mode 100644 core/src/main/scala/sbt/librarymanagement/ConfigRef.scala create mode 100644 core/src/main/scala/sbt/librarymanagement/ConfigRefFormats.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala deleted file mode 100644 index bc926aaab..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRef.scala +++ /dev/null @@ -1,36 +0,0 @@ -/** - * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -/** - * A reference to Configuration. - * @param name The name of the configuration that eventually get used by Maven. - */ -final class ConfigRef private ( - val name: String) extends Serializable { - - - - override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: ConfigRef => (this.name == x.name) - case _ => false - }) - override def hashCode: Int = { - 37 * (37 * (17 + "sbt.librarymanagement.ConfigRef".##) + name.##) - } - override def toString: String = { - name - } - private[this] def copy(name: String = name): ConfigRef = { - new ConfigRef(name) - } - def withName(name: String): ConfigRef = { - copy(name = name) - } -} -object ConfigRef extends sbt.librarymanagement.ConfigRefFunctions { - - def apply(name: String): ConfigRef = new ConfigRef(name) -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala deleted file mode 100644 index ffbb7f296..000000000 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigRefFormats.scala +++ /dev/null @@ -1,27 +0,0 @@ -/** - * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. - */ - -// DO NOT EDIT MANUALLY -package sbt.librarymanagement -import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigRefFormats { self: sjsonnew.BasicJsonProtocol => -implicit lazy val ConfigRefFormat: JsonFormat[sbt.librarymanagement.ConfigRef] = new JsonFormat[sbt.librarymanagement.ConfigRef] { - override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigRef = { - __jsOpt match { - case Some(__js) => - unbuilder.beginObject(__js) - val name = unbuilder.readField[String]("name") - unbuilder.endObject() - sbt.librarymanagement.ConfigRef(name) - case None => - deserializationError("Expected JsObject but found None") - } - } - override def write[J](obj: sbt.librarymanagement.ConfigRef, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("name", obj.name) - builder.endObject() - } -} -} diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala index fc918b42b..7334fd859 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/LibraryManagementCodec.scala @@ -4,8 +4,8 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement -trait LibraryManagementCodec extends sjsonnew.BasicJsonProtocol - with sbt.librarymanagement.ConfigRefFormats +trait LibraryManagementCodec extends sbt.librarymanagement.ConfigRefFormats + with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 0b9d307fa..59767a820 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -192,24 +192,6 @@ ], "toString": "s\"$caller\"" }, - { - "name": "ConfigRef", - "namespace": "sbt.librarymanagement", - "target": "Scala", - "type": "record", - "doc": [ - "A reference to Configuration." - ], - "fields": [ - { - "name": "name", - "type": "String", - "doc": [ "The name of the configuration that eventually get used by Maven." ] - } - ], - "parentsCompanion": "sbt.librarymanagement.ConfigRefFunctions", - "toString": "name" - }, { "name": "ConfigurationReport", "namespace": "sbt.librarymanagement", diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigRef.scala b/core/src/main/scala/sbt/librarymanagement/ConfigRef.scala new file mode 100644 index 000000000..6143642b6 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/ConfigRef.scala @@ -0,0 +1,75 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.librarymanagement + +import scala.collection.concurrent.TrieMap + +/** + * A reference to Configuration. + * @param name The name of the configuration that eventually get used by Maven. + */ +final class ConfigRef private (val name: String) extends Serializable { + + override def equals(o: Any): Boolean = + this.eq(o.asInstanceOf[AnyRef]) + + override val hashCode: Int = { + 37 * (37 * (17 + "sbt.librarymanagement.ConfigRef".##) + name.##) + } + + override def toString: String = { + name + } + + private[this] def copy(name: String = name): ConfigRef = { + ConfigRef(name) + } + + def withName(name: String): ConfigRef = { + copy(name = name) + } +} + +object ConfigRef extends sbt.librarymanagement.ConfigRefFunctions { + // cache the reference to ConfigRefs + private val cache = new TrieMap[String, ConfigRef] + private lazy val Default = new ConfigRef("default") + private lazy val Compile = new ConfigRef("compile") + private lazy val IntegrationTest = new ConfigRef("it") + private lazy val Provided = new ConfigRef("provided") + private lazy val Runtime = new ConfigRef("runtime") + private lazy val Test = new ConfigRef("test") + private lazy val System = new ConfigRef("system") + private lazy val Optional = new ConfigRef("optional") + private lazy val Pom = new ConfigRef("pom") + private lazy val ScalaTool = new ConfigRef("scala-tool") + private lazy val ScalaDocTool = new ConfigRef("scala-doc-tool") + private lazy val CompilerPlugin = new ConfigRef("plugin") + private lazy val Component = new ConfigRef("component") + private lazy val RuntimeInternal = new ConfigRef("runtime-internal") + private lazy val TestInternal = new ConfigRef("test-internal") + private lazy val IntegrationTestInternal = new ConfigRef("it-internal") + private lazy val CompileInternal = new ConfigRef("compile-internal") + + def apply(name: String): ConfigRef = name match { + case "default" => Default + case "compile" => Compile + case "it" => IntegrationTest + case "provided" => Provided + case "runtime" => Runtime + case "test" => Test + case "system" => System + case "optional" => Optional + case "pom" => Pom + case "scala-tool" => ScalaTool + case "scala-doc-tool" => ScalaDocTool + case "plugin" => CompilerPlugin + case "component" => Component + case "runtime-internal" => RuntimeInternal + case "test-internal" => TestInternal + case "it-internal" => IntegrationTestInternal + case "compile-internal" => CompileInternal + case _ => cache.getOrElseUpdate(name, new ConfigRef(name)) + } +} diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigRefFormats.scala b/core/src/main/scala/sbt/librarymanagement/ConfigRefFormats.scala new file mode 100644 index 000000000..b7d8d0b05 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/ConfigRefFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[https://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ +package sbt.librarymanagement + +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } + +trait ConfigRefFormats { self: sjsonnew.BasicJsonProtocol => + implicit lazy val ConfigRefFormat: JsonFormat[sbt.librarymanagement.ConfigRef] = + new JsonFormat[sbt.librarymanagement.ConfigRef] { + override def read[J]( + __jsOpt: Option[J], + unbuilder: Unbuilder[J] + ): sbt.librarymanagement.ConfigRef = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val name = unbuilder.readField[String]("name") + unbuilder.endObject() + sbt.librarymanagement.ConfigRef(name) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ConfigRef, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("name", obj.name) + builder.endObject() + } + } +} diff --git a/project/DatatypeConfig.scala b/project/DatatypeConfig.scala index dbd1ba8ce..38807b394 100644 --- a/project/DatatypeConfig.scala +++ b/project/DatatypeConfig.scala @@ -54,6 +54,10 @@ object DatatypeConfig { Nil } + case "sbt.librarymanagement.ConfigRef" => { _ => + "sbt.librarymanagement.ConfigRefFormats" :: Nil + } + // TODO: These are handled by BasicJsonProtocol, and sbt-datatype should handle them by default, imo case "Option" | "Set" | "scala.Vector" => { tpe => getFormats(oneArg(tpe)) From caf47ff5cda52f6c6aa9708c34a9319161b796b3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 29 Nov 2021 03:34:25 -0500 Subject: [PATCH 0936/1030] Util 1.6.0-RC1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d6eec7cd9..d179c64da 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.6.0-M1") - private val utilVersion = nightlyVersion.getOrElse("1.6.0-M1") + private val ioVersion = nightlyVersion.getOrElse("1.6.0-M2") + private val utilVersion = nightlyVersion.getOrElse("1.6.0-RC1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From f89ba489066f186777e024a804206d6bfb41567d Mon Sep 17 00:00:00 2001 From: Peter Janssen Date: Wed, 22 Dec 2021 23:08:27 +0100 Subject: [PATCH 0937/1030] Respect maven.repo.local property --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 8626f7822..cb353df1f 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -392,7 +392,8 @@ private[librarymanagement] abstract class ResolverFunctions { System.err.println(s"WARNING: Problem parsing ${f().getAbsolutePath}, ${e.getMessage}"); None } - loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse + sys.props.get("maven.repo.local").map(new File(_)) orElse + loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse new File(sbt.io.Path.userHome, ".m2/repository") } From 31db59c82546c952c3124d362a0469bb8b19b6ab Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Dec 2021 01:08:49 -0500 Subject: [PATCH 0938/1030] IO 1.6.0, Util 1.6.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d179c64da..59367176b 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.6.0-M2") - private val utilVersion = nightlyVersion.getOrElse("1.6.0-RC1") + private val ioVersion = nightlyVersion.getOrElse("1.6.0") + private val utilVersion = nightlyVersion.getOrElse("1.6.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From a561f3a901cbff26cf3fd32ccafbe7bc4978561f Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 16 Jan 2022 21:34:54 +0000 Subject: [PATCH 0939/1030] Add shortcut for s01.oss.sonatype.org to Resolver Fixes https://github.com/sbt/sbt/issues/6787. See also: https://central.sonatype.org/news/20210223_new-users-on-s01/ --- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index cb353df1f..003c6015a 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -102,6 +102,7 @@ private[librarymanagement] abstract class ResolverFunctions { @deprecated("Renamed to SbtRepositoryRoot.", "1.0.0") val SbtPluginRepositoryRoot = SbtRepositoryRoot val SonatypeRepositoryRoot = "https://oss.sonatype.org/content/repositories" + val SonatypeS01RepositoryRoot = "https://s01.oss.sonatype.org/content/repositories" val SonatypeReleasesRepository = "https://oss.sonatype.org/service/local/repositories/releases/content/" val JavaNet2RepositoryName = "java.net Maven2 Repository" @@ -159,6 +160,11 @@ private[librarymanagement] abstract class ResolverFunctions { if (status == "releases") SonatypeReleasesRepository else SonatypeRepositoryRoot + "/" + status ) + def sonatypeS01Repo(status: String) = + MavenRepository( + "sonatype-s01-" + status, + SonatypeS01RepositoryRoot + "/" + status + ) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = From c17309a91438a45491359fb94099b8828b72d246 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sun, 16 Jan 2022 19:56:58 +0000 Subject: [PATCH 0940/1030] Deprecate sonatypeRepo, add sonatypeRepos --- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 003c6015a..4bb59b79c 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -5,6 +5,7 @@ package sbt.librarymanagement import java.io.{ IOException, File } import java.net.{ URI, URL } +import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger @@ -154,17 +155,20 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) + @deprecated("Use sonatypeRepos instead", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, if (status == "releases") SonatypeReleasesRepository else SonatypeRepositoryRoot + "/" + status ) - def sonatypeS01Repo(status: String) = + private def sonatypeS01Repo(status: String) = MavenRepository( "sonatype-s01-" + status, SonatypeS01RepositoryRoot + "/" + status ) + def sonatypeRepos(status: String) = + Vector(sonatypeRepo(status): @nowarn("cat=deprecation"), sonatypeS01Repo(status)) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = From e9ee8a6cab6247574488114871c77db1a0fb7d0f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 29 Jan 2022 23:29:07 -0500 Subject: [PATCH 0941/1030] Scala 3 --- .scalafmt.conf | 11 ++-- build.sbt | 12 ++-- .../sbt/librarymanagement/CallerFormats.scala | 2 +- .../ConfigurationReportFormats.scala | 2 +- .../ConfigurationReportLiteFormats.scala | 2 +- .../FileRepositoryFormats.scala | 2 +- .../GetClassifiersConfigurationFormats.scala | 2 +- .../GetClassifiersModuleFormats.scala | 2 +- .../IvyFileConfigurationFormats.scala | 2 +- ...ModuleDescriptorConfigurationFormats.scala | 2 +- .../librarymanagement/ModuleIDFormats.scala | 2 +- .../ModuleReportFormats.scala | 2 +- .../ModuleSettingsFormats.scala | 2 +- .../OrganizationArtifactReportFormats.scala | 2 +- .../PatternsBasedRepositoryFormats.scala | 2 +- .../PomConfigurationFormats.scala | 2 +- .../librarymanagement/ResolverFormats.scala | 2 +- .../SftpRepositoryFormats.scala | 2 +- .../SshBasedRepositoryFormats.scala | 2 +- .../SshRepositoryFormats.scala | 2 +- .../UpdateConfigurationFormats.scala | 2 +- .../UpdateReportFormats.scala | 2 +- .../UpdateReportLiteFormats.scala | 2 +- .../ConfigurationExtra.scala | 66 +++++++------------ .../librarymanagement/EvictionWarning.scala | 39 +++++------ core/src/test/scala/ConfigMacroSpec.scala | 2 +- .../librarymanagement/VersionNumberSpec.scala | 15 ++--- .../ivy/InlineIvyConfigurationFormats.scala | 2 +- .../ivy/IvyConfigurationFormats.scala | 2 +- .../sbt/internal/librarymanagement/Ivy.scala | 41 ++++++------ .../librarymanagement/IvyRetrieve.scala | 26 +++++--- .../internal/librarymanagement/MakePom.scala | 4 +- .../librarymanagement/ivy/Credentials.scala | 21 +++--- .../ComponentManagerTest.scala | 2 +- .../librarymanagement/CredentialsSpec.scala | 14 +++- .../DMSerializationSpec.scala | 2 +- .../librarymanagement/EvictionErrorSpec.scala | 16 +++-- .../EvictionWarningSpec.scala | 40 ++++++++--- .../InconsistentDuplicateSpec.scala | 12 +++- .../librarymanagement/IvyRepoSpec.scala | 28 ++++---- .../MergeDescriptorSpec.scala | 27 ++++---- .../librarymanagement/ResolutionSpec.scala | 4 +- .../librarymanagement/SftpRepoSpec.scala | 2 +- project/Dependencies.scala | 16 +++-- project/build.properties | 2 +- project/plugins.sbt | 2 +- 46 files changed, 242 insertions(+), 208 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e98e60599..be2e97005 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,11 +1,14 @@ -version = 2.0.0 +version = 3.2.1 +runner.dialect = scala3 + maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] -# http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style. +# https://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style. # scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala -docstrings = JavaDoc +docstrings.style = Asterisk +docstrings.wrap = false # This also seems more idiomatic to include whitespace in import x.{ yyy } spaces.inImportCurlyBraces = true @@ -16,6 +19,6 @@ align.openParenCallSite = false align.openParenDefnSite = false # For better code clarity -danglingParentheses = true +danglingParentheses.preset = true trailingCommas = preserve diff --git a/build.sbt b/build.sbt index 00e45416b..c5f546833 100644 --- a/build.sbt +++ b/build.sbt @@ -40,17 +40,16 @@ ThisBuild / publishTo := { ThisBuild / Test / classLoaderLayeringStrategy := ClassLoaderLayeringStrategy.Flat def commonSettings: Seq[Setting[_]] = Def.settings( - scalaVersion := scala212, + scalaVersion := scala3, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), - resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), compile / javacOptions ++= Seq("-Xlint", "-Xlint:-serial"), - crossScalaVersions := Seq(scala212, scala213), + crossScalaVersions := Seq(scala3), resolvers += Resolver.sonatypeRepo("public"), scalacOptions := { val old = scalacOptions.value @@ -114,14 +113,16 @@ lazy val lmCore = (project in file("core")) .settings( commonSettings, name := "librarymanagement-core", + contrabandSjsonNewVersion := sjsonNewVersion, libraryDependencies ++= Seq( jsch, - scalaReflect.value, - scalaCompiler.value, + // scalaReflect.value, + // scalaCompiler.value, launcherInterface, gigahorseOkhttp, okhttpUrlconnection, sjsonnewScalaJson.value % Optional, + sjsonnew.value % Optional, scalaTest % Test, scalaCheck % Test, scalaVerify % Test, @@ -275,6 +276,7 @@ lazy val lmIvy = (project in file("ivy")) .settings( commonSettings, name := "librarymanagement-ivy", + contrabandSjsonNewVersion := sjsonNewVersion, libraryDependencies ++= Seq( ivy, scalaTest % Test, diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala index 41c97f1be..5b3f57d80 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/CallerFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol => +trait CallerFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats => implicit lazy val CallerFormat: JsonFormat[sbt.librarymanagement.Caller] = new JsonFormat[sbt.librarymanagement.Caller] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.Caller = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index c2017c8be..c8090c6e1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => +trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.OrganizationArtifactReportFormats => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala index 59a27855a..b0181f495 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportLiteFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportLiteFormats { self: sbt.librarymanagement.OrganizationArtifactReportFormats with sjsonnew.BasicJsonProtocol => +trait ConfigurationReportLiteFormats { self: sbt.librarymanagement.OrganizationArtifactReportFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats => implicit lazy val ConfigurationReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] = new JsonFormat[sbt.internal.librarymanagement.ConfigurationReportLite] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.ConfigurationReportLite = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala index 18099155e..da1e0c26f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/FileRepositoryFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait FileRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sjsonnew.BasicJsonProtocol => +trait FileRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileConfigurationFormats => implicit lazy val FileRepositoryFormat: JsonFormat[sbt.librarymanagement.FileRepository] = new JsonFormat[sbt.librarymanagement.FileRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.FileRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala index 19abfb80e..c76d4686a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait GetClassifiersConfigurationFormats { self: sbt.librarymanagement.GetClassifiersModuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.UpdateConfigurationFormats with sjsonnew.BasicJsonProtocol => +trait GetClassifiersConfigurationFormats { self: sbt.librarymanagement.GetClassifiersModuleFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.UpdateConfigurationFormats with sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats with sbt.librarymanagement.ArtifactTypeFilterFormats => implicit lazy val GetClassifiersConfigurationFormat: JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] = new JsonFormat[sbt.librarymanagement.GetClassifiersConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala index e981e5761..bd9475f86 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/GetClassifiersModuleFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait GetClassifiersModuleFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => +trait GetClassifiersModuleFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats => implicit lazy val GetClassifiersModuleFormat: JsonFormat[sbt.librarymanagement.GetClassifiersModule] = new JsonFormat[sbt.librarymanagement.GetClassifiersModule] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.GetClassifiersModule = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala index a78fcc09d..990f2b9c0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/IvyFileConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait IvyFileConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => +trait IvyFileConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val IvyFileConfigurationFormat: JsonFormat[sbt.librarymanagement.IvyFileConfiguration] = new JsonFormat[sbt.librarymanagement.IvyFileConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.IvyFileConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala index 7005fb518..e774c1a5c 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleDescriptorConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleDescriptorConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sjsonnew.BasicJsonProtocol => +trait ModuleDescriptorConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.ScmInfoFormats with sbt.librarymanagement.DeveloperFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConflictManagerFormats => implicit lazy val ModuleDescriptorConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleDescriptorConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleDescriptorConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala index b1c27558d..bb0df05a5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sjsonnew.BasicJsonProtocol => +trait ModuleIDFormats { self: sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats => implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = new JsonFormat[sbt.librarymanagement.ModuleID] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleID = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala index efcc6d76f..43d2a196f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleReportFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.CallerFormats with sjsonnew.BasicJsonProtocol => +trait ModuleReportFormats { self: sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats => implicit lazy val ModuleReportFormat: JsonFormat[sbt.librarymanagement.ModuleReport] = new JsonFormat[sbt.librarymanagement.ModuleReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala index 23b6bea80..f72bc1a96 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleSettingsFormats.scala @@ -6,6 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait ModuleSettingsFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConfigurationFormats with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.ModuleDescriptorConfigurationFormats => +trait ModuleSettingsFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.IvyFileConfigurationFormats with sbt.librarymanagement.PomConfigurationFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.ModuleInfoFormats with sbt.librarymanagement.ScmInfoFormats with sbt.librarymanagement.DeveloperFormats with sbt.internal.librarymanagement.formats.NodeSeqFormat with sbt.librarymanagement.ConflictManagerFormats with sbt.librarymanagement.ModuleDescriptorConfigurationFormats => implicit lazy val ModuleSettingsFormat: JsonFormat[sbt.librarymanagement.ModuleSettings] = flatUnionFormat3[sbt.librarymanagement.ModuleSettings, sbt.librarymanagement.IvyFileConfiguration, sbt.librarymanagement.PomConfiguration, sbt.librarymanagement.ModuleDescriptorConfiguration]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala index 1b2c4810f..2744325a2 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/OrganizationArtifactReportFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait OrganizationArtifactReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sjsonnew.BasicJsonProtocol => +trait OrganizationArtifactReportFormats { self: sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats => implicit lazy val OrganizationArtifactReportFormat: JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] = new JsonFormat[sbt.librarymanagement.OrganizationArtifactReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.OrganizationArtifactReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala index 96e5a93cd..843e70f3d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -6,6 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val PatternsBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.PatternsBasedRepository] = flatUnionFormat4[sbt.librarymanagement.PatternsBasedRepository, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala index 0529fba88..229957379 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PomConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PomConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sjsonnew.BasicJsonProtocol => +trait PomConfigurationFormats { self: sbt.librarymanagement.ScalaModuleInfoFormats with sbt.librarymanagement.ConfigurationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PomConfigurationFormat: JsonFormat[sbt.librarymanagement.PomConfiguration] = new JsonFormat[sbt.librarymanagement.PomConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PomConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala index 67d790a14..5569ef568 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -6,6 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val ResolverFormat: JsonFormat[sbt.librarymanagement.Resolver] = flatUnionFormat7[sbt.librarymanagement.Resolver, sbt.librarymanagement.ChainedResolver, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala index a5fdb55a3..9441ada31 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => +trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala index 7561f480a..8143d7239 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -6,6 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val SshBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.SshBasedRepository] = flatUnionFormat2[sbt.librarymanagement.SshBasedRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala index d9f141b18..861d359b1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.SshConnectionFormats with sjsonnew.BasicJsonProtocol => +trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala index 8114a8576..70f7d3994 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats with sbt.librarymanagement.ArtifactTypeFilterFormats with sjsonnew.BasicJsonProtocol => +trait UpdateConfigurationFormats { self: sbt.librarymanagement.RetrieveConfigurationFormats with sbt.librarymanagement.ConfigRefFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.UpdateLoggingFormats with sbt.internal.librarymanagement.formats.LogicalClockFormats with sbt.librarymanagement.ArtifactTypeFilterFormats => implicit lazy val UpdateConfigurationFormat: JsonFormat[sbt.librarymanagement.UpdateConfiguration] = new JsonFormat[sbt.librarymanagement.UpdateConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala index 2defd540e..41951020d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait UpdateReportFormats { self: sbt.librarymanagement.ConfigurationReportFormats with sbt.librarymanagement.UpdateStatsFormats with sjsonnew.BasicJsonProtocol => +trait UpdateReportFormats { self: sbt.librarymanagement.ConfigurationReportFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sbt.librarymanagement.UpdateStatsFormats => implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateReport] = new JsonFormat[sbt.librarymanagement.UpdateReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.UpdateReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala index 4e9641f9e..f28ed6713 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportLiteFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait UpdateReportLiteFormats { self: sbt.librarymanagement.ConfigurationReportLiteFormats with sjsonnew.BasicJsonProtocol => +trait UpdateReportLiteFormats { self: sbt.librarymanagement.ConfigurationReportLiteFormats with sbt.librarymanagement.OrganizationArtifactReportFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats => implicit lazy val UpdateReportLiteFormat: JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] = new JsonFormat[sbt.internal.librarymanagement.UpdateReportLite] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.librarymanagement.UpdateReportLite = { __jsOpt match { diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 7431e8950..4acc996bb 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -4,10 +4,12 @@ package sbt.librarymanagement import scala.annotation.tailrec -import scala.language.experimental.macros +import scala.quoted.* object Configurations { - def config(name: String): Configuration = macro ConfigurationMacro.configMacroImpl + inline def config(name: String): Configuration = ${ + ConfigurationMacro.configMacroImpl('{ name }) + } def default: Vector[Configuration] = defaultMavenConfigurations def defaultMavenConfigurations: Vector[Configuration] = Vector(Compile, Runtime, Test, Provided, Optional) @@ -104,50 +106,26 @@ private[librarymanagement] abstract class ConfigurationExtra { def hide = Configuration.of(id, name, description, false, extendsConfigs, transitive) } -private[sbt] object ConfigurationMacro { - import scala.reflect.macros._ +private[sbt] object ConfigurationMacro: + def configMacroImpl(name: Expr[String])(using Quotes): Expr[Configuration] = { + import quotes.reflect.* + def enclosingTerm(sym: Symbol): Symbol = + sym match + case sym if sym.flags is Flags.Macro => enclosingTerm(sym.owner) + case sym if !sym.isTerm => enclosingTerm(sym.owner) + case _ => sym + val term = enclosingTerm(Symbol.spliceOwner) + if !term.isValDef then + report.error( + """config must be directly assigned to a val, such as `val Tooling = config("tooling")`.""" + ) - def configMacroImpl(c: blackbox.Context)(name: c.Expr[String]): c.Expr[Configuration] = { - import c.universe._ - val enclosingValName = definingValName( - c, - methodName => - s"""$methodName must be directly assigned to a val, such as `val Tooling = $methodName("tooling")`.""" - ) - if (enclosingValName.head.isLower) { - c.error(c.enclosingPosition, "configuration id must be capitalized") - } - val id = c.Expr[String](Literal(Constant(enclosingValName))) - reify { Configuration.of(id.splice, name.splice) } + val enclosingValName = term.name + if enclosingValName.head.isLower then report.error("configuration id must be capitalized") + val id = Expr(enclosingValName) + '{ Configuration.of($id, $name) } } - - def definingValName(c: blackbox.Context, invalidEnclosingTree: String => String): String = { - import c.universe.{ Apply => ApplyTree, _ } - val methodName = c.macroApplication.symbol.name - def processName(n: Name): String = - n.decodedName.toString.trim // trim is not strictly correct, but macros don't expose the API necessary - @tailrec def enclosingVal(trees: List[c.Tree]): String = { - trees match { - case ValDef(_, name, _, _) :: _ => processName(name) - case (_: ApplyTree | _: Select | _: TypeApply) :: xs => enclosingVal(xs) - // lazy val x: X = has this form for some reason (only when the explicit type is present, though) - case Block(_, _) :: DefDef(mods, name, _, _, _, _) :: _ if mods.hasFlag(Flag.LAZY) => - processName(name) - case _ => - c.error(c.enclosingPosition, invalidEnclosingTree(methodName.decodedName.toString)) - "" - } - } - enclosingVal(enclosingTrees(c).toList) - } - - def enclosingTrees(c: blackbox.Context): Seq[c.Tree] = - c.asInstanceOf[reflect.macros.runtime.Context] - .callsiteTyper - .context - .enclosingContextChain - .map(_.tree.asInstanceOf[c.Tree]) -} +end ConfigurationMacro private[librarymanagement] abstract class ConfigRefFunctions { implicit def configToConfigRef(c: Configuration): ConfigRef = diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index ae6c95638..25cae9c61 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -392,28 +392,29 @@ object EvictionWarning { ) } - implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { a: EvictionWarning => - import ShowLines._ - val out: mutable.ListBuffer[String] = mutable.ListBuffer() - if (a.options.warnEvictionSummary && a.binaryIncompatibleEvictionExists) { - out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - } + implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { + (a: EvictionWarning) => + import ShowLines._ + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + if (a.options.warnEvictionSummary && a.binaryIncompatibleEvictionExists) { + out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + } - if (a.scalaEvictions.nonEmpty) { - out += "Scala version was updated by one of library dependencies:" - out ++= (a.scalaEvictions flatMap { _.lines }) - out += "To force scalaVersion, add the following:" - out += "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - } + if (a.scalaEvictions.nonEmpty) { + out += "Scala version was updated by one of library dependencies:" + out ++= (a.scalaEvictions flatMap { _.lines }) + out += "To force scalaVersion, add the following:" + out += "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + } - if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { - out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" - out += "" - out ++= (a.directEvictions flatMap { _.lines }) - out ++= (a.transitiveEvictions flatMap { _.lines }) - } + if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { + out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" + out += "" + out ++= (a.directEvictions flatMap { _.lines }) + out ++= (a.transitiveEvictions flatMap { _.lines }) + } - out.toList + out.toList } private[sbt] def infoAllTheThings(a: EvictionWarning): List[String] = diff --git a/core/src/test/scala/ConfigMacroSpec.scala b/core/src/test/scala/ConfigMacroSpec.scala index c35ab104b..ea409efa7 100644 --- a/core/src/test/scala/ConfigMacroSpec.scala +++ b/core/src/test/scala/ConfigMacroSpec.scala @@ -56,6 +56,6 @@ object ConfigMacroSpec extends Properties("ConfigMacroSpec") { s"Actual isPublic: ${c.isPublic}" |: (c.id == id) && (c.name == name) && - (c.isPublic == isPublic) + (c.isPublic == isPublic) } } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 9f240f432..608be5f03 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -133,7 +133,7 @@ class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { assertParsesToError(v) } - //// + // // private[this] final class VersionString(val value: String) @@ -148,13 +148,12 @@ class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { ts: Seq[String], es: Seq[String] ): Unit = - s"should parse to ($ns, $ts, $es)" in inside(v.value) { - case VersionNumber(ns1, ts1, es1) => - (ns1 shouldBe ns) - (ts1 shouldBe ts) - (es1 shouldBe es) - (VersionNumber(ns, ts, es).toString shouldBe v.value) - (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) + s"should parse to ($ns, $ts, $es)" in inside(v.value) { case VersionNumber(ns1, ts1, es1) => + (ns1 shouldBe ns) + (ts1 shouldBe ts) + (es1 shouldBe es) + (VersionNumber(ns, ts, es).toString shouldBe v.value) + (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) } private[this] def assertParsesToError(v: VersionString): Unit = diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala index 4fa266e4d..b73006cd3 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala @@ -5,7 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol => +trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats => implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { __jsOpt match { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala index ee0807427..c281e7d05 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala @@ -6,6 +6,6 @@ package sbt.librarymanagement.ivy import _root_.sjsonnew.JsonFormat -trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ivy.InlineIvyConfigurationFormats with sbt.librarymanagement.ivy.ExternalIvyConfigurationFormats => +trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sbt.librarymanagement.ivy.InlineIvyConfigurationFormats with sbt.librarymanagement.ivy.ExternalIvyConfigurationFormats => implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.IvyConfiguration] = flatUnionFormat2[sbt.librarymanagement.ivy.IvyConfiguration, sbt.librarymanagement.ivy.InlineIvyConfiguration, sbt.librarymanagement.ivy.ExternalIvyConfiguration]("type") } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e45a5fcf4..78b31d531 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -141,7 +141,8 @@ final class IvySbt( is } - /** Defines a parallel [[CachedResolutionResolveEngine]]. + /** + * Defines a parallel [[CachedResolutionResolveEngine]]. * * This is defined here because it needs access to [[mkIvy]]. */ @@ -160,8 +161,10 @@ final class IvySbt( } } - /** Provides a default ivy implementation that decides which resolution - * engine to use depending on the passed ivy configuration options. */ + /** + * Provides a default ivy implementation that decides which resolution + * engine to use depending on the passed ivy configuration options. + */ private class IvyImplementation extends Ivy { private val loggerEngine = new SbtMessageLoggerEngine override def getLoggerEngine: SbtMessageLoggerEngine = loggerEngine @@ -201,7 +204,7 @@ final class IvySbt( // ========== End Configuration/Setup ============ - /** Uses the configured Ivy instance within a safe context.*/ + /** Uses the configured Ivy instance within a safe context. */ def withIvy[T](log: Logger)(f: Ivy => T): T = withIvy(new IvyLoggerInterface(log))(f) @@ -292,7 +295,7 @@ final class IvySbt( IvySbt.wrapped(module, ivyXML), moduleID, defaultConf.name, - validate + ic.validate ) IvySbt.addMainArtifact(moduleID) IvySbt.addOverrides(moduleID, overrides, ivy.getSettings.getMatcher(PatternMatcher.EXACT)) @@ -320,7 +323,7 @@ final class IvySbt( mod } - /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ + /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`. */ private def configurePom(pc: PomConfiguration) = { val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) @@ -334,7 +337,7 @@ final class IvySbt( (dmd, defaultConf) } - /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`. */ private def configureIvyFile(ifc: IvyFileConfiguration) = { val parser = new CustomXmlParser.CustomParser(settings, None) parser.setValidate(ifc.validate) @@ -517,8 +520,7 @@ private[sbt] object IvySbt { val ivyResolvers = resolvers.map(r => ConvertResolver(r, settings, updateOptions, log)) val (projectResolvers, rest) = ivyResolvers.partition(_.getName == ProjectResolver.InterProject) - if (projectResolvers.isEmpty) - ivyint.SbtChainResolver(name, rest, settings, updateOptions, log) + if (projectResolvers.isEmpty) ivyint.SbtChainResolver(name, rest, settings, updateOptions, log) else { // Force that we always look at the project resolver first by wrapping the chain resolver val delegatedName = s"$name-delegate" @@ -591,8 +593,7 @@ private[sbt] object IvySbt { private[sbt] def resetArtifactResolver( resolved: ResolvedModuleRevision ): ResolvedModuleRevision = - if (resolved eq null) - null + if (resolved eq null) null else { val desc = resolved.getDescriptor val updatedDescriptor = CustomPomParser.defaultTransform(desc.getParser, desc) @@ -690,7 +691,7 @@ private[sbt] object IvySbt { moduleID.addConflictManager(mid, matcher, manager) } - /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ + /** Converts the given sbt module id into an Ivy ModuleRevisionId. */ def toID(m: ModuleID) = { import m._ ModuleRevisionId.newInstance( @@ -758,7 +759,8 @@ private[sbt] object IvySbt { } private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { import scala.collection.JavaConverters._ - val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m + val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } + else m if (map.isEmpty) null else map.asJava } @@ -789,15 +791,14 @@ private[sbt] object IvySbt { elem: scala.xml.Elem, extra: Map[String, String] ): scala.xml.Elem = - extra.foldLeft(elem) { - case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) + extra.foldLeft(elem) { case (e, (key, value)) => + e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { val info = {x} \ "info" if (info.nonEmpty) { def check(found: NodeSeq, expected: String, label: String) = - if (found.isEmpty) - sys.error("Missing " + label + " in inline Ivy XML.") + if (found.isEmpty) sys.error("Missing " + label + " in inline Ivy XML.") else { val str = found.text if (str != expected) @@ -918,7 +919,7 @@ private[sbt] object IvySbt { } } - /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor. */ def convertDependency( moduleID: DefaultModuleDescriptor, dependency: ModuleID, @@ -936,7 +937,9 @@ private[sbt] object IvySbt { dependency.configurations match { case None => // The configuration for this dependency was not explicitly specified, so use the default parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + case Some( + confs + ) => // The configuration mapping (looks like: test->default) was specified for this dependency parser.parseDepsConfs(confs, dependencyDescriptor) } for (artifact <- dependency.explicitArtifacts) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index a6d2604ce..a1784ffd0 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -54,14 +54,18 @@ object IvyRetrieve { private[sbt] def organizationArtifactReports( confReport: ConfigurationResolveReport ): Vector[OrganizationArtifactReport] = { - val moduleIds = confReport.getModuleIds.toArray.toVector collect { - case mId: IvyModuleId => mId + val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => + mId } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } - OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { - moduleRevisionDetail(confReport, _) - }) + OrganizationArtifactReport( + mid.getOrganisation, + mid.getName, + deps map { + moduleRevisionDetail(confReport, _) + } + ) } moduleIds map { organizationArtifact } } @@ -141,9 +145,13 @@ object IvyRetrieve { val edOpt = Option(dep.getEvictedData(confReport.getConfiguration)) edOpt match { case Some(ed) => - (true, nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { - "transitive" - }), nonEmptyString(ed.getDetail)) + ( + true, + nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { + "transitive" + }), + nonEmptyString(ed.getDetail) + ) case None => (true, None, None) } case _ => (false, None, None) @@ -218,7 +226,7 @@ object IvyRetrieve { getType, getExt, Option(getExtraAttribute("classifier")), - getConfigurations.toVector map { c: String => + getConfigurations.toVector map { (c: String) => ConfigRef(c) }, Option(getUrl) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index a030a277a..8e90b4eb1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -202,7 +202,7 @@ class MakePom(val log: Logger) { if (moduleInfo.developers.nonEmpty) { { - moduleInfo.developers.map { developer: Developer => + moduleInfo.developers.map { (developer: Developer) => {developer.id} {developer.name} @@ -431,7 +431,7 @@ class MakePom(val log: Logger) { def getScopeAndOptional(confs: Array[String]): (Option[String], Boolean) = { val (opt, notOptional) = confs.partition(_ == Optional.name) val defaultNotOptional = - Configurations.defaultMavenConfigurations.find({ c: Configuration => + Configurations.defaultMavenConfigurations.find({ (c: Configuration) => notOptional contains c.name }) val scope = defaultNotOptional.map(_.name) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 458972409..656247304 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -16,11 +16,11 @@ object Credentials { def apply(file: File): Credentials = new FileCredentials(file) - /** Add the provided credentials to Ivy's credentials cache.*/ + /** Add the provided credentials to Ivy's credentials cache. */ def add(realm: String, host: String, userName: String, passwd: String): Unit = CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) - /** Load credentials from the given file into Ivy's credentials cache.*/ + /** Load credentials from the given file into Ivy's credentials cache. */ def add(path: File, log: Logger): Unit = loadCredentials(path) match { case Left(err) => log.warn(err) @@ -41,23 +41,20 @@ object Credentials { def loadCredentials(path: File): Either[String, DirectCredentials] = if (path.exists) { val properties = read(path) - def get(keys: List[String]) = + def get(keys: List[String]): Either[String, String] = keys .flatMap(properties.get) .headOption .toRight(keys.head + " not specified in credentials file: " + path) - IvyUtil.separate(List(HostKeys, UserKeys, PasswordKeys).map(get)) match { - case (Nil, List(host, user, pass)) => - IvyUtil.separate(List(RealmKeys).map(get)) match { - case (_, List(realm)) => Right(new DirectCredentials(realm, host, user, pass)) - case _ => Right(new DirectCredentials(null, host, user, pass)) - } + IvyUtil.separate(List(HostKeys, UserKeys, PasswordKeys).map(get)) match + case (Nil, List(host: String, user: String, pass: String)) => + IvyUtil.separate(List(RealmKeys).map(get)) match + case (_, List(realm: String)) => Right(new DirectCredentials(realm, host, user, pass)) + case _ => Right(new DirectCredentials(null, host, user, pass)) case (errors, _) => Left(errors.mkString("\n")) - } - } else - Left("Credentials file " + path + " does not exist") + } else Left("Credentials file " + path + " does not exist") def register(cs: Seq[Credentials], log: Logger): Unit = cs foreach { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index dc2947e26..15a68f70e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -121,7 +121,7 @@ object ComponentManagerTest extends BasicTestSuite { TestLogger { logger => withTemporaryDirectory { temp => // The actual classes we'll use at runtime. - //val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + // val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) // A stub component manager object provider extends ComponentProvider { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala index e546f9758..13189de5b 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -28,12 +28,22 @@ class CredentialsSpec extends AnyFunSuite { test("DirectCredentials.toString") { assert( - Credentials(realm = null, host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = null, + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials(null, "example.org", "username", ****)""" ) assert( - Credentials(realm = "realm", host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = "realm", + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials("realm", "example.org", "username", ****)""" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 86cf43322..b7cb02ce4 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -101,7 +101,7 @@ object DMSerializationSpec extends BasicTestSuite { def roundtripBuilder[A: JsonReader: JsonWriter](a: A)(f: (A, A) => Unit): Unit = { val json = isoString to (Converter toJsonUnsafe a) println(json) - val obj = Converter fromJsonUnsafe [A] (isoString from json) + val obj = Converter.fromJsonUnsafe[A](isoString from json) f(a, obj) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index a6b97c99e..5e67681ea 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -101,17 +101,25 @@ object EvictionErrorSpec extends BaseIvySpecification { def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") lazy val `akkaActor2.1.4` = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `akkaActor2.3.0` = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `scala2.10.4` = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) lazy val `scala2.13.3` = ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) lazy val `bananaSesame0.4` = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 lazy val `akkaRemote2.3.4` = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 lazy val `http4s0.21.11` = ("org.http4s" %% "http4s-blaze-server" % "0.21.11").withConfigurations(Some("compile")) // https://repo1.maven.org/maven2/org/typelevel/cats-effect_2.13/3.0.0-M4/cats-effect_2.13-3.0.0-M4.pom diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 09975ba5f..4f8ded23f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -20,7 +20,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -79,7 +83,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -302,11 +310,17 @@ object EvictionWarningSpec extends BaseIvySpecification { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor234 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) def scala2103 = @@ -317,13 +331,21 @@ object EvictionWarningSpec extends BaseIvySpecification { def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile")) def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile")) def bnfparser10 = - ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 + ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations( + Some("compile") + ) // uses commons-io 2.4 def unfilteredUploads080 = - ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses commons-io 1.4 def bananaSesame04 = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 def akkaRemote234 = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 def fullOptions = EvictionWarningOptions.full def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala index db9344070..46e830c04 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala @@ -24,9 +24,15 @@ object InconsistentDuplicateSpec extends BasicTestSuite { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230Test = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("test") + ) cross CrossVersion.binary } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 97515d9ef..c3235b934 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -17,7 +17,7 @@ object IvyRepoSpec extends BaseIvySpecification { module( ourModuleID, Vector(dep), - None //, UpdateOptions().withCachedResolution(true) + None // , UpdateOptions().withCachedResolution(true) ) } @@ -31,13 +31,11 @@ object IvyRepoSpec extends BaseIvySpecification { val report = ivyUpdate(m) import Inside._ - inside(report.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.`type` == "jar") - assert(ar.extension == "jar") - } + inside(report.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.`type` == "jar") + assert(ar.extension == "jar") + } } } @@ -90,14 +88,12 @@ object IvyRepoSpec extends BaseIvySpecification { .get import Inside._ - inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.name == "libmodule-source") - assert(ar.`type` == "src") - assert(ar.extension == "jar") - } + inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.name == "libmodule-source") + assert(ar.`type` == "src") + assert(ar.extension == "jar") + } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala index 898402224..780613096 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala @@ -14,20 +14,19 @@ object MergeDescriptorSpec extends BaseIvySpecification { None, UpdateOptions() ) - m.withModule(log) { - case (_, md, _) => - val deps = md.getDependencies - assert(deps.size == 1) - deps.headOption.getOrElse(sys.error("Dependencies not found")) match { - case dd @ MergedDescriptors(_, _) => - val arts = dd.getAllDependencyArtifacts - val a0: DependencyArtifactDescriptor = arts.toList(0) - val a1: DependencyArtifactDescriptor = arts.toList(1) - val configs0 = a0.getConfigurations.toList - val configs1 = a1.getConfigurations.toList - assert(configs0 == List("compile")) - assert(configs1 == List("test")) - } + m.withModule(log) { case (_, md, _) => + val deps = md.getDependencies + assert(deps.size == 1) + deps.headOption.getOrElse(sys.error("Dependencies not found")) match { + case dd @ MergedDescriptors(_, _) => + val arts = dd.getAllDependencyArtifacts + val a0: DependencyArtifactDescriptor = arts.toList(0) + val a1: DependencyArtifactDescriptor = arts.toList(1) + val configs0 = a0.getConfigurations.toList + val configs1 = a1.getConfigurations.toList + assert(configs0 == List("compile")) + assert(configs1 == List("test")) + } } } def guavaTest = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala index 818da8155..6b8fc49bc 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala @@ -70,10 +70,10 @@ abstract class ResolutionSpec extends AbstractEngineSpec { // second resolution reads from the minigraph val report = update(m) val modules: Seq[String] = report.configurations.head.modules map { _.toString } - assert(modules exists { x: String => + assert(modules exists { (x: String) => x contains """org.jboss.netty:netty:3.2.0.Final""" }) - assert(!(modules exists { x: String => + assert(!(modules exists { (x: String) => x contains """org.jboss.netty:netty:3.2.1.Final""" })) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala index 2bf13668d..c131e2900 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -13,7 +13,7 @@ import java.nio.file.Paths object SftpRepoSpec extends BaseIvySpecification { val repo: Option[String] = None // val repo: Option[String] = Some("some repo") - //a dependency which depends on another in the repo + // a dependency which depends on another in the repo def org(repo: String) = s"com.${repo}" def module(org: String) = org % "some-lib" % "version" diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 59367176b..48df24769 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,12 +5,13 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.15" val scala213 = "2.13.6" + val scala3 = "3.1.0" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.6.0") - private val utilVersion = nightlyVersion.getOrElse("1.6.0") + private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -51,16 +52,17 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" - val scalaTest = "org.scalatest" %% "scalatest" % "3.2.0" + val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.0.1" + val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" - val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" + val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" + val sjsonNewVersion = "0.10.0" val sjsonnew = Def.setting { - "com.eed3si9n" %% "sjson-new-core" % contrabandSjsonNewVersion.value + "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } val sjsonnewScalaJson = Def.setting { - "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value + "com.eed3si9n" %% "sjson-new-scalajson" % sjsonNewVersion } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" + val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.6.0" val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" } diff --git a/project/build.properties b/project/build.properties index f0be67b9f..3161d2146 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.5.1 +sbt.version=1.6.1 diff --git a/project/plugins.sbt b/project/plugins.sbt index f55cc0ddd..ff65f715d 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -2,7 +2,7 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") -addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") +addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.3") addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From a4ce8db55b403446025b7a3519f8e035760b23e3 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 30 Jan 2022 02:19:11 -0500 Subject: [PATCH 0942/1030] Manually edit Contraband-generated code --- .../ChainedResolverFormats.scala | 15 +++++++- .../ConfigurationReportFormats.scala | 18 +++++++++- .../ModuleConfigurationFormats.scala | 16 ++++++++- .../PatternsBasedRepositoryFormats.scala | 12 ++++++- .../PublishConfigurationFormats.scala | 8 ++++- .../librarymanagement/ResolverFormats.scala | 15 +++++++- .../SftpRepositoryFormats.scala | 7 +++- .../SshBasedRepositoryFormats.scala | 9 ++++- .../SshConnectionFormats.scala | 5 ++- .../SshRepositoryFormats.scala | 7 +++- .../ivy/ExternalIvyConfigurationFormats.scala | 32 ++++++++++++++++- .../ivy/InlineIvyConfigurationFormats.scala | 34 +++++++++++++++++- .../ivy/IvyConfigurationFormats.scala | 36 ++++++++++++++++++- .../ivy/formats/UpdateOptionsFormat.scala | 30 +++++++++++++++- 14 files changed, 230 insertions(+), 14 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala index 61cf796da..25792d684 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala @@ -5,7 +5,20 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.MavenRepoFormats with + sbt.librarymanagement.MavenCacheFormats with + sbt.librarymanagement.PatternsFormats with + sbt.librarymanagement.FileConfigurationFormats with + sbt.librarymanagement.FileRepositoryFormats with + sbt.librarymanagement.URLRepositoryFormats with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.SshRepositoryFormats with + sbt.librarymanagement.SftpRepositoryFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val ChainedResolverFormat: JsonFormat[sbt.librarymanagement.ChainedResolver] = new JsonFormat[sbt.librarymanagement.ChainedResolver] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index c8090c6e1..282877526 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -5,7 +5,23 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.OrganizationArtifactReportFormats => +trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with + sbt.librarymanagement.ModuleReportFormats with + sbt.librarymanagement.ModuleIDFormats with + sbt.librarymanagement.ArtifactFormats with + sbt.librarymanagement.ChecksumFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.InclExclRuleFormats with + sbt.librarymanagement.CrossVersionFormats with + sbt.librarymanagement.DisabledFormats with + sbt.librarymanagement.BinaryFormats with + sbt.librarymanagement.ConstantFormats with + sbt.librarymanagement.PatchFormats with + sbt.librarymanagement.FullFormats with + sbt.librarymanagement.For3Use2_13Formats with + sbt.librarymanagement.For2_13Use3Formats with + sbt.librarymanagement.CallerFormats with + sbt.librarymanagement.OrganizationArtifactReportFormats => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala index 1f34ab28f..f562f1bb4 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala @@ -5,7 +5,21 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.ChainedResolverFormats with + sbt.librarymanagement.MavenRepoFormats with + sbt.librarymanagement.MavenCacheFormats with + sbt.librarymanagement.PatternsFormats with + sbt.librarymanagement.FileConfigurationFormats with + sbt.librarymanagement.FileRepositoryFormats with + sbt.librarymanagement.URLRepositoryFormats with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.SshRepositoryFormats with + sbt.librarymanagement.SftpRepositoryFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val ModuleConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala index 843e70f3d..f49f0f9c6 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -6,6 +6,16 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.FileConfigurationFormats with + sbt.librarymanagement.FileRepositoryFormats with + sbt.librarymanagement.URLRepositoryFormats with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.SshRepositoryFormats with + sbt.librarymanagement.SftpRepositoryFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val PatternsBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.PatternsBasedRepository] = flatUnionFormat4[sbt.librarymanagement.PatternsBasedRepository, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala index d1fde3d18..8b2842ad8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala @@ -5,7 +5,13 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.UpdateLoggingFormats with sjsonnew.BasicJsonProtocol => +trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with + sbt.librarymanagement.ArtifactFormats with + sbt.librarymanagement.UpdateLoggingFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats with + sbt.librarymanagement.ChecksumFormats => implicit lazy val PublishConfigurationFormat: JsonFormat[sbt.librarymanagement.PublishConfiguration] = new JsonFormat[sbt.librarymanagement.PublishConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala index 5569ef568..3f0a73150 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -6,6 +6,19 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.ChainedResolverFormats with + sbt.librarymanagement.MavenRepoFormats with + sbt.librarymanagement.MavenCacheFormats with + sbt.librarymanagement.PatternsFormats with + sbt.librarymanagement.FileConfigurationFormats with + sbt.librarymanagement.FileRepositoryFormats with + sbt.librarymanagement.URLRepositoryFormats with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.SshRepositoryFormats with + sbt.librarymanagement.SftpRepositoryFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val ResolverFormat: JsonFormat[sbt.librarymanagement.Resolver] = flatUnionFormat7[sbt.librarymanagement.Resolver, sbt.librarymanagement.ChainedResolver, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala index 9441ada31..2a2f49073 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -5,7 +5,12 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => +trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala index 8143d7239..b16f32821 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -6,6 +6,13 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => +trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.SshRepositoryFormats with + sbt.librarymanagement.SftpRepositoryFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val SshBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.SshBasedRepository] = flatUnionFormat2[sbt.librarymanagement.SshBasedRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala index 9daea2940..db4ea41e5 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala @@ -5,7 +5,10 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with sjsonnew.BasicJsonProtocol => +trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val SshConnectionFormat: JsonFormat[sbt.librarymanagement.SshConnection] = new JsonFormat[sbt.librarymanagement.SshConnection] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala index 861d359b1..2b3c4893b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -5,7 +5,12 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => +trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with + sjsonnew.BasicJsonProtocol with + sbt.librarymanagement.SshConnectionFormats with + sbt.librarymanagement.SshAuthenticationFormats with + sbt.librarymanagement.PasswordAuthenticationFormats with + sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { __jsOpt match { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala index e9384ca63..49c66fc7b 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala @@ -5,7 +5,37 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => +trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat + with sbt.librarymanagement.ModuleIDFormats + with sbt.librarymanagement.ResolverFormats + with sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.ConfigRefFormats + with sbt.librarymanagement.ChecksumFormats + with sbt.librarymanagement.InclExclRuleFormats + with sbt.librarymanagement.CrossVersionFormats + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats + with sbt.librarymanagement.ChainedResolverFormats + with sbt.librarymanagement.MavenRepoFormats + with sbt.librarymanagement.MavenCacheFormats + with sbt.librarymanagement.PatternsFormats + with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.FileRepositoryFormats + with sbt.librarymanagement.URLRepositoryFormats + with sbt.librarymanagement.SshConnectionFormats + with sbt.librarymanagement.SshAuthenticationFormats + with sbt.librarymanagement.SshRepositoryFormats + with sbt.librarymanagement.SftpRepositoryFormats + with sbt.librarymanagement.PasswordAuthenticationFormats + with sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { __jsOpt match { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala index b73006cd3..28fbd616f 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala @@ -5,7 +5,39 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement.ivy import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats => +trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat + with sbt.librarymanagement.ivy.IvyPathsFormats + with sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.ModuleIDFormats + with sbt.librarymanagement.ResolverFormats + with sbt.librarymanagement.ModuleConfigurationFormats + with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.ConfigRefFormats + with sbt.librarymanagement.ChecksumFormats + with sbt.librarymanagement.InclExclRuleFormats + with sbt.librarymanagement.CrossVersionFormats + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats + with sbt.librarymanagement.ChainedResolverFormats + with sbt.librarymanagement.MavenRepoFormats + with sbt.librarymanagement.MavenCacheFormats + with sbt.librarymanagement.PatternsFormats + with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.FileRepositoryFormats + with sbt.librarymanagement.URLRepositoryFormats + with sbt.librarymanagement.SshConnectionFormats + with sbt.librarymanagement.SshAuthenticationFormats + with sbt.librarymanagement.SshRepositoryFormats + with sbt.librarymanagement.SftpRepositoryFormats + with sbt.librarymanagement.PasswordAuthenticationFormats + with sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { __jsOpt match { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala index c281e7d05..cbab06322 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala @@ -6,6 +6,40 @@ package sbt.librarymanagement.ivy import _root_.sjsonnew.JsonFormat -trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat with sbt.internal.librarymanagement.formats.LoggerFormat with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat with sbt.librarymanagement.ivy.IvyPathsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ResolverFormats with sbt.librarymanagement.ModuleConfigurationFormats with sbt.librarymanagement.ivy.InlineIvyConfigurationFormats with sbt.librarymanagement.ivy.ExternalIvyConfigurationFormats => +trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.GlobalLockFormat + with sbt.internal.librarymanagement.formats.LoggerFormat + with sbt.librarymanagement.ivy.formats.UpdateOptionsFormat + with sbt.librarymanagement.ivy.IvyPathsFormats + with sbt.librarymanagement.ModuleIDFormats + with sjsonnew.BasicJsonProtocol + with sbt.librarymanagement.ResolverFormats + with sbt.librarymanagement.ModuleConfigurationFormats + with sbt.librarymanagement.ivy.InlineIvyConfigurationFormats + with sbt.librarymanagement.ivy.ExternalIvyConfigurationFormats + with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.ConfigRefFormats + with sbt.librarymanagement.ChecksumFormats + with sbt.librarymanagement.InclExclRuleFormats + with sbt.librarymanagement.CrossVersionFormats + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats + with sbt.librarymanagement.ChainedResolverFormats + with sbt.librarymanagement.MavenRepoFormats + with sbt.librarymanagement.MavenCacheFormats + with sbt.librarymanagement.PatternsFormats + with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.FileRepositoryFormats + with sbt.librarymanagement.URLRepositoryFormats + with sbt.librarymanagement.SshConnectionFormats + with sbt.librarymanagement.SshAuthenticationFormats + with sbt.librarymanagement.SshRepositoryFormats + with sbt.librarymanagement.SftpRepositoryFormats + with sbt.librarymanagement.PasswordAuthenticationFormats + with sbt.librarymanagement.KeyFileAuthenticationFormats => implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.IvyConfiguration] = flatUnionFormat2[sbt.librarymanagement.ivy.IvyConfiguration, sbt.librarymanagement.ivy.InlineIvyConfiguration, sbt.librarymanagement.ivy.ExternalIvyConfiguration]("type") } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala index fc71dee26..6929546be 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/formats/UpdateOptionsFormat.scala @@ -4,7 +4,35 @@ package formats import sjsonnew._ import sbt.librarymanagement._ -trait UpdateOptionsFormat { self: BasicJsonProtocol with ModuleIDFormats with ResolverFormats => +trait UpdateOptionsFormat { + self: BasicJsonProtocol + with ModuleIDFormats + with ResolverFormats + with sbt.librarymanagement.ArtifactFormats + with sbt.librarymanagement.ConfigRefFormats + with sbt.librarymanagement.ChecksumFormats + with sbt.librarymanagement.InclExclRuleFormats + with sbt.librarymanagement.CrossVersionFormats + with sbt.librarymanagement.DisabledFormats + with sbt.librarymanagement.BinaryFormats + with sbt.librarymanagement.ConstantFormats + with sbt.librarymanagement.PatchFormats + with sbt.librarymanagement.FullFormats + with sbt.librarymanagement.For3Use2_13Formats + with sbt.librarymanagement.For2_13Use3Formats + with sbt.librarymanagement.ChainedResolverFormats + with sbt.librarymanagement.MavenRepoFormats + with sbt.librarymanagement.MavenCacheFormats + with sbt.librarymanagement.PatternsFormats + with sbt.librarymanagement.FileConfigurationFormats + with sbt.librarymanagement.FileRepositoryFormats + with sbt.librarymanagement.URLRepositoryFormats + with sbt.librarymanagement.SshConnectionFormats + with sbt.librarymanagement.SshAuthenticationFormats + with sbt.librarymanagement.SshRepositoryFormats + with sbt.librarymanagement.SftpRepositoryFormats + with sbt.librarymanagement.PasswordAuthenticationFormats + with sbt.librarymanagement.KeyFileAuthenticationFormats => /* This is necessary to serialize/deserialize `directResolvers`. */ private implicit val moduleIdJsonKeyFormat: sjsonnew.JsonKeyFormat[ModuleID] = { new sjsonnew.JsonKeyFormat[ModuleID] { From a8f2b1f6361913942c19c25fdd06b8e154b0dadb Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 30 Jan 2022 03:08:24 -0500 Subject: [PATCH 0943/1030] Reformat --- .../internal/librarymanagement/JsonUtil.scala | 55 +++-- .../SemanticSelectorExtra.scala | 8 +- .../librarymanagement/VersionRange.scala | 2 +- .../librarymanagement/VersionSchemes.scala | 3 +- .../cross/CrossVersionUtil.scala | 3 +- .../librarymanagement/CrossVersionExtra.scala | 6 +- .../librarymanagement/DependencyFilter.scala | 4 +- .../DependencyResolution.scala | 14 +- .../sbt/librarymanagement/EvictionError.scala | 58 ++--- .../librarymanagement/EvictionWarning.scala | 10 +- .../sbt/librarymanagement/ModuleIDExtra.scala | 12 +- .../sbt/librarymanagement/ResolverExtra.scala | 35 +-- .../librarymanagement/RichUpdateReport.scala | 25 +- .../librarymanagement/UnresolvedWarning.scala | 28 ++- .../librarymanagement/UpdateReportExtra.scala | 33 +-- .../sbt/librarymanagement/VersionNumber.scala | 9 +- .../ReplaceMavenConfigurationMappings.scala | 2 - .../librarymanagement/ComponentManager.scala | 2 +- .../librarymanagement/ConvertResolver.scala | 152 ++++++------ .../librarymanagement/CustomPomParser.scala | 22 +- .../librarymanagement/CustomXmlParser.scala | 4 +- .../librarymanagement/FakeResolver.scala | 4 +- .../librarymanagement/IvyActions.scala | 117 +++++---- .../internal/librarymanagement/IvyCache.scala | 18 +- .../librarymanagement/IvyLogger.scala | 2 +- .../librarymanagement/IvyScalaUtil.scala | 14 +- .../librarymanagement/ResolutionCache.scala | 3 +- .../CachedResolutionResolveEngine.scala | 228 ++++++++++-------- .../ivyint/ErrorMessageAuthenticator.scala | 6 +- .../ivyint/GigahorseUrlHandler.scala | 82 ++++--- .../ivyint/IvyCredentialsLookup.scala | 4 +- .../ivyint/MergeDescriptors.scala | 16 +- .../ivyint/ParallelResolveEngine.scala | 25 +- .../ivyint/SbtChainResolver.scala | 79 +++--- 34 files changed, 570 insertions(+), 515 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index e7e087537..8d15a64cb 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -34,34 +34,33 @@ private[sbt] object JsonUtil { UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite( cr.configuration.name, - cr.details map { - oar => - OrganizationArtifactReport( - oar.organization, - oar.name, - oar.modules map { mr => - ModuleReport( - mr.module, - mr.artifacts, - mr.missingArtifacts, - mr.status, - mr.publicationDate, - mr.resolver, - mr.artifactResolver, - mr.evicted, - mr.evictedData, - mr.evictedReason, - mr.problem, - mr.homepage, - mr.extraAttributes, - mr.isDefault, - mr.branch, - mr.configurations, - mr.licenses, - filterOutArtificialCallers(mr.callers) - ) - } - ) + cr.details map { oar => + OrganizationArtifactReport( + oar.organization, + oar.name, + oar.modules map { mr => + ModuleReport( + mr.module, + mr.artifacts, + mr.missingArtifacts, + mr.status, + mr.publicationDate, + mr.resolver, + mr.artifactResolver, + mr.evicted, + mr.evictedData, + mr.evictedReason, + mr.problem, + mr.homepage, + mr.extraAttributes, + mr.isDefault, + mr.branch, + mr.configurations, + mr.licenses, + filterOutArtificialCallers(mr.callers) + ) + } + ) } ) }) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index 8fafce2a0..d9a7fb24f 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -58,8 +58,8 @@ private[librarymanagement] abstract class SemComparatorExtra { protected def toStringImpl: String = { val versionStr = Seq(major, minor, patch) - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" @@ -177,8 +177,8 @@ private[librarymanagement] abstract class SemComparatorFunctions { } parse( numbers - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") ) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index 74c7ff253..3bf85a9e9 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -71,7 +71,7 @@ object VersionRange { case _: NumberFormatException => // TODO - if the version doesn't meet our expectations, maybe we just issue a hard // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") + // sys.error(s"Could not fix version [$revision] into maven style version") revision } } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala index e214cc377..112420028 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -36,7 +36,8 @@ private[sbt] object VersionSchemes { case x => sys.error(s"unknown version scheme: $x") } - /** info.versionScheme property will be included into POM after sbt 1.4.0. + /** + * info.versionScheme property will be included into POM after sbt 1.4.0. */ def extractFromId(mid: ModuleID): Option[String] = extractFromExtraAttributes(mid.extraAttributes) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index fe6b107cf..b487a3b9a 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -27,7 +27,8 @@ object CrossVersionUtil { private[sbt] val BinCompatV = raw"""$basicVersion(-$tagPattern)?-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r private val MilestonV = raw"""$basicVersion(-M$tagPattern)""".r - private val NonReleaseV_n = raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes + private val NonReleaseV_n = + raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes private val NonReleaseV_1 = raw"""$basicVersion(-$tagPattern)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 9de8605ea..cd4736dff 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -37,13 +37,13 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def fullWith(prefix: String, suffix: String): CrossVersion = Full(prefix, suffix) - /** Cross-versions a module with the binary version (typically the binary Scala version). */ + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ def disabled: CrossVersion = sbt.librarymanagement.Disabled - /** Cross-versions a module with a constant string (typically the binary Scala version). */ + /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) /** @@ -218,7 +218,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def scalaApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.scalaApiVersion(v) - /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2. */ val PartialVersion = CrossVersionUtil.PartialVersion /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 2f2adf763..3aa96f30d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -29,7 +29,9 @@ trait DependencyFilterExtra { ): ArtifactFilter = new ArtifactFilter { def apply(a: Artifact): Boolean = - name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier + name.accept(a.name) && `type`.accept(a.`type`) && extension.accept( + a.extension + ) && classifier .accept(a.classifier getOrElse "") } diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index 500f569e5..1f2b37a2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -189,10 +189,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap Right(r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { - case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + artFileSeq map { case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f } }) case Left(w) => Left(w) @@ -200,10 +199,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface } protected def directDependenciesNames(module: ModuleDescriptor): String = - (module.directDependencies map { - case mID: ModuleID => - import mID._ - s"$organization % $name % $revision" + (module.directDependencies map { case mID: ModuleID => + import mID._ + s"$organization % $name % $revision" }).mkString(", ") } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 6d0d0c274..01fcb3bc5 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -106,11 +106,16 @@ object EvictionError { if (isNameScalaSuffixed(p.name)) assumedVersionScheme else assumedVersionSchemeJava val guess = VersionSchemes.evalFunc(scheme) - (p.evicteds forall { r => - f((r.module, winnerOpt, module.scalaModuleInfo)) - }, schemeOpt.getOrElse("?"), p.evicteds forall { r => - guess((r.module, winnerOpt, module.scalaModuleInfo)) - }, scheme) + ( + p.evicteds forall { r => + f((r.module, winnerOpt, module.scalaModuleInfo)) + }, + schemeOpt.getOrElse("?"), + p.evicteds forall { r => + guess((r.module, winnerOpt, module.scalaModuleInfo)) + }, + scheme + ) } pairs foreach { // don't report on a transitive eviction that does not have a winner @@ -152,30 +157,29 @@ final class EvictionError private[sbt] ( val out: mutable.ListBuffer[String] = mutable.ListBuffer() out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" - evictions.foreach({ - case (a, scheme) => - val revs = a.evicteds map { _.module.revision } - val revsStr = - if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" - val seen: mutable.Set[ModuleID] = mutable.Set() - val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => - val rev = r.module.revision - r.callers.toList flatMap { caller => - if (seen(caller.caller)) Nil - else { - seen += caller.caller - List(f"\t +- ${caller}%-50s (depends on $rev)") - } + evictions.foreach({ case (a, scheme) => + val revs = a.evicteds map { _.module.revision } + val revsStr = + if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") } } - val que = if (assumed) "?" else "" - val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" - case _ => " is evicted for all versions" - } - val title = s"\t* ${a.organization}:${a.name}$winnerRev" - val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") - out ++= lines + } + val que = if (assumed) "?" else "" + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" + case _ => " is evicted for all versions" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") + out ++= lines }) out.toList } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 25cae9c61..33899306a 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -279,10 +279,12 @@ object EvictionWarning { } confs flatMap { confReport => confReport.details map { detail => - if ((detail.modules exists { _.evicted }) && - !(buffer exists { x => - (x.organization == detail.organization) && (x.name == detail.name) - })) { + if ( + (detail.modules exists { _.evicted }) && + !(buffer exists { x => + (x.organization == detail.organization) && (x.name == detail.name) + }) + ) { buffer += detail } } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index cb68eaf78..022d919de 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -37,10 +37,10 @@ private[librarymanagement] abstract class ModuleIDExtra { protected def toStringImpl: String = s"""$organization:$name:$revision""" + (configurations match { case Some(s) => ":" + s; case None => "" }) + { - val attr = attributeString - if (attr == "") "" - else " " + attr - } + + val attr = attributeString + if (attr == "") "" + else " " + attr + } + (if (extraAttributes.isEmpty) "" else " " + extraString) protected def attributeString: String = { @@ -95,10 +95,10 @@ private[librarymanagement] abstract class ModuleIDExtra { }) // () required for chaining - /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `intransitive`. */ def notTransitive(): ModuleID = intransitive() - /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `notTransitive`. */ def intransitive(): ModuleID = withIsTransitive(false) /** diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index cb353df1f..22f630156 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -167,7 +167,7 @@ private[librarymanagement] abstract class ResolverFunctions { ) def jcenterRepo = JCenterRepository - /** Add the local and Maven Central repositories to the user repositories. */ + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) @@ -214,7 +214,10 @@ private[librarymanagement] abstract class ResolverFunctions { single(JCenterRepository, jcenter) ++ (xs.partition(_ == DefaultMavenRepository) match { case (_, xs) => - single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates? + single( + DefaultMavenRepository, + mavenCentral + ) ++ xs // TODO - Do we need to filter out duplicates? }) }) } @@ -222,7 +225,7 @@ private[librarymanagement] abstract class ResolverFunctions { private def single[T](value: T, nonEmpty: Boolean): Vector[T] = if (nonEmpty) Vector(value) else Vector.empty - /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ sealed abstract class Define[RepositoryType <: SshBasedRepository] { /** Subclasses should implement this method to */ @@ -251,8 +254,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), None, Some(basePath)) @@ -260,8 +263,8 @@ private[librarymanagement] abstract class ResolverFunctions { * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), None) @@ -270,8 +273,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), Some(basePath)) @@ -286,13 +289,13 @@ private[librarymanagement] abstract class ResolverFunctions { construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) } - /** A factory to construct an interface to an Ivy SSH resolver.*/ + /** A factory to construct an interface to an Ivy SSH resolver. */ object ssh extends Define[SshRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) } - /** A factory to construct an interface to an Ivy SFTP resolver.*/ + /** A factory to construct an interface to an Ivy SFTP resolver. */ object sftp extends Define[SftpRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) @@ -330,8 +333,8 @@ private[librarymanagement] abstract class ResolverFunctions { def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) } - private def baseRepository[T](base: String)(construct: Patterns => T)( - implicit basePatterns: Patterns + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit + basePatterns: Patterns ): T = construct(resolvePatterns(base, basePatterns)) @@ -363,7 +366,7 @@ private[librarymanagement] abstract class ResolverFunctions { } def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern)) - def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) + def ivyStylePatterns = defaultIvyPatterns // Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = @@ -394,7 +397,9 @@ private[librarymanagement] abstract class ResolverFunctions { } sys.props.get("maven.repo.local").map(new File(_)) orElse loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse - loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse + loadHomeFromSettings(() => + new File(new File(System.getenv("M2_HOME")), "conf/settings.xml") + ) getOrElse new File(sbt.io.Path.userHome, ".m2/repository") } // TODO - should this just be the *exact* same as mavenLocal? probably... diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index f66440bbb..9060f14b6 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -12,16 +12,15 @@ final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles val stamps = files - .map( - f => - ( - f, - // TODO: The list of files may also contain some odd files that do not actually exist like: - // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". - // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such - // files to begin with, in principle. - IO.getModifiedTimeOrZero(f) - ) + .map(f => + ( + f, + // TODO: The list of files may also contain some odd files that do not actually exist like: + // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". + // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such + // files to begin with, in principle. + IO.getModifiedTimeOrZero(f) + ) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) @@ -65,13 +64,13 @@ final class RichUpdateReport(report: UpdateReport) { file } - /** Constructs a new report that only contains files matching the specified filter.*/ + /** Constructs a new report that only contains files matching the specified filter. */ def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => modReport .withArtifacts( - modReport.artifacts filter { - case (art, _) => f(configuration, modReport.module, art) + modReport.artifacts filter { case (art, _) => + f(configuration, modReport.module, art) } ) .withMissingArtifacts( diff --git a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala index d871caa83..5e267f75b 100644 --- a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala @@ -10,9 +10,13 @@ final class ResolveException( val failedPaths: Map[ModuleID, Seq[ModuleID]] ) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = - this(messages, failed, Map(failed map { m => - m -> Nil - }: _*)) + this( + messages, + failed, + Map(failed map { m => + m -> Nil + }: _*) + ) } /** @@ -30,13 +34,12 @@ object UnresolvedWarning { config: UnresolvedWarningConfiguration ): UnresolvedWarning = { def modulePosition(m0: ModuleID): Option[SourcePosition] = - config.modulePositions.find { - case (m, _) => - (m.organization == m0.organization) && - (m0.name startsWith m.name) && - (m.revision == m0.revision) - } map { - case (_, p) => p + config.modulePositions.find { case (m, _) => + (m.organization == m0.organization) && + (m0.name startsWith m.name) && + (m.revision == m0.revision) + } map { case (_, p) => + p } val failedPaths = err.failed map { (x: ModuleID) => err.failedPaths(x).toList.reverse map { id => @@ -67,9 +70,8 @@ object UnresolvedWarning { if (path.nonEmpty) { val head = path.head buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) - path.tail foreach { - case (m, pos) => - buffer += "\t\t +- " + m.toString + sourcePosStr(pos) + path.tail foreach { case (m, pos) => + buffer += "\t\t +- " + m.toString + sourcePosStr(pos) } } } diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 1ffba5008..910827703 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -29,9 +29,13 @@ private[librarymanagement] abstract class ConfigurationReportExtra { } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): ConfigurationReport = - ConfigurationReport(configuration, modules map { - _.retrieve((mid, art, file) => f(configuration, mid, art, file)) - }, details) + ConfigurationReport( + configuration, + modules map { + _.retrieve((mid, art, file) => f(configuration, mid, art, file)) + }, + details + ) } private[librarymanagement] abstract class ModuleReportExtra { @@ -124,24 +128,23 @@ private[librarymanagement] abstract class UpdateReportExtra { /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { - case (_, v) => - v reduceLeft { (agg, x) => - agg.withConfigurations( - (agg.configurations, x.configurations) match { - case (None, _) => x.configurations - case (Some(ac), None) => Some(ac) - case (Some(ac), Some(xc)) => Some(s"$ac;$xc") - } - ) - } + configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } + ) + } } } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) - /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ + /** Gets the report for the given configuration, or `None` if the configuration was not resolved. */ def configuration(s: ConfigRef) = configurations.find(_.configuration == s) /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 8ce15c72d..1da91342e 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -162,7 +162,8 @@ object VersionNumber { } } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -172,7 +173,8 @@ object VersionNumber { PackVer.isCompatible(v1, v2) } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -193,7 +195,8 @@ object VersionNumber { } } - /** A variant of SemVar that enforces API compatibility when the first segment is zero. + /** + * A variant of SemVar that enforces API compatibility when the first segment is zero. */ object EarlySemVer extends VersionNumberCompatibility { import SemVer._ diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index 410bdcfb7..fb0b889d6 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -21,8 +21,6 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; * * Also see: http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html * and: http://svn.apache.org/repos/asf/ant/ivy/core/tags/2.3.0/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java - * - * */ object ReplaceMavenConfigurationMappings { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index ed42cd14c..710c120de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -56,7 +56,7 @@ class ComponentManager( /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action) - /** This is used to ensure atomic access to components in the global Ivy cache.*/ + /** This is used to ensure atomic access to components in the global Ivy cache. */ private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action) private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index f682a785e..33b55ab86 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -151,83 +151,82 @@ private[sbt] object ConvertResolver { (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) /** The default implementation of converter. */ - lazy val defaultConvert: ResolverConverter = { - case (r, settings, log) => - val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { - case Some(x) => x.toBoolean - case _ => false + lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => + val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { + case Some(x) => x.toBoolean + case _ => false + } + r match { + case repo: MavenRepository => { + val pattern = Collections.singletonList( + Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) + ) + final class PluginCapableResolver + extends IBiblioResolver + with ChecksumFriendlyURLResolver + with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + def setPatterns(): Unit = { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + } + val resolver = new PluginCapableResolver + if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver + .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } - r match { - case repo: MavenRepository => { - val pattern = Collections.singletonList( - Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) - ) - final class PluginCapableResolver - extends IBiblioResolver - with ChecksumFriendlyURLResolver - with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - def setPatterns(): Unit = { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - } - val resolver = new PluginCapableResolver - if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver - .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver + case repo: SshRepository => { + val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) } - case repo: SshRepository => { - val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - initializeSSHResolver(resolver, repo, settings) - repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - resolver - } - case repo: SftpRepository => { - val resolver = new SFTPResolver with ThreadSafeSshBasedResolver - initializeSSHResolver(resolver, repo, settings) - resolver - } - case repo: FileRepository => { - val resolver = new FileSystemResolver with DescriptorRequired { - // Workaround for #1156 - // Temporarily in sbt 0.13.x we deprecate overwriting - // in local files for non-changing revisions. - // This will be fully enforced in sbt 1.0. - setRepository(new WarnOnOverwriteFileRepo()) - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - import repo.configuration.{ isLocal, isTransactional } - resolver.setLocal(isLocal) - isTransactional.foreach(value => resolver.setTransactional(value.toString)) - resolver - } - case repo: URLRepository => { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - resolver - } - case repo: ChainedResolver => - IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) - case repo: RawRepository => - repo.resolver match { - case r: DependencyResolver => r - } + initializeSSHResolver(resolver, repo, settings) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver } + case repo: SftpRepository => { + val resolver = new SFTPResolver with ThreadSafeSshBasedResolver + initializeSSHResolver(resolver, repo, settings) + resolver + } + case repo: FileRepository => { + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + import repo.configuration.{ isLocal, isTransactional } + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => { + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + resolver + } + case repo: ChainedResolver => + IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) + case repo: RawRepository => + repo.resolver match { + case r: DependencyResolver => r + } + } } private sealed trait DescriptorRequired extends BasicResolver { @@ -290,8 +289,9 @@ private[sbt] object ConvertResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { val prev = descriptorString(isAllownomd) setDescriptor(descriptorString(hasExplicitURL(dd))) - val t = try super.getDependency(dd, data) - finally setDescriptor(prev) + val t = + try super.getDependency(dd, data) + finally setDescriptor(prev) t } def descriptorString(optional: Boolean) = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index e81ef45cd..8d1ca3bb4 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -64,7 +64,7 @@ object CustomPomParser { // Evil hackery to override the default maven pom mappings. ReplaceMavenConfigurationMappings.init() - /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution. */ val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX val ApiURLKey = SbtPomExtraProperties.POM_API_KEY val VersionSchemeKey = SbtPomExtraProperties.VERSION_SCHEME_KEY @@ -109,7 +109,9 @@ object CustomPomParser { val MyHash = MakeTransformHash(md) // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && - ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + ((Option(extraInfo get TransformedHashKey) orElse Option( + extraInfo get oldTransformedHashKey + )) match { case Some(MyHash) => true case _ => false }) @@ -269,17 +271,23 @@ object CustomPomParser { for (l <- md.getLicenses) dmd.addLicense(l) for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again - for ((key, value) <- md.getExtraAttributesNamespaces - .asInstanceOf[java.util.Map[String, String]] - .asScala) dmd.addExtraAttributeNamespace(key, value) + dmd.addExtraInfo( + TransformedHashKey, + MakeTransformHash(md) + ) // mark as transformed by this version, so we don't need to do it again + for ( + (key, value) <- md.getExtraAttributesNamespaces + .asInstanceOf[java.util.Map[String, String]] + .asScala + ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = - if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra + if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } + else withExtra val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index 0498828be..a72a65339 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.repository.url.URLResource -/** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ +/** Subclasses the default Ivy file parser in order to provide access to protected methods. */ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) @@ -26,7 +26,7 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { } def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes)) - /** Overridden because the super implementation overwrites the module descriptor.*/ + /** Overridden because the super implementation overwrites the module descriptor. */ override def setResource(res: Resource): Unit = () override def setMd(md: DefaultModuleDescriptor) = { super.setMd(md) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 794fff9e3..df4a7d66b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -178,8 +178,8 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val artifact = for { artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) - artifact <- artifacts find ( - a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt + artifact <- artifacts find (a => + a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt ) } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 6d223287c..42a0eed7f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -29,7 +29,7 @@ import sbt.internal.librarymanagement.IvyUtil.TransientNetworkException object IvyActions { - /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'. */ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { module.withModule(log) { (ivy, md, _) => for (dependency <- md.getDependencies) { @@ -57,7 +57,7 @@ object IvyActions { module.owner.cleanCachedResolutionCache() } - /** Creates a Maven pom from the given Ivy configuration*/ + /** Creates a Maven pom from the given Ivy configuration */ def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = { import configuration.{ allRepositories, @@ -91,13 +91,12 @@ object IvyActions { val deliverIvyPattern = configuration.deliverIvyPattern .getOrElse(sys.error("deliverIvyPattern must be specified.")) val status = getDeliverStatus(configuration.status) - module.withModule(log) { - case (ivy, md, _) => - val revID = md.getModuleRevisionId - val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(getConfigurations(md, configuration.configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) - deliveredFile(ivy, deliverIvyPattern, md) + module.withModule(log) { case (ivy, md, _) => + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(getConfigurations(md, configuration.configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } } @@ -130,18 +129,17 @@ object IvyActions { val artifacts = Map(configuration.artifacts: _*) val checksums = configuration.checksums - module.withModule(log) { - case (ivy, md, _) => - val resolver = ivy.getSettings.getResolver(resolverName) - if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") - val ivyArtifact = ivyFile map { file => - (MDArtifact.newIvyArtifact(md), file) - } - val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList - withChecksums(resolver, checksums) { - publish(md, as, resolver, overwrite = configuration.overwrite) - } + module.withModule(log) { case (ivy, md, _) => + val resolver = ivy.getSettings.getResolver(resolverName) + if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") + val ivyArtifact = ivyFile map { file => + (MDArtifact.newIvyArtifact(md), file) + } + val cross = crossVersionMap(module.moduleSettings) + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList + withChecksums(resolver, checksums) { + publish(md, as, resolver, overwrite = configuration.overwrite) + } } } private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])( @@ -193,35 +191,36 @@ object IvyActions { uwconfig: UnresolvedWarningConfiguration, log: Logger ): Either[UnresolvedWarning, UpdateReport] = { - module.withModule(log) { - case (ivy, moduleDescriptor, _) => - // Warn about duplicated and inconsistent dependencies - val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) - iw.foreach(log.warn(_)) + module.withModule(log) { case (ivy, moduleDescriptor, _) => + // Warn about duplicated and inconsistent dependencies + val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) + iw.foreach(log.warn(_)) - val metadataDirectory = configuration.metadataDirectory + val metadataDirectory = configuration.metadataDirectory - // Create inputs, resolve and retrieve the module descriptor - val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) - val resolutionResult: Either[ResolveException, UpdateReport] = { - if (module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined) { - val cache = - metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) - cachedResolveAndRetrieve(inputs, cache) - } else resolveAndRetrieve(inputs) - } + // Create inputs, resolve and retrieve the module descriptor + val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) + val resolutionResult: Either[ResolveException, UpdateReport] = { + if ( + module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined + ) { + val cache = + metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) + cachedResolveAndRetrieve(inputs, cache) + } else resolveAndRetrieve(inputs) + } - // Convert to unresolved warning or retrieve update report - resolutionResult.fold( - exception => Left(UnresolvedWarning(exception, uwconfig)), - ur0 => { - val ur = configuration.retrieveManaged match { - case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) - case _ => ur0 - } - Right(ur) + // Convert to unresolved warning or retrieve update report + resolutionResult.fold( + exception => Left(UnresolvedWarning(exception, uwconfig)), + ur0 => { + val ur = configuration.retrieveManaged match { + case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) + case _ => ur0 } - ) + Right(ur) + } + ) } } @@ -252,11 +251,10 @@ object IvyActions { exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { - case (_, mod, art) => - art.classifier.map { c => - (restrictedCopy(mod, false), c) - } + report.allMissing flatMap { case (_, mod, art) => + art.classifier.map { c => + (restrictedCopy(mod, false), c) + } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } /** @@ -275,8 +273,8 @@ object IvyActions { ) implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { - case a: IArtifact => applyFilter(a) + override def accept(o: Object): Boolean = Option(o) exists { case a: IArtifact => + applyFilter(a) } def applyFilter(a: IArtifact): Boolean = @@ -498,13 +496,12 @@ object IvyActions { checkFilesPresent(artifacts) try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - artifacts.foreach { - case (artifact, file) => - IvyUtil.retryWithBackoff( - resolver.publish(artifact, file, overwrite), - TransientNetworkException.apply, - maxAttempts = LMSysProp.maxPublishAttempts - ) + artifacts.foreach { case (artifact, file) => + IvyUtil.retryWithBackoff( + resolver.publish(artifact, file, overwrite), + TransientNetworkException.apply, + maxAttempts = LMSysProp.maxPublishAttempts + ) } resolver.commitPublishTransaction() } catch { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 397f2e8d7..cadd0e313 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -31,11 +31,11 @@ private object NotInCache { } } -/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ +/** Provides methods for working at the level of a single jar file with the default Ivy cache. */ class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") - /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID. */ def cacheJar( moduleID: ModuleID, file: File, @@ -52,7 +52,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Clears the cache of the jar for the given ID.*/ + /** Clears the cache of the jar for the given ID. */ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { try { withCachedJar(id, lock, log)(_.delete); () @@ -61,7 +61,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown. */ def retrieveCachedJar( id: ModuleID, toDirectory: File, @@ -74,7 +74,7 @@ class IvyCache(val ivyHome: Option[File]) { copyTo } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown . */ def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)( f: File => T ): T = { @@ -89,7 +89,7 @@ class IvyCache(val ivyHome: Option[File]) { if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } - /** Calls the given function with the default Ivy cache.*/ + /** Calls the given function with the default Ivy cache. */ def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)( f: DefaultRepositoryCacheManager => T ): T = { @@ -103,7 +103,7 @@ class IvyCache(val ivyHome: Option[File]) { } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) - /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory. */ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal val paths = IvyPaths(new File("."), ivyHome) @@ -115,12 +115,12 @@ class IvyCache(val ivyHome: Option[File]) { (new IvySbt(conf, CustomHttp.defaultHttpClient), local) } - /** Creates a default jar artifact based on the given ID.*/ + /** Creates a default jar artifact based on the given ID. */ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } -/** Required by Ivy for copying to the cache.*/ +/** Required by Ivy for copying to the cache. */ private class FileDownloader extends ResourceDownloader { def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { if (dest.exists()) dest.delete() diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index 29f61222a..dd0416399 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -19,7 +19,7 @@ private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogge case MSG_ERR => error(msg) } } - //DEBUG level messages are very verbose and rarely useful to users. + // DEBUG level messages are very verbose and rarely useful to users. // TODO: provide access to this information some other way def debug(msg: String): Unit = () def verbose(msg: String): Unit = logger.verbose(msg) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 3ea763301..a2c3ec452 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -67,9 +67,11 @@ object IvyScalaUtil { new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid - else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && - configQualifies && - dependeeQualifies) { + else if ( + (isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && + configQualifies && + dependeeQualifies + ) { // do not override the binary incompatible Scala version because: // - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library // - the Scala 2 TASTy reader can consume the Scala 3 artifacts @@ -152,7 +154,8 @@ object IvyScalaUtil { .forall(bv => bv.startsWith("3") || bv.startsWith("2.13")) def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } - val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs + val mismatched = + isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some( "Binary version (" + depBinaryVersion + ") for dependency " + id + @@ -180,8 +183,7 @@ object IvyScalaUtil { ): Unit = { val configurationNames = { val names = module.getConfigurationsNames - if (configurations.isEmpty) - names + if (configurations.isEmpty) names else { val configSet = configurationSet(configurations) configSet.intersect(HashSet(names: _*)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index c6d3da447..5c381913a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -102,5 +102,6 @@ private[sbt] object ResolutionCache { private val Name = "sbt-resolution-cache" // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions - private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" + private val ResolvedPattern = + "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7d94bca6d..c75b874d2 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -127,8 +127,12 @@ private[sbt] class CachedResolutionResolveCache { val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" - val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts + val depsString = s"""$mrid;${confMap.mkString( + "," + )};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString( + "," + )};explicitArtifacts=${explicitArtifacts .mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex( Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""") @@ -158,15 +162,14 @@ private[sbt] class CachedResolutionResolveCache { md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { case (k, _) => k.toString - } collect { - case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => - val attr: Map[Any, Any] = k.getAttributes.asScala.toMap - val module = IvyModuleId.newInstance( - attr(IvyPatternHelper.ORGANISATION_KEY).toString, - attr(IvyPatternHelper.MODULE_KEY).toString - ) - val pm = k.getPatternMatcher - IvyOverride(module, pm, v) + } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => + val attr: Map[Any, Any] = k.getAttributes.asScala.toMap + val module = IvyModuleId.newInstance( + attr(IvyPatternHelper.ORGANISATION_KEY).toString, + attr(IvyPatternHelper.MODULE_KEY).toString + ) + val pm = k.getPatternMatcher + IvyOverride(module, pm, v) } } def getOrElseUpdateMiniGraph( @@ -200,8 +203,10 @@ private[sbt] class CachedResolutionResolveCache { } val staticGraphDirectory = miniGraphPath / "static" val dynamicGraphDirectory = miniGraphPath / "dynamic" - val staticGraphPath = staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val staticGraphPath = + staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = + dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" def cleanDynamicGraph(): Unit = { val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList list filterNot { d => @@ -282,9 +287,12 @@ private[sbt] class CachedResolutionResolveCache { val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) - (surviving map moduleIdMap, evicted map moduleIdMap map { - _.withEvicted(true).withEvictedReason(Some(mgr.toString)) - }) + ( + surviving map moduleIdMap, + evicted map moduleIdMap map { + _.withEvicted(true).withEvictedReason(Some(mgr.toString)) + } + ) } (conflictCache get ((cf0, cf1))) match { case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) @@ -304,8 +312,7 @@ private[sbt] class CachedResolutionResolveCache { def getOrElseUpdateProjectReport(mrid: ModuleRevisionId, logicalClock: LogicalClock)( f: => Either[ResolveException, UpdateReport] ): Either[ResolveException, UpdateReport] = - if (projectReportCache contains (mrid -> logicalClock)) - projectReportCache((mrid, logicalClock)) + if (projectReportCache contains (mrid -> logicalClock)) projectReportCache((mrid, logicalClock)) else { val oldKeys = projectReportCache.keys filter { case (_, clk) => clk != logicalClock } projectReportCache --= oldKeys @@ -410,59 +417,58 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { Left(new ResolveException(messages, failed, failedPaths)) } } - val (internal, external) = mds.partition { - case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined + val (internal, external) = mds.partition { case (_, _, dd) => + cache.internalDependency(dd, projectResolver).isDefined } - val internalResults = internal map { - case (md, changing, dd) => - cache.getOrElseUpdateMiniGraph( - md, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md, dd) - } + val internalResults = internal map { case (md, changing, dd) => + cache.getOrElseUpdateMiniGraph( + md, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md, dd) + } } - val externalResults = external map { - case (md0, changing, dd) => - val configurationsInInternal = internalResults flatMap { - case Right(ur) => - ur.allModules.flatMap { - case md => - val sameName = md.name == dd.getDependencyId.getName - val sameOrg = md.organization == dd.getDependencyId.getOrganisation - if (sameName && sameOrg) md.configurations - else None + val externalResults = external map { case (md0, changing, dd) => + val configurationsInInternal = internalResults flatMap { + case Right(ur) => + ur.allModules.flatMap { case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } + case _ => Nil + } + + dd match { + case d: DefaultDependencyDescriptor => + configurationsInInternal foreach { c => + val configurations = c.split(";").map(_.split("->")) + configurations foreach { conf => + try d.addDependencyConfiguration(conf(0), conf(1)) + catch { + case _: Throwable => () + } // An exception will be thrown if `conf(0)` doesn't exist. } - case _ => Nil - } + } - dd match { - case d: DefaultDependencyDescriptor => - configurationsInInternal foreach { c => - val configurations = c.split(";").map(_.split("->")) - configurations foreach { conf => - try d.addDependencyConfiguration(conf(0), conf(1)) - catch { case _: Throwable => () } // An exception will be thrown if `conf(0)` doesn't exist. - } - } + case _ => () + } - case _ => () - } - - cache.getOrElseUpdateMiniGraph( - md0, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md0, dd) - } + cache.getOrElseUpdateMiniGraph( + md0, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md0, dd) + } } val results = internalResults ++ externalResults val uReport = @@ -485,21 +491,20 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { log: Logger ): Either[ResolveException, UpdateReport] = if (!missingOk && (results exists { _.isLeft })) - Left(mergeErrors(md0, results collect { case Left(re) => re })) + Left(mergeErrors(md0, results collect { case Left(re) => re })) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException]): ResolveException = { val messages = errors flatMap { _.messages } val failed = errors flatMap { _.failed } val failedPaths = errors flatMap { - _.failedPaths.toList map { - case (failed, paths) => - if (paths.isEmpty) (failed, paths) - else - ( - failed, - List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail - ) + _.failedPaths.toList map { case (failed, paths) => + if (paths.isEmpty) (failed, paths) + else + ( + failed, + List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail + ) } } new ResolveException(messages, failed, ListMap(failedPaths: _*)) @@ -579,12 +584,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // this might take up some memory, but it's limited to a single val reports1 = reports0 flatMap { filterReports } val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = - Map(orgNamePairs map { - case (organization, name) => - val xs = reports1 filter { oar => - oar.organization == organization && oar.name == name - } - ((organization, name), xs) + Map(orgNamePairs map { case (organization, name) => + val xs = reports1 filter { oar => + oar.organization == organization && oar.name == name + } + ((organization, name), xs) }: _*) // this returns a List of Lists of (org, name). should be deterministic def detectLoops( @@ -766,8 +770,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. - val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { - case (_, xs) => xs.head + val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (_, xs) => + xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct xs.head @@ -777,10 +781,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) - }).toSeq.toVector flatMap { - case (_, xs) => - if (xs.size < 2) xs - else Vector(mergeModuleReports(xs)) + }).toSeq.toVector flatMap { case (_, xs) => + if (xs.size < 2) xs + else Vector(mergeModuleReports(xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty @@ -789,9 +792,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { else resolveConflict(rootModuleConf, conflicts, os, log) match { case (survivor, evicted) => - (survivor ++ (merged filter { m => - m.evicted || m.problem.isDefined - }), evicted) + ( + survivor ++ (merged filter { m => + m.evicted || m.problem.isDefined + }), + evicted + ) } } @@ -869,9 +875,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }) match { case Some(m) => log.debug(s"- directly forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("direct-force")) - }, "direct-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("direct-force")) + }, + "direct-force" + ) case None => (conflicts find { m => m.callers.exists { _.isForceDependency } @@ -879,18 +889,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. case Some(m) if !ignoreTransitiveForce => log.debug(s"- transitively forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("transitive-force")) - }, "transitive-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("transitive-force")) + }, + "transitive-force" + ) case _ => val strategy = lcm.getStrategy val infos = conflicts map { ModuleReportArtifactInfo(_) } log.debug(s"- Using $strategy with $infos") Option(strategy.findLatest(infos.toArray, None.orNull)) match { case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some(lcm.toString)) - }, lcm.toString) + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some(lcm.toString)) + }, + lcm.toString + ) case _ => (conflicts, Vector(), lcm.toString) } } @@ -905,9 +923,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { mr.module.revision == ovrVersion } match { case Some(m) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("override")) - }, "override") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("override")) + }, + "override" + ) case None => sys.error( s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { @@ -925,7 +947,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }).mkString("(", ", ", ")")) ) case lcm: LatestConflictManager => useLatest(lcm) - case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") } } if (conflicts.size == 2 && os.isEmpty) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 2ba03b741..8b63ae40d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -65,8 +65,10 @@ object ErrorMessageAuthenticator { } try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some(_: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) + case Some( + _: ErrorMessageAuthenticator + ) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) } catch { case t: Throwable => Message.debug( diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala index 87ed352b1..b020fb432 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala @@ -47,52 +47,53 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { val response = http.newCall(request.build()).execute() try { - val infoOption = try { + val infoOption = + try { - if (checkStatusCode(url, response)) { - val bodyCharset = - BasicURLHandler.getCharSetFromContentType( - Option(response.body().contentType()).map(_.toString).orNull + if (checkStatusCode(url, response)) { + val bodyCharset = + BasicURLHandler.getCharSetFromContentType( + Option(response.body().contentType()).map(_.toString).orNull + ) + Some( + new SbtUrlInfo( + true, + response.body().contentLength(), + lastModifiedTimestamp(response), + bodyCharset + ) ) - Some( - new SbtUrlInfo( - true, - response.body().contentLength(), - lastModifiedTimestamp(response), - bodyCharset - ) - ) - } else None - // - // Commented out for now - can potentially be used for non HTTP urls - // - // val contentLength: Long = con.getContentLengthLong - // if (contentLength <= 0) None - // else { - // // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? - // val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) - // Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset)) - // } + } else None + // + // Commented out for now - can potentially be used for non HTTP urls + // + // val contentLength: Long = con.getContentLengthLong + // if (contentLength <= 0) None + // else { + // // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? + // val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) + // Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset)) + // } - } catch { - case e: UnknownHostException => - Message.warn("Host " + e.getMessage + " not found. url=" + url) - Message.info( - "You probably access the destination server through " - + "a proxy server that is not well configured." - ) - None - case e: IOException => - Message.error("Server access Error: " + e.getMessage + " url=" + url) - None - } + } catch { + case e: UnknownHostException => + Message.warn("Host " + e.getMessage + " not found. url=" + url) + Message.info( + "You probably access the destination server through " + + "a proxy server that is not well configured." + ) + None + case e: IOException => + Message.error("Server access Error: " + e.getMessage + " url=" + url) + None + } infoOption.getOrElse(UNAVAILABLE) } finally { response.close() } } - //The caller of this *MUST* call Response.close() + // The caller of this *MUST* call Response.close() private def getUrl(url0: URL): okhttp3.Response = { // Install the ErrorMessageAuthenticator if ("http" == url0.getProtocol || "https" == url0.getProtocol) { @@ -117,7 +118,7 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { response } catch { case NonFatal(e) => - //ensure the response gets closed if there's an error + // ensure the response gets closed if there's an error response.close() throw e } @@ -125,7 +126,7 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { } def openStream(url: URL): InputStream = { - //It's assumed that the caller of this will call close() on the supplied inputstream, + // It's assumed that the caller of this will call close() on the supplied inputstream, // thus closing the OkHTTP request getUrl(url).body().byteStream() } @@ -201,7 +202,8 @@ class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { } } - private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies + private val ErrorBodyTruncateLen = + 512 // in case some bad service returns files rather than messages in error bodies private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 // neurotic resource managemement... diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index 4d1e92420..9d8148323 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -56,8 +56,8 @@ private[sbt] object IvyCredentialsLookup { * A mapping of host -> realms in the ivy credentials store. */ def realmsForHost: Map[String, Set[String]] = - (keyringKeys collect { - case x: Realm => x + (keyringKeys collect { case x: Realm => + x } groupBy { realm => realm.host } mapValues { realms => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 1c9f2e7de..765360d90 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -13,14 +13,14 @@ private[sbt] object MergeDescriptors { a.isTransitive == b.isTransitive && a.getParentRevisionId == b.getParentRevisionId && a.getNamespace == b.getNamespace && { - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - amrid == bmrid - } && { - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - adyn == bdyn - } + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { assert(mergeable(a, b)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 9af7ef6cb..711e03225 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -48,17 +48,18 @@ private[sbt] class ParallelResolveEngine( } // Farm out the dependencies for parallel download implicit val ec = ParallelResolveEngine.resolveExecutionContext - val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { - case dep: IvyNode => - Future { - if (!(dep.isCompletelyEvicted || dep.hasProblem) && - dep.getModuleRevision != null) { - Some(downloadNodeArtifacts(dep, artifactFilter, options)) - } else None - } + val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { case dep: IvyNode => + Future { + if ( + !(dep.isCompletelyEvicted || dep.hasProblem) && + dep.getModuleRevision != null + ) { + Some(downloadNodeArtifacts(dep, artifactFilter, options)) + } else None + } } val allDownloads = Await.result(allDownloadsFuture, Duration.Inf) - //compute total downloaded size + // compute total downloaded size val totalSize = allDownloads.foldLeft(0L) { case (size, Some(download)) => val dependency = download.dep @@ -67,8 +68,10 @@ private[sbt] class ParallelResolveEngine( val configurationReport = report.getConfigurationReport(configuration) // Take into account artifacts required by the given configuration - if (dependency.isEvicted(configuration) || - dependency.isBlacklisted(configuration)) { + if ( + dependency.isEvicted(configuration) || + dependency.isBlacklisted(configuration) + ) { configurationReport.addDependency(dependency) } else configurationReport.addDependency(dependency, download.report) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 2314838ef..f239b282d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -124,7 +124,8 @@ private[sbt] case class SbtChainResolver( /** If None, module was not found. Otherwise, hit. */ type TriedResolution = Option[(ResolvedModuleRevision, DependencyResolver)] - /** Attempts to resolve the artifact from each of the resolvers in the chain. + /** + * Attempts to resolve the artifact from each of the resolvers in the chain. * * Contract: * 1. It doesn't resolve anything when there is a resolved module, `isReturnFirst` is @@ -155,8 +156,8 @@ private[sbt] case class SbtChainResolver( currentlyResolved = Option(resolver.getDependency(descriptor, data)) if (currentlyResolved eq previouslyResolved) None else if (useLatest) { - currentlyResolved.map( - x => (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) + currentlyResolved.map(x => + (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) ) } else currentlyResolved.map(x => (forcedRevision(x), resolver)) } @@ -174,7 +175,8 @@ private[sbt] case class SbtChainResolver( val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) try Right(performResolution(resolver)) - catch { case NonFatal(t) => reportError(t, resolver); Left(t) } finally { + catch { case NonFatal(t) => reportError(t, resolver); Left(t) } + finally { oldLatest.foreach(_ => doSetLatestStrategy(resolver, oldLatest)) checkInterrupted() } @@ -189,34 +191,33 @@ private[sbt] case class SbtChainResolver( data: ResolveData ): Option[ResolvedModuleRevision] = { - val sortedRevisions = foundRevisions.sortBy { - case (rmr, resolver) => - val publicationDate = rmr.getPublicationDate - val descriptorDate = rmr.getDescriptor.getPublicationDate - Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") - // Just issue warning about issues with publication date, and fake one on it for now - val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) - chosenPublicationDate match { - case Some(date) => date.getTime - case None => - val id = rmr.getId - val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) - resolvedResource match { - case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => - val resolvedPublicationDate = new java.util.Date(res.getLastModified) - Message.debug(s"No publication date from resolver $resolver for $id.") - Message.debug(s"Setting publication date to: $resolvedPublicationDate.") - dmd.setPublicationDate(resolvedPublicationDate) - res.getLastModified - case (ivf, dmd) => - // The dependency is specified by a direct URL or some sort of non-ivy file - if (ivf == null && descriptor.isChanging) - Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") - if (dmd == null) - Message.warn(s"$prefix: no publication date from resolver $resolver for $id") - 0L - } - } + val sortedRevisions = foundRevisions.sortBy { case (rmr, resolver) => + val publicationDate = rmr.getPublicationDate + val descriptorDate = rmr.getDescriptor.getPublicationDate + Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") + // Just issue warning about issues with publication date, and fake one on it for now + val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) + chosenPublicationDate match { + case Some(date) => date.getTime + case None => + val id = rmr.getId + val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) + resolvedResource match { + case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => + val resolvedPublicationDate = new java.util.Date(res.getLastModified) + Message.debug(s"No publication date from resolver $resolver for $id.") + Message.debug(s"Setting publication date to: $resolvedPublicationDate.") + dmd.setPublicationDate(resolvedPublicationDate) + res.getLastModified + case (ivf, dmd) => + // The dependency is specified by a direct URL or some sort of non-ivy file + if (ivf == null && descriptor.isChanging) + Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") + if (dmd == null) + Message.warn(s"$prefix: no publication date from resolver $resolver for $id") + 0L + } + } } val firstHit = sortedRevisions.reverse.headOption @@ -277,12 +278,11 @@ private[sbt] case class SbtChainResolver( } /** Cleans unnecessary module id information not provided by [[IvyRetrieve.toModuleID()]]. */ - private final val moduleResolvers = updateOptions.moduleResolvers.map { - case (key, value) => - val cleanKey = ModuleID(key.organization, key.name, key.revision) - .withExtraAttributes(key.extraAttributes) - .withBranchName(key.branchName) - cleanKey -> value + private final val moduleResolvers = updateOptions.moduleResolvers.map { case (key, value) => + val cleanKey = ModuleID(key.organization, key.name, key.revision) + .withExtraAttributes(key.extraAttributes) + .withBranchName(key.branchName) + cleanKey -> value } /** @@ -309,7 +309,8 @@ private[sbt] case class SbtChainResolver( def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] = resolvers.find(_.getName == ProjectResolver.InterProject) - /** Gets the dependency for a given descriptor with the pertinent resolve data. + /** + * Gets the dependency for a given descriptor with the pertinent resolve data. * * This is a custom sbt chain operation that produces better error output and deals with * cases that the conventional ivy resolver does not. It accumulates the resolution of From 7a2f81ea05ad1228c3c8bad7eccc742cddd07a44 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Mon, 31 Jan 2022 23:23:34 +0000 Subject: [PATCH 0944/1030] sonatypeRepos -> sonatypeOssRepos --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 4bb59b79c..0d6683a91 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,7 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("Use sonatypeRepos instead", "1.7.0") + @deprecated("Use sonatypeOssRepos instead", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, @@ -167,7 +167,7 @@ private[librarymanagement] abstract class ResolverFunctions { "sonatype-s01-" + status, SonatypeS01RepositoryRoot + "/" + status ) - def sonatypeRepos(status: String) = + def sonatypeOssRepos(status: String) = Vector(sonatypeRepo(status): @nowarn("cat=deprecation"), sonatypeS01Repo(status)) def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") From a07188232146d3a6f3644ec46c7da36d7151e5c0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 31 Jan 2022 19:22:37 -0500 Subject: [PATCH 0945/1030] Add predefined list of licenses --- .../scala/sbt/librarymanagement/License.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 core/src/main/scala/sbt/librarymanagement/License.scala diff --git a/core/src/main/scala/sbt/librarymanagement/License.scala b/core/src/main/scala/sbt/librarymanagement/License.scala new file mode 100644 index 000000000..6f335fb24 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/License.scala @@ -0,0 +1,24 @@ +package sbt.librarymanagement + +import java.net.URL + +/** + * Commonly used software licenses + * Names are SPDX ids: + * https://raw.githubusercontent.com/spdx/license-list-data/master/json/licenses.json + */ +object License { + lazy val Apache2: (String, URL) = + ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")) + + lazy val MIT: (String, URL) = + ("MIT", new URL("https://opensource.org/licenses/MIT")) + + lazy val CC0: (String, URL) = + ("CC0-1.0", new URL("https://creativecommons.org/publicdomain/zero/1.0/legalcode")) + + def PublicDomain: (String, URL) = CC0 + + lazy val GPL3_or_later: (String, URL) = + ("GPL-3.0-or-later", new URL("https://spdx.org/licenses/GPL-3.0-or-later.html")) +} From 85271660c70bd761d0c58ee73fb36b1a15074500 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sun, 22 May 2022 10:02:26 +0900 Subject: [PATCH 0946/1030] remove bintray resolver --- build.sbt | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sbt b/build.sbt index 00e45416b..a6d4c6df2 100644 --- a/build.sbt +++ b/build.sbt @@ -45,7 +45,6 @@ def commonSettings: Seq[Setting[_]] = Def.settings( resolvers += Resolver.typesafeIvyRepo("releases"), resolvers += Resolver.sonatypeRepo("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), - resolvers += "bintray-sbt-maven-releases" at "https://dl.bintray.com/sbt/maven-releases/", testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), From 91bf2649b25dd13c28f12cb22cee58e79e77c1f7 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 21:55:09 -0400 Subject: [PATCH 0947/1030] Bump sbt --- .github/workflows/ci.yml | 2 +- .gitignore | 1 + build.sbt | 21 ++++++--------------- project/build.properties | 2 +- project/plugins.sbt | 1 - 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6f16581f8..897e165ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,7 +37,7 @@ jobs: run: | case ${{ matrix.jobtype }} in 1) - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll whitesourceCheckPolicies +test +packagedArtifacts + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts ;; *) echo unknown jobtype diff --git a/.gitignore b/.gitignore index 495231475..0cbd43574 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__ scripted-test/src/sbt-test/*/*/project/build.properties scripted-test/src/sbt-test/*/*/project/plugins.sbt +metals.sbt diff --git a/build.sbt b/build.sbt index a6d4c6df2..ecc65b8d0 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,8 @@ val _ = { //https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } - +Global / semanticdbEnabled := true +Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { @@ -118,8 +119,7 @@ lazy val lmCore = (project in file("core")) scalaReflect.value, scalaCompiler.value, launcherInterface, - gigahorseOkhttp, - okhttpUrlconnection, + gigahorseApacheHttp, sjsonnewScalaJson.value % Optional, scalaTest % Test, scalaCheck % Test, @@ -260,7 +260,9 @@ lazy val lmCore = (project in file("core")) "sbt.librarymanagement.ResolverFunctions.validateArtifact" ), exclude[IncompatibleResultTypeProblem]("sbt.librarymanagement.*.validateProtocol"), - exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.cross.CrossVersionUtil.TransitionDottyVersion"), + exclude[DirectMissingMethodProblem]( + "sbt.internal.librarymanagement.cross.CrossVersionUtil.TransitionDottyVersion" + ), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.dottyID"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.DottyIDPrefix"), exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.toolDependencies*"), @@ -387,16 +389,5 @@ def customCommands: Seq[Setting[_]] = Seq( } ) -inThisBuild( - Seq( - whitesourceProduct := "Lightbend Reactive Platform", - whitesourceAggregateProjectName := "sbt-lm-master", - whitesourceAggregateProjectToken := "9bde4ccbaab7401a91f8cda337af84365d379e13abaf473b85cb16e3f5c65cb6", - whitesourceIgnoredScopes += "scalafmt", - whitesourceFailOnError := sys.env.contains("WHITESOURCE_PASSWORD"), // fail if pwd is present - whitesourceForceCheckAllDependencies := true, - ) -) - def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] = Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*))) diff --git a/project/build.properties b/project/build.properties index f0be67b9f..c8fcab543 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.5.1 +sbt.version=1.6.2 diff --git a/project/plugins.sbt b/project/plugins.sbt index f55cc0ddd..279b64f16 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,6 +3,5 @@ addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") -addSbtPlugin("com.lightbend" % "sbt-whitesource" % "0.1.14") scalacOptions += "-language:postfixOps" From 76452e53ff6f7211db2bab5dd3bc8f06dac1bbce Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 22:24:44 -0400 Subject: [PATCH 0948/1030] Drop OkHttp dependency Ref https://github.com/sbt/sbt/issues/6912 Problem ------- There's apparently a security issue with OkHttp 3.x, which I am not really sure how applicable it is to our usage of OkHttp but it is there. Solution -------- Since most of OkHttp-specic usage within LM is for Apache Ivy downloading, I am going to drop this. Since `sbt.librarymanagement.Http.http` is a public API, I am substituting this with Apache HTTP backed implementation. --- build.sbt | 10 + .../scala/sbt/librarymanagement/Http.scala | 2 +- .../JavaNetAuthenticator.java | 82 ----- .../librarymanagement/CustomHttp.scala | 21 -- .../sbt/internal/librarymanagement/Ivy.scala | 10 +- .../internal/librarymanagement/IvyCache.scala | 2 +- .../ivyint/GigahorseUrlHandler.scala | 339 ------------------ .../ivy/IvyDependencyResolution.scala | 6 +- .../librarymanagement/ivy/IvyPublisher.scala | 6 +- project/Dependencies.scala | 7 +- 10 files changed, 19 insertions(+), 466 deletions(-) delete mode 100644 ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java delete mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala delete mode 100644 ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala diff --git a/build.sbt b/build.sbt index ecc65b8d0..07e4fc470 100644 --- a/build.sbt +++ b/build.sbt @@ -89,6 +89,7 @@ val mimaSettings = Def settings ( "1.3.0", "1.4.0", "1.5.0", + "1.6.0", ) map ( version => organization.value %% moduleName.value % version @@ -353,6 +354,15 @@ lazy val lmIvy = (project in file("ivy")) "sbt.internal.librarymanagement.CustomPomParser.versionRangeFlag" ), exclude[MissingClassProblem]("sbt.internal.librarymanagement.FixedParser*"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler*"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.JavaNetAuthenticator"), + exclude[MissingClassProblem]("sbt.internal.librarymanagement.CustomHttp*"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.http"), + exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.IvySbt.this"), + exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ivy.IvyPublisher.apply"), + exclude[DirectMissingMethodProblem]( + "sbt.librarymanagement.ivy.IvyDependencyResolution.apply" + ), ), ) diff --git a/core/src/main/scala/sbt/librarymanagement/Http.scala b/core/src/main/scala/sbt/librarymanagement/Http.scala index 2b54f8140..5edf9a746 100644 --- a/core/src/main/scala/sbt/librarymanagement/Http.scala +++ b/core/src/main/scala/sbt/librarymanagement/Http.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import gigahorse._, support.okhttp.Gigahorse +import gigahorse._, support.apachehttp.Gigahorse import scala.concurrent.duration.DurationInt object Http { diff --git a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java b/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java deleted file mode 100644 index aa10461cc..000000000 --- a/ivy/src/main/java/internal/librarymanagement/JavaNetAuthenticator.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2013 Square, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package sbt.internal.librarymanagement; - -import java.io.IOException; -import java.net.Authenticator.RequestorType; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.PasswordAuthentication; -import java.net.Proxy; -import java.util.List; -import okhttp3.Authenticator; -import okhttp3.Route; -import okhttp3.Request; -import okhttp3.Response; -import okhttp3.HttpUrl; -import okhttp3.Challenge; -import okhttp3.Credentials; - -/** - * Adapts java.net.Authenticator to Authenticator. Configure OkHttp to use - * java.net.Authenticator with OkHttpClient.Builder#authenticator or - * OkHttpClient.Builder#proxyAuthenticator(Authenticator). - */ -public final class JavaNetAuthenticator implements Authenticator { - @Override public Request authenticate(Route route, Response response) throws IOException { - List challenges = response.challenges(); - Request request = response.request(); - HttpUrl url = request.url(); - boolean proxyAuthorization = response.code() == 407; - Proxy proxy = null; - if (route != null) { - proxy = route.proxy(); - } - - for (int i = 0, size = challenges.size(); i < size; i++) { - Challenge challenge = challenges.get(i); - if (!"Basic".equalsIgnoreCase(challenge.scheme())) continue; - - PasswordAuthentication auth; - if (proxyAuthorization) { - InetSocketAddress proxyAddress = (InetSocketAddress) proxy.address(); - auth = java.net.Authenticator.requestPasswordAuthentication( - proxyAddress.getHostName(), getConnectToInetAddress(proxy, url), proxyAddress.getPort(), - url.scheme(), challenge.realm(), challenge.scheme(), url.url(), - RequestorType.PROXY); - } else { - auth = java.net.Authenticator.requestPasswordAuthentication( - url.host(), getConnectToInetAddress(proxy, url), url.port(), url.scheme(), - challenge.realm(), challenge.scheme(), url.url(), RequestorType.SERVER); - } - - if (auth != null) { - String credential = Credentials.basic(auth.getUserName(), new String(auth.getPassword())); - return request.newBuilder() - .header(proxyAuthorization ? "Proxy-Authorization" : "Authorization", credential) - .build(); - } - } - - return null; // No challenges were satisfied! - } - - private InetAddress getConnectToInetAddress(Proxy proxy, HttpUrl url) throws IOException { - return (proxy != null && proxy.type() != Proxy.Type.DIRECT) - ? ((InetSocketAddress) proxy.address()).getAddress() - : InetAddress.getByName(url.host()); - } -} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala deleted file mode 100644 index 9454affc4..000000000 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomHttp.scala +++ /dev/null @@ -1,21 +0,0 @@ -package sbt.internal.librarymanagement - -import gigahorse.HttpClient -import okhttp3.{ JavaNetAuthenticator => _, _ } -import sbt.librarymanagement.Http - -object CustomHttp { - private[this] def http0: HttpClient = Http.http - - private[sbt] def defaultHttpClientBuilder: OkHttpClient.Builder = { - http0 - .underlying[OkHttpClient] - .newBuilder() - .authenticator(new sbt.internal.librarymanagement.JavaNetAuthenticator) - .followRedirects(true) - .followSslRedirects(true) - } - - private[sbt] lazy val defaultHttpClient: OkHttpClient = - defaultHttpClientBuilder.build -} diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index e45a5fcf4..eaab99af1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -7,7 +7,6 @@ import java.io.File import java.net.URI import java.util.concurrent.Callable -import okhttp3.OkHttpClient import org.apache.ivy.Ivy import org.apache.ivy.core.IvyPatternHelper import org.apache.ivy.core.cache.{ CacheMetadataOptions, DefaultRepositoryCacheManager } @@ -50,17 +49,13 @@ import ivyint.{ CachedResolutionResolveEngine, ParallelResolveEngine, SbtDefaultDependencyDescriptor, - GigahorseUrlHandler } import sjsonnew.JsonFormat import sjsonnew.support.murmurhash.Hasher final class IvySbt( val configuration: IvyConfiguration, - val http: OkHttpClient ) { self => - def this(configuration: IvyConfiguration) = this(configuration, CustomHttp.defaultHttpClient) - /* * ========== Configuration/Setup ============ * This part configures the Ivy instance by first creating the logger interface to ivy, then IvySettings, and then the Ivy instance. @@ -90,7 +85,6 @@ final class IvySbt( } private lazy val basicUrlHandler: URLHandler = new BasicURLHandler - private lazy val gigahorseUrlHandler: URLHandler = new GigahorseUrlHandler(http) private lazy val settings: IvySettings = { val dispatcher: URLHandlerDispatcher = URLHandlerRegistry.getDefault match { @@ -106,8 +100,8 @@ final class IvySbt( disp } - val urlHandler: URLHandler = - if (configuration.updateOptions.gigahorse) gigahorseUrlHandler else basicUrlHandler + // Ignore configuration.updateOptions.gigahorse due to sbt/sbt#6912 + val urlHandler: URLHandler = basicUrlHandler // Only set the urlHandler for the http/https protocols so we do not conflict with any other plugins // that might register other protocol handlers. diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index 397f2e8d7..f5ae6d8fb 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -112,7 +112,7 @@ class IvyCache(val ivyHome: Option[File]) { .withResolvers(Vector(local)) .withLock(lock) .withLog(log) - (new IvySbt(conf, CustomHttp.defaultHttpClient), local) + (new IvySbt(conf), local) } /** Creates a default jar artifact based on the given ID.*/ diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala deleted file mode 100644 index 87ed352b1..000000000 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/GigahorseUrlHandler.scala +++ /dev/null @@ -1,339 +0,0 @@ -package sbt.internal.librarymanagement -package ivyint - -import java.net.{ URL, UnknownHostException } -import java.io._ - -import scala.util.control.NonFatal - -import okhttp3.{ MediaType, Request, RequestBody } -import okhttp3.internal.http.HttpDate - -import okhttp3.{ JavaNetAuthenticator => _, _ } -import okio._ - -import org.apache.ivy.util.{ CopyProgressEvent, CopyProgressListener, Message } -import org.apache.ivy.util.url.{ AbstractURLHandler, BasicURLHandler, IvyAuthenticator, URLHandler } -import org.apache.ivy.util.url.URLHandler._ -import sbt.io.IO - -// Copied from Ivy's BasicURLHandler. -class GigahorseUrlHandler(http: OkHttpClient) extends AbstractURLHandler { - - import GigahorseUrlHandler._ - - /** - * Returns the URLInfo of the given url or a #UNAVAILABLE instance, - * if the url is not reachable. - */ - def getURLInfo(url: URL): URLInfo = getURLInfo(url, 0) - - /** - * Returns the URLInfo of the given url or a #UNAVAILABLE instance, - * if the url is not reachable. - */ - def getURLInfo(url0: URL, timeout: Int): URLInfo = { - // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol || "https" == url0.getProtocol) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - } - - val url = normalizeToURL(url0) - val request = new Request.Builder() - .url(url) - - if (getRequestMethod == URLHandler.REQUEST_METHOD_HEAD) request.head() else request.get() - - val response = http.newCall(request.build()).execute() - try { - val infoOption = try { - - if (checkStatusCode(url, response)) { - val bodyCharset = - BasicURLHandler.getCharSetFromContentType( - Option(response.body().contentType()).map(_.toString).orNull - ) - Some( - new SbtUrlInfo( - true, - response.body().contentLength(), - lastModifiedTimestamp(response), - bodyCharset - ) - ) - } else None - // - // Commented out for now - can potentially be used for non HTTP urls - // - // val contentLength: Long = con.getContentLengthLong - // if (contentLength <= 0) None - // else { - // // TODO: not HTTP... maybe we *don't* want to default to ISO-8559-1 here? - // val bodyCharset = BasicURLHandler.getCharSetFromContentType(con.getContentType) - // Some(new SbtUrlInfo(true, contentLength, con.getLastModified(), bodyCharset)) - // } - - } catch { - case e: UnknownHostException => - Message.warn("Host " + e.getMessage + " not found. url=" + url) - Message.info( - "You probably access the destination server through " - + "a proxy server that is not well configured." - ) - None - case e: IOException => - Message.error("Server access Error: " + e.getMessage + " url=" + url) - None - } - infoOption.getOrElse(UNAVAILABLE) - } finally { - response.close() - } - } - - //The caller of this *MUST* call Response.close() - private def getUrl(url0: URL): okhttp3.Response = { - // Install the ErrorMessageAuthenticator - if ("http" == url0.getProtocol || "https" == url0.getProtocol) { - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - } - - val url = normalizeToURL(url0) - val request = new Request.Builder() - .url(url) - .get() - .build() - - val response = http.newCall(request).execute() - try { - if (!checkStatusCode(url, response)) { - throw new IOException( - "The HTTP response code for " + url + " did not indicate a success." - + " See log for more detail." - ) - } - response - } catch { - case NonFatal(e) => - //ensure the response gets closed if there's an error - response.close() - throw e - } - - } - - def openStream(url: URL): InputStream = { - //It's assumed that the caller of this will call close() on the supplied inputstream, - // thus closing the OkHTTP request - getUrl(url).body().byteStream() - } - - def download(url: URL, dest: File, l: CopyProgressListener): Unit = { - - val response = getUrl(url) - try { - - if (l != null) { - l.start(new CopyProgressEvent()) - } - val sink = Okio.buffer(Okio.sink(dest)) - try { - sink.writeAll(response.body().source()) - sink.flush() - } finally { - sink.close() - } - - val contentLength = response.body().contentLength() - if (contentLength != -1 && dest.length != contentLength) { - IO.delete(dest) - throw new IOException( - "Downloaded file size doesn't match expected Content Length for " + url - + ". Please retry." - ) - } - - val lastModified = lastModifiedTimestamp(response) - if (lastModified > 0) { - IO.setModifiedTimeOrFalse(dest, lastModified) - } - - if (l != null) { - l.end(new CopyProgressEvent(EmptyBuffer, contentLength)) - } - - } finally { - response.close() - } - } - - def upload(source: File, dest0: URL, l: CopyProgressListener): Unit = { - - if (("http" != dest0.getProtocol) && ("https" != dest0.getProtocol)) { - throw new UnsupportedOperationException("URL repository only support HTTP PUT at the moment") - } - - IvyAuthenticator.install() - ErrorMessageAuthenticator.install() - - val dest = normalizeToURL(dest0) - - val body = RequestBody.create(MediaType.parse("application/octet-stream"), source) - - val request = new Request.Builder() - .url(dest) - .put(body) - .build() - - if (l != null) { - l.start(new CopyProgressEvent()) - } - val response = http.newCall(request).execute() - try { - if (l != null) { - l.end(new CopyProgressEvent(EmptyBuffer, source.length())) - } - validatePutStatusCode(dest, response) - } finally { - response.close() - } - } - - private val ErrorBodyTruncateLen = 512 // in case some bad service returns files rather than messages in error bodies - private val DefaultErrorCharset = java.nio.charset.StandardCharsets.UTF_8 - - // neurotic resource managemement... - // we could use this elsewhere in the class too - private def borrow[S <: AutoCloseable, T](rsrc: => S)(op: S => T): T = { - val r = rsrc - val out = { - try { - op(r) - } catch { - case NonFatal(t) => { - try { - r.close() - } catch { - case NonFatal(ct) => t.addSuppressed(ct) - } - throw t - } - } - } - r.close() - out - } - - // this is perhaps overly cautious, but oh well - private def readTruncated(byteStream: InputStream): Option[(Array[Byte], Boolean)] = { - borrow(byteStream) { is => - borrow(new ByteArrayOutputStream(ErrorBodyTruncateLen)) { os => - var count = 0 - var b = is.read() - var truncated = false - while (!truncated && b >= 0) { - if (count >= ErrorBodyTruncateLen) { - truncated = true - } else { - os.write(b) - count += 1 - b = is.read() - } - } - if (count > 0) { - Some((os.toByteArray, truncated)) - } else { - None - } - } - } - } - - /* - * Supplements the IOException emitted on a bad status code by our inherited validatePutStatusCode(...) - * method with any message that might be present in an error response body. - * - * after calling this method, the object given as the response parameter must be reliably closed. - */ - private def validatePutStatusCode(dest: URL, response: Response): Unit = { - try { - validatePutStatusCode(dest, response.code(), response.message()) - } catch { - case ioe: IOException => { - val mbBodyMessage = { - for { - body <- Option(response.body()) - is <- Option(body.byteStream) - (bytes, truncated) <- readTruncated(is) - charset <- Option(body.contentType()).map(_.charset(DefaultErrorCharset)) orElse Some( - DefaultErrorCharset - ) - } yield { - val raw = new String(bytes, charset) - if (truncated) raw + "..." else raw - } - } - - mbBodyMessage match { - case Some(bodyMessage) => { // reconstruct the IOException - val newMessage = ioe.getMessage() + s"; Response Body: ${bodyMessage}" - val reconstructed = new IOException(newMessage, ioe.getCause()) - reconstructed.setStackTrace(ioe.getStackTrace()) - throw reconstructed - } - case None => { - throw ioe - } - } - } - } - } -} - -object GigahorseUrlHandler { - // This is requires to access the constructor of URLInfo. - private[sbt] class SbtUrlInfo( - available: Boolean, - contentLength: Long, - lastModified: Long, - bodyCharset: String - ) extends URLInfo(available, contentLength, lastModified, bodyCharset) { - def this(available: Boolean, contentLength: Long, lastModified: Long) = { - this(available, contentLength, lastModified, null) - } - } - - private val EmptyBuffer: Array[Byte] = new Array[Byte](0) - - private def checkStatusCode(url: URL, response: Response): Boolean = - response.code() match { - case 200 => true - case 204 if "HEAD" == response.request().method() => true - case status => - Message.debug("HTTP response status: " + status + " url=" + url) - if (status == 407 /* PROXY_AUTHENTICATION_REQUIRED */ ) { - Message.warn("Your proxy requires authentication.") - } else if (status == 401) { - Message.warn( - "CLIENT ERROR: 401 Unauthorized. Check your resolvers username and password." - ) - } else if (String.valueOf(status).startsWith("4")) { - Message.verbose("CLIENT ERROR: " + response.message() + " url=" + url) - } else if (String.valueOf(status).startsWith("5")) { - Message.error("SERVER ERROR: " + response.message() + " url=" + url) - } - false - } - - private def lastModifiedTimestamp(response: Response): Long = { - val lastModifiedDate = - Option(response.headers().get("Last-Modified")).flatMap { headerValue => - Option(HttpDate.parse(headerValue)) - } - - lastModifiedDate.map(_.getTime).getOrElse(0) - } - -} diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index bc72f4bc2..3f5aedaca 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement package ivy -import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger @@ -30,8 +29,5 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) object IvyDependencyResolution { def apply(ivyConfiguration: IvyConfiguration): DependencyResolution = - apply(ivyConfiguration, CustomHttp.defaultHttpClient) - - def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): DependencyResolution = - DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration, http))) + DependencyResolution(new IvyDependencyResolution(new IvySbt(ivyConfiguration))) } diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index dc15ba7a9..784398744 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -2,7 +2,6 @@ package sbt package librarymanagement package ivy -import okhttp3.OkHttpClient import sbt.internal.librarymanagement._ import sbt.util.Logger import java.io.File @@ -36,8 +35,5 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface object IvyPublisher { def apply(ivyConfiguration: IvyConfiguration): Publisher = - apply(ivyConfiguration, CustomHttp.defaultHttpClient) - - def apply(ivyConfiguration: IvyConfiguration, http: OkHttpClient): Publisher = - Publisher(new IvyPublisher(new IvySbt(ivyConfiguration, http))) + Publisher(new IvyPublisher(new IvySbt(ivyConfiguration))) } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 59367176b..2b9a0d742 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,8 +3,8 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.15" - val scala213 = "2.13.6" + val scala212 = "2.12.16" + val scala213 = "2.13.8" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -61,6 +61,5 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % contrabandSjsonNewVersion.value } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-okhttp" % "0.5.0" - val okhttpUrlconnection = "com.squareup.okhttp3" % "okhttp-urlconnection" % "3.7.0" + val gigahorseApacheHttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" } From c896641f1cc9c81d3e552b366657878a2965ee45 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Jun 2022 23:46:55 -0400 Subject: [PATCH 0949/1030] Turn off semanticdb on CI --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 07e4fc470..54d0c8aa5 100644 --- a/build.sbt +++ b/build.sbt @@ -6,7 +6,7 @@ val _ = { //https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } -Global / semanticdbEnabled := true +Global / semanticdbEnabled := !(Global / insideCI).value Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value From 2318269dc5fd14f31ccfbb8fa8564deabc91d613 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Gonc=CC=A7alves?= Date: Sat, 25 Jun 2022 21:41:10 +0100 Subject: [PATCH 0950/1030] Add CrossVersionExtra.isBinaryCompatible utility --- .gitignore | 5 ++ .../cross/CrossVersionUtil.scala | 17 +++++++ .../librarymanagement/CrossVersionExtra.scala | 8 ++- .../librarymanagement/CrossVersionTest.scala | 49 +++++++++++++++++++ 4 files changed, 78 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 0cbd43574..99e785f4e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,9 @@ __pycache__ scripted-test/src/sbt-test/*/*/project/build.properties scripted-test/src/sbt-test/*/*/project/plugins.sbt + +.idea +.bloop +.metals +.bsp/ metals.sbt diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index fe6b107cf..b09f42ca7 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -84,6 +84,23 @@ object CrossVersionUtil { case _ => full } + // Uses the following rules: + // + // - Forwards and backwards compatibility is guaranteed for Scala 2.N.x (https://docs.scala-lang.org/overviews/core/binary-compatibility-of-scala-releases.html) + // + // - A Scala compiler in version 3.x1.y1 is able to read TASTy files produced by another compiler in version 3.x2.y2 if x1 >= x2 (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) + // + // - For non-stable Scala 3 versions, compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) + // + private[sbt] def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { + (newVersion, origVersion) match { + case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => nMin == oMin + case (ReleaseV("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt >= oMin.toInt + case (NonReleaseV_1("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt > oMin.toInt + case _ => newVersion == origVersion + } + } + def binaryScalaVersion(full: String): String = { if (ScalaArtifacts.isScala3(full)) binaryScala3Version(full) else diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 9de8605ea..a60f30325 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -9,7 +9,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { /** Compatibility with 0.13 */ @deprecated( - "use CrossVersion.disabled instead. prior to sbt 1.3.0, Diabled did not work without apply(). sbt/sbt#4977", + "use CrossVersion.disabled instead. prior to sbt 1.3.0, Disabled did not work without apply(). sbt/sbt#4977", "1.3.0" ) final val Disabled = sbt.librarymanagement.Disabled @@ -235,4 +235,10 @@ private[librarymanagement] abstract class CrossVersionFunctions { * Full sbt versions earlier than [[sbt.librarymanagement.CrossVersion.TransitionSbtVersion]] are returned as is. */ def binarySbtVersion(full: String): String = CrossVersionUtil.binarySbtVersion(full) + + /** + * Returns `true` if a project targeting version `origVersion` can run with version `newVersion`. + */ + def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = + CrossVersionUtil.isBinaryCompatibleWith(newVersion, origVersion) } diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index d47b17c14..b4e570083 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -284,6 +284,55 @@ class CrossVersionTest extends UnitSpec { patchVersion("2.11.8-X1.5-bin-extra") shouldBe Some("artefact_2.11.8-X1.5") } + "isBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true + } + it should "for (2.10.6, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true + } + it should "for (2.11.0, 2.10.5) return false" in { + isBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false + } + it should "for (3.0.0, 2.10.5) return false" in { + isBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false + } + it should "for (3.0.0, 3.1.0) return false" in { + isBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false + } + it should "for (3.1.0, 3.0.0) return true" in { + isBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true + } + it should "for (3.1.0, 3.1.1) return true" in { + isBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true + } + it should "for (3.1.1, 3.1.0) return true" in { + isBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true + } + it should "for (2.10.0-M1, 2.10.5) return true" in { + isBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + } + it should "for (2.10.5, 2.10.0-M1) return true" in { + isBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + } + it should "for (2.10.0-M1, 2.10.0-M2) return true" in { + isBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + } + it should "for (2.10.0-M1, 2.11.0-M1) return false" in { + isBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false + } + it should "for (3.1.0-M1, 3.0.0) return true" in { + isBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true + } + it should "for (3.1.0-M1, 3.1.0) return false" in { + isBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false + } + it should "for (3.1.0-M1, 3.1.0-M2) return false" in { + isBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false + } + it should "for (3.1.0-M2, 3.1.0-M1) return false" in { + isBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false + } + private def constantVersion(value: String) = CrossVersion(CrossVersion.constant(value), "dummy1", "dummy2") map (fn => fn("artefact")) From daec6265c441ba8dedfd893250b4152bd9bcbc9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rui=20Gonc=CC=A7alves?= Date: Sat, 25 Jun 2022 22:54:08 +0100 Subject: [PATCH 0951/1030] Rename function and extend support to Scala 4+ --- .../cross/CrossVersionUtil.scala | 16 ++++++--- .../librarymanagement/CrossVersionExtra.scala | 4 +-- .../librarymanagement/CrossVersionTest.scala | 34 +++++++++---------- 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index b09f42ca7..1f58cfe7d 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -92,12 +92,18 @@ object CrossVersionUtil { // // - For non-stable Scala 3 versions, compiler versions can read TASTy in an older stable format but their TASTY versions are not compatible between each other even if the compilers have the same minor version (https://docs.scala-lang.org/scala3/reference/language-versions/binary-compatibility.html) // - private[sbt] def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { + private[sbt] def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { (newVersion, origVersion) match { - case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => nMin == oMin - case (ReleaseV("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt >= oMin.toInt - case (NonReleaseV_1("3", nMin, _, _), ReleaseV("3", oMin, _, _)) => nMin.toInt > oMin.toInt - case _ => newVersion == origVersion + case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => + nMin == oMin + case (ReleaseV(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) + if nMaj == oMaj && nMaj.toLong >= 3 => + nMin.toInt >= oMin.toInt + case (NonReleaseV_1(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) + if nMaj == oMaj && nMaj.toLong >= 3 => + nMin.toInt > oMin.toInt + case _ => + newVersion == origVersion } } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index a60f30325..03cd97e88 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -239,6 +239,6 @@ private[librarymanagement] abstract class CrossVersionFunctions { /** * Returns `true` if a project targeting version `origVersion` can run with version `newVersion`. */ - def isBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = - CrossVersionUtil.isBinaryCompatibleWith(newVersion, origVersion) + def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = + CrossVersionUtil.isScalaBinaryCompatibleWith(newVersion, origVersion) } diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index b4e570083..aae585b16 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -284,53 +284,53 @@ class CrossVersionTest extends UnitSpec { patchVersion("2.11.8-X1.5-bin-extra") shouldBe Some("artefact_2.11.8-X1.5") } - "isBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true + "isScalaBinaryCompatibleWith" should "for (2.10.4, 2.10.5) return true" in { + isScalaBinaryCompatibleWith("2.10.4", "2.10.5") shouldBe true } it should "for (2.10.6, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true + isScalaBinaryCompatibleWith("2.10.6", "2.10.5") shouldBe true } it should "for (2.11.0, 2.10.5) return false" in { - isBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false + isScalaBinaryCompatibleWith("2.11.0", "2.10.5") shouldBe false } it should "for (3.0.0, 2.10.5) return false" in { - isBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false + isScalaBinaryCompatibleWith("3.0.0", "2.10.5") shouldBe false } it should "for (3.0.0, 3.1.0) return false" in { - isBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false + isScalaBinaryCompatibleWith("3.0.0", "3.1.0") shouldBe false } it should "for (3.1.0, 3.0.0) return true" in { - isBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.0", "3.0.0") shouldBe true } it should "for (3.1.0, 3.1.1) return true" in { - isBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true + isScalaBinaryCompatibleWith("3.1.0", "3.1.1") shouldBe true } it should "for (3.1.1, 3.1.0) return true" in { - isBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true } it should "for (2.10.0-M1, 2.10.5) return true" in { - isBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true } it should "for (2.10.5, 2.10.0-M1) return true" in { - isBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true } it should "for (2.10.0-M1, 2.10.0-M2) return true" in { - isBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true } it should "for (2.10.0-M1, 2.11.0-M1) return false" in { - isBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false + isScalaBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false } it should "for (3.1.0-M1, 3.0.0) return true" in { - isBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true + isScalaBinaryCompatibleWith("3.1.0-M1", "3.0.0") shouldBe true } it should "for (3.1.0-M1, 3.1.0) return false" in { - isBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M1", "3.1.0") shouldBe false } it should "for (3.1.0-M1, 3.1.0-M2) return false" in { - isBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M1", "3.1.0-M2") shouldBe false } it should "for (3.1.0-M2, 3.1.0-M1) return false" in { - isBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false + isScalaBinaryCompatibleWith("3.1.0-M2", "3.1.0-M1") shouldBe false } private def constantVersion(value: String) = From 457af6978fcfee61c618643986fa78d93a1f7b0c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 26 Jun 2022 21:05:52 -0400 Subject: [PATCH 0952/1030] Fix isScalaBinaryCompatibleWith Problem ------- Current impl is relaxed about comparing non-release Scala 2.x versions. Solutution ---------- Use scalaApiVersion to compare two Scala 2 versions. --- .../librarymanagement/cross/CrossVersionUtil.scala | 6 ++++-- .../sbt/librarymanagement/CrossVersionTest.scala | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 1f58cfe7d..8f84cad47 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -94,8 +94,10 @@ object CrossVersionUtil { // private[sbt] def isScalaBinaryCompatibleWith(newVersion: String, origVersion: String): Boolean = { (newVersion, origVersion) match { - case (NonReleaseV_n("2", nMin, _, _), NonReleaseV_n("2", oMin, _, _)) => - nMin == oMin + case (NonReleaseV_n("2", _, _, _), NonReleaseV_n("2", _, _, _)) => + val api1 = scalaApiVersion(newVersion) + val api2 = scalaApiVersion(origVersion) + (api1.isDefined && api1 == api2) || (newVersion == origVersion) case (ReleaseV(nMaj, nMin, _, _), ReleaseV(oMaj, oMin, _, _)) if nMaj == oMaj && nMaj.toLong >= 3 => nMin.toInt >= oMin.toInt diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index aae585b16..96b3d164f 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -308,14 +308,14 @@ class CrossVersionTest extends UnitSpec { it should "for (3.1.1, 3.1.0) return true" in { isScalaBinaryCompatibleWith("3.1.1", "3.1.0") shouldBe true } - it should "for (2.10.0-M1, 2.10.5) return true" in { - isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe true + it should "for (2.10.0-M1, 2.10.5) return false" in { + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.5") shouldBe false } - it should "for (2.10.5, 2.10.0-M1) return true" in { - isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe true + it should "for (2.10.5, 2.10.0-M1) return false" in { + isScalaBinaryCompatibleWith("2.10.5", "2.10.0-M1") shouldBe false } - it should "for (2.10.0-M1, 2.10.0-M2) return true" in { - isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe true + it should "for (2.10.0-M1, 2.10.0-M2) return false" in { + isScalaBinaryCompatibleWith("2.10.0-M1", "2.10.0-M2") shouldBe false } it should "for (2.10.0-M1, 2.11.0-M1) return false" in { isScalaBinaryCompatibleWith("2.10.0-M1", "2.11.0-M1") shouldBe false From 5dd056fa4dbc9f47e84449426f47c065c2985c3b Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 05:28:16 -0400 Subject: [PATCH 0953/1030] util 1.7.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 2b9a0d742..ac0f037e4 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.6.0") - private val utilVersion = nightlyVersion.getOrElse("1.6.0") + private val ioVersion = nightlyVersion.getOrElse("1.7.0") + private val utilVersion = nightlyVersion.getOrElse("1.7.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 925c461aa84c0855b104bd6672029286edc13891 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 10 Jul 2022 23:09:51 -0400 Subject: [PATCH 0954/1030] sbt 1.7.0 --- .github/workflows/ci.yml | 36 ++++++++++-------------------------- build.sbt | 2 +- project/build.properties | 2 +- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 897e165ce..6ef1c3dab 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,31 +21,15 @@ jobs: JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout - uses: actions/checkout@v1 - - name: Setup - uses: olafurpg/setup-scala@v10 + uses: actions/checkout@v3 + - name: Setup JDK + uses: actions/setup-java@v3 with: - java-version: "adopt@1.${{ matrix.java }}" - - name: Coursier cache - uses: coursier/cache-action@v5 - - name: Cache sbt - uses: actions/cache@v1 - with: - path: $HOME/.sbt - key: ${{ runner.os }}-sbt-cache-${{ hashFiles('**/*.sbt') }}-${{ hashFiles('project/build.properties') }} - - name: Build and test + distribution: temurin + java-version: "${{ matrix.java }}" + cache: sbt + - name: Build and test (1) + if: ${{ matrix.jobtype == 1 }} + shell: bash run: | - case ${{ matrix.jobtype }} in - 1) - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts - ;; - *) - echo unknown jobtype - exit 1 - esac - rm -rf "$HOME/.ivy2/local" - find $HOME/Library/Caches/Coursier/v1 -name "ivydata-*.properties" -delete || true - find $HOME/.ivy2/cache -name "ivydata-*.properties" -delete || true - find $HOME/.ivy2/cache -name "*-LM-SNAPSHOT*" -delete || true - find $HOME/.cache/coursier/v1 -name "ivydata-*.properties" -delete || true - find $HOME/.sbt -name "*.lock" -delete || true + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts diff --git a/build.sbt b/build.sbt index 54d0c8aa5..b47005ad0 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val _ = { sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value -Global / semanticdbVersion := "4.5.9" +// Global / semanticdbVersion := "4.5.9" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { diff --git a/project/build.properties b/project/build.properties index c8fcab543..5b12c1dc6 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.2 +sbt.version=1.7.0 From d2fba6fde0a616382322a92f451cb86810394fe5 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Fri, 29 Jul 2022 19:32:14 -0700 Subject: [PATCH 0955/1030] Better deprecation message for `sonatypeRepo` --- core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 0d6683a91..d80df66a2 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,7 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("Use sonatypeOssRepos instead", "1.7.0") + @deprecated("""Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", "1.7.0") def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, From f17280780dc7de5e7bd0b3c24e616f549b602d02 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Sat, 30 Jul 2022 02:51:02 +0000 Subject: [PATCH 0956/1030] Formatting --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index d80df66a2..e08b97f31 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -155,7 +155,10 @@ private[librarymanagement] abstract class ResolverFunctions { url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( ivyStylePatterns ) - @deprecated("""Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", "1.7.0") + @deprecated( + """Use sonatypeOssRepos instead e.g. `resolvers ++= Resolver.sonatypeOssRepos("snapshots")`""", + "1.7.0" + ) def sonatypeRepo(status: String) = MavenRepository( "sonatype-" + status, From b807671ec5b9b7b8379bf3a628ea5b1aac1a603c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 11 Aug 2022 23:40:40 -0400 Subject: [PATCH 0957/1030] Downgrade scala-xml to _2.13 on Scala 3 Since Coursier doesn't have Scala 3 artifacts yet, downgrade scala-xml so we can use for3Use2_13. --- build.sbt | 12 ++++++------ project/Dependencies.scala | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build.sbt b/build.sbt index c5f546833..4fcd4c253 100644 --- a/build.sbt +++ b/build.sbt @@ -12,7 +12,7 @@ ThisBuild / version := { nightlyVersion match { case Some(v) => v case _ => - if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + if ((ThisBuild / isSnapshot).value) "2.0.0-SNAPSHOT" else old } } @@ -109,7 +109,7 @@ lazy val lmRoot = (project in file(".")) ) lazy val lmCore = (project in file("core")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + // .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .settings( commonSettings, name := "librarymanagement-core", @@ -121,13 +121,13 @@ lazy val lmCore = (project in file("core")) launcherInterface, gigahorseOkhttp, okhttpUrlconnection, + scalaXml, sjsonnewScalaJson.value % Optional, sjsonnew.value % Optional, scalaTest % Test, scalaCheck % Test, scalaVerify % Test, ), - libraryDependencies += scalaXml, Compile / resourceGenerators += Def .task( Util.generateVersionFile( @@ -142,7 +142,7 @@ lazy val lmCore = (project in file("core")) case v if v.startsWith("2.12.") => List("-Ywarn-unused:-locals,-explicits,-privates") case _ => List() }), - Compile / managedSourceDirectories += + Compile / unmanagedSourceDirectories += baseDirectory.value / "src" / "main" / "contraband-scala", Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala", Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats, @@ -271,7 +271,7 @@ lazy val lmCore = (project in file("core")) .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) lazy val lmIvy = (project in file("ivy")) - .enablePlugins(ContrabandPlugin, JsonCodecPlugin) + // .enablePlugins(ContrabandPlugin, JsonCodecPlugin) .dependsOn(lmCore) .settings( commonSettings, @@ -283,7 +283,7 @@ lazy val lmIvy = (project in file("ivy")) scalaCheck % Test, scalaVerify % Test, ), - Compile / managedSourceDirectories += + Compile / unmanagedSourceDirectories += baseDirectory.value / "src" / "main" / "contraband-scala", Compile / generateContrabands / sourceManaged := baseDirectory.value / "src" / "main" / "contraband-scala", Compile / generateContrabands / contrabandFormatsForType := DatatypeConfig.getFormats, diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 48df24769..78ae999f5 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -52,8 +52,8 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.0.1" - val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" + val scalaXml = ("org.scala-lang.modules" % "scala-xml" % "2.0.1").cross(CrossVersion.for3Use2_13) + val scalaTest = ("org.scalatest" %% "scalatest" % "3.2.10").cross(CrossVersion.for3Use2_13) val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" val sjsonNewVersion = "0.10.0" From 90795c3590f54cbd566b4dff74894145a5dd1b3e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 2 Oct 2022 21:49:45 -0400 Subject: [PATCH 0958/1030] Util 1.7.1 --- build.sbt | 2 +- project/Dependencies.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index b47005ad0..b44f77bdb 100644 --- a/build.sbt +++ b/build.sbt @@ -13,7 +13,7 @@ ThisBuild / version := { nightlyVersion match { case Some(v) => v case _ => - if ((ThisBuild / isSnapshot).value) "1.4.0-SNAPSHOT" + if ((ThisBuild / isSnapshot).value) "1.7.2-SNAPSHOT" else old } } diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ac0f037e4..b990e4be6 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -10,7 +10,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.7.0") - private val utilVersion = nightlyVersion.getOrElse("1.7.0") + private val utilVersion = nightlyVersion.getOrElse("1.7.1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 07725bb6260695c78dac60d0695751c656da7d68 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 19 Oct 2022 01:31:12 -0400 Subject: [PATCH 0959/1030] sjson-new 0.11.0 --- project/Dependencies.scala | 6 +++--- project/build.properties | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 78ae999f5..30beafe34 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,13 +5,13 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.15" val scala213 = "2.13.6" - val scala3 = "3.1.0" + val scala3 = "3.1.3" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.6.0") - private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha1") + private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha3") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -56,7 +56,7 @@ object Dependencies { val scalaTest = ("org.scalatest" %% "scalatest" % "3.2.10").cross(CrossVersion.for3Use2_13) val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" - val sjsonNewVersion = "0.10.0" + val sjsonNewVersion = "0.11.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } diff --git a/project/build.properties b/project/build.properties index 3161d2146..563a014da 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.6.1 +sbt.version=1.7.2 From adc682c9266c5f1e3ff048022c9cdd8b68ca40a0 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 10:04:52 -0500 Subject: [PATCH 0960/1030] Ivy 2.3.0-sbt-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b990e4be6..e726ce267 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,7 +43,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-fbc4f586aeeb1591710b14eb4f41b94880dcd745" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e" val sbtV = "1.0" val scalaV = "2.12" From adc246ea9a6659896d11b43829d2497acd61793f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 10 Nov 2022 13:40:09 -0500 Subject: [PATCH 0961/1030] Bump io, util, and scala-xml --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e726ce267..7424830d9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,14 +3,14 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.16" + val scala212 = "2.12.17" val scala213 = "2.13.8" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.7.0") - private val utilVersion = nightlyVersion.getOrElse("1.7.1") + private val ioVersion = nightlyVersion.getOrElse("1.8.0") + private val utilVersion = nightlyVersion.getOrElse("1.8.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -51,7 +51,7 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "1.2.0" + val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.1.0" val scalaTest = "org.scalatest" %% "scalatest" % "3.2.0" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.14.0" From 5a0e9b2fe743e1159528314a039a655baf808ffe Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Fri, 23 Dec 2022 16:05:43 +0100 Subject: [PATCH 0962/1030] Try resolve sbt plugin from valid Maven pattern sbt plugins were published to an invalid path with regard to Maven's specifictation. As of sbt 1.9 we produce two POMs, a deprecated one and a new one, that is valid with regard to Maven resolution. When resolving, we first try to resolve the new valid POM and we fallback to the invalid one if needed. In the new POM format, we append the sbt cross-version to all artifactIds of sbt plugins. This is because we want Maven to be able to resolve the plugin and all its dependencies. When parsing it, we remove the cross-version suffix so that the result of parsing the valid POM format is exactly the same as parsing the deprecated POM format. Hence conflict resolution happens as intended. More details can be found at https://github.com/sbt/sbt/pull/7096 --- .../librarymanagement/ConvertResolver.scala | 41 ++++++++++- .../librarymanagement/CustomPomParser.scala | 30 +++++++- .../sbt/internal/librarymanagement/Ivy.scala | 73 +++++++++++++------ .../BaseIvySpecification.scala | 5 +- .../librarymanagement/IvyModuleSpec.scala | 38 ++++++++++ 5 files changed, 162 insertions(+), 25 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index f682a785e..94e82974a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -27,10 +27,16 @@ import org.apache.ivy.plugins.resolver.{ import org.apache.ivy.plugins.repository.url.{ URLRepository => URLRepo } import org.apache.ivy.plugins.repository.file.{ FileResource, FileRepository => FileRepo } import java.io.{ File, IOException } +import java.util.Date -import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } import org.apache.ivy.core.module.descriptor.{ Artifact => IArtifact } +import org.apache.ivy.core.module.id.ModuleRevisionId +import org.apache.ivy.core.module.descriptor.DefaultArtifact import org.apache.ivy.core.report.DownloadReport +import org.apache.ivy.plugins.resolver.util.{ ResolvedResource, ResourceMDParser } +import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } +import scala.collection.JavaConverters._ +import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes import sbt.io.IO import sbt.util.Logger import sbt.librarymanagement._ @@ -173,6 +179,32 @@ private[sbt] object ConvertResolver { setArtifactPatterns(pattern) setIvyPatterns(pattern) } + override protected def findResourceUsingPattern( + mrid: ModuleRevisionId, + pattern: String, + artifact: IArtifact, + rmdparser: ResourceMDParser, + date: Date + ): ResolvedResource = { + val extraAttributes = + mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] + getSbtPluginCrossVersion(extraAttributes) match { + case Some(sbtCrossVersion) => + // if the module is an sbt plugin + // we first try to resolve the artifact with the sbt cross version suffix + // and we fallback to the one without the suffix + val newArtifact = DefaultArtifact.cloneWithAnotherName( + artifact, + artifact.getName + sbtCrossVersion + ) + val resolved = + super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) + if (resolved != null) resolved + else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + case None => + super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + } + } } val resolver = new PluginCapableResolver if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) @@ -230,6 +262,13 @@ private[sbt] object ConvertResolver { } } + private def getSbtPluginCrossVersion(extraAttributes: Map[String, String]): Option[String] = { + for { + sbtVersion <- extraAttributes.get(PomExtraDependencyAttributes.SbtVersionKey) + scalaVersion <- extraAttributes.get(PomExtraDependencyAttributes.ScalaVersionKey) + } yield s"_${scalaVersion}_$sbtVersion" + } + private sealed trait DescriptorRequired extends BasicResolver { // Works around implementation restriction to access protected method `get` def getResource(resource: Resource, dest: File): Long diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index e81ef45cd..3ec3282f6 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -75,6 +75,31 @@ object CustomPomParser { private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey, VersionSchemeKey) + /** In the new POM format of sbt plugins, the dependency to an sbt plugin + * contains the sbt cross-version _2.12_1.0. The reason is we want Maven to be able + * to resolve the dependency using the pattern: + * /_2.12_1.0//_2.12_1.0-.pom + * In sbt 1.x we use extra-attributes to resolve sbt plugins, so here we must remove + * the sbt cross-version and keep the extra-attributes. + * Parsing a dependency found in the new POM format produces the same module as + * if it is found in the old POM format. It used not to contain the sbt cross-version + * suffix, but that was invalid. + * Hence we can resolve conflicts between new and old POM formats. + * + * To compare the two formats you can look at the POMs in: + * https://repo1.maven.org/maven2/ch/epfl/scala/sbt-plugin-example-diamond_2.12_1.0/0.5.0/ + */ + private def removeSbtCrossVersion( + properties: Map[String, String], + moduleName: String + ): String = { + val sbtCrossVersion = for { + sbtVersion <- properties.get(s"e:$SbtVersionKey") + scalaVersion <- properties.get(s"e:$ScalaVersionKey") + } yield s"_${scalaVersion}_$sbtVersion" + sbtCrossVersion.map(moduleName.stripSuffix).getOrElse(moduleName) + } + // packagings that should be jars, but that Ivy doesn't handle as jars // TODO - move this elsewhere. val JarPackagings = Set("eclipse-plugin", "hk2-jar", "orbit", "scala-jar") @@ -163,9 +188,12 @@ object CustomPomParser { import collection.JavaConverters._ val oldExtra = qualifiedExtra(id) val newExtra = (oldExtra ++ properties).asJava + // remove the sbt plugin cross version from the resolved ModuleRevisionId + // sbt-plugin-example_2.12_1.0 => sbt-plugin-example + val nameWithoutCrossVersion = removeSbtCrossVersion(properties, id.getName) ModuleRevisionId.newInstance( id.getOrganisation, - id.getName, + nameWithoutCrossVersion, id.getBranch, id.getRevision, newExtra diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index eaab99af1..270d08546 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -219,9 +219,28 @@ final class IvySbt( else IvySbt.cachedResolutionResolveCache.clean() } - final class Module(rawModuleSettings: ModuleSettings) + /** + * In the new POM format of sbt plugins, we append the sbt-cross version _2.12_1.0 to + * the module artifactId, and the artifactIds of its dependencies that are sbt plugins. + * + * The goal is to produce a valid Maven POM, a POM that Maven can resolve: + * Maven will try and succeed to resolve the POM of pattern: + * /_2.12_1.0//_2.12_1.0-.pom + */ + final class Module(rawModuleSettings: ModuleSettings, appendSbtCrossVersion: Boolean) extends sbt.librarymanagement.ModuleDescriptor { self => - val moduleSettings: ModuleSettings = IvySbt.substituteCross(rawModuleSettings) + + def this(rawModuleSettings: ModuleSettings) = + this(rawModuleSettings, appendSbtCrossVersion = false) + + val moduleSettings: ModuleSettings = + rawModuleSettings match { + case ic: InlineConfiguration => + val icWithCross = IvySbt.substituteCross(ic) + if (appendSbtCrossVersion) IvySbt.appendSbtCrossVersion(icWithCross) + else icWithCross + case m => m + } def directDependencies: Vector[ModuleID] = moduleSettings match { @@ -696,32 +715,44 @@ private[sbt] object IvySbt { ) } - private def substituteCross(m: ModuleSettings): ModuleSettings = { - m.scalaModuleInfo match { - case None => m - case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) + private def substituteCross(ic: InlineConfiguration): InlineConfiguration = { + ic.scalaModuleInfo match { + case None => ic + case Some(is) => substituteCross(ic, is.scalaFullVersion, is.scalaBinaryVersion) } } private def substituteCross( - m: ModuleSettings, + ic: InlineConfiguration, scalaFullVersion: String, scalaBinaryVersion: String - ): ModuleSettings = { - m match { - case ic: InlineConfiguration => - val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) - def propagateCrossVersion(moduleID: ModuleID): ModuleID = { - val crossExclusions: Vector[ExclusionRule] = - moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) - applyCross(moduleID) - .withExclusions(crossExclusions) - } - ic.withModule(applyCross(ic.module)) - .withDependencies(ic.dependencies.map(propagateCrossVersion)) - .withOverrides(ic.overrides map applyCross) - case _ => m + ): InlineConfiguration = { + val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) + def propagateCrossVersion(moduleID: ModuleID): ModuleID = { + val crossExclusions: Vector[ExclusionRule] = + moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) + applyCross(moduleID) + .withExclusions(crossExclusions) } + ic.withModule(applyCross(ic.module)) + .withDependencies(ic.dependencies.map(propagateCrossVersion)) + .withOverrides(ic.overrides map applyCross) + } + + private def appendSbtCrossVersion(ic: InlineConfiguration): InlineConfiguration = + ic.withModule(appendSbtCrossVersion(ic.module)) + .withDependencies(ic.dependencies.map(appendSbtCrossVersion)) + .withOverrides(ic.overrides.map(appendSbtCrossVersion)) + + private def appendSbtCrossVersion(mid: ModuleID): ModuleID = { + val crossVersion = for { + scalaVersion <- mid.extraAttributes.get("e:scalaVersion") + sbtVersion <- mid.extraAttributes.get("e:sbtVersion") + } yield s"_${scalaVersion}_$sbtVersion" + crossVersion + .filter(!mid.name.endsWith(_)) + .map(cv => mid.withName(mid.name + cv)) + .getOrElse(mid) } private def toIvyArtifact( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index f6bcba917..a1bd6d31f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -37,7 +37,8 @@ trait BaseIvySpecification extends AbstractEngineSpec { deps: Vector[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), - overrideScalaVersion: Boolean = true + overrideScalaVersion: Boolean = true, + appendSbtCrossVersion: Boolean = false ): IvySbt#Module = { val scalaModuleInfo = scalaFullVersion map { fv => ScalaModuleInfo( @@ -55,7 +56,7 @@ trait BaseIvySpecification extends AbstractEngineSpec { .withConfigurations(configurations) .withScalaModuleInfo(scalaModuleInfo) val ivySbt = new IvySbt(mkIvyConfiguration(uo)) - new ivySbt.Module(moduleSetting) + new ivySbt.Module(moduleSetting, appendSbtCrossVersion) } def resolvers: Vector[Resolver] = Vector(Resolver.mavenCentral) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala new file mode 100644 index 000000000..ac9474912 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyModuleSpec.scala @@ -0,0 +1,38 @@ +package sbt.internal.librarymanagement + +import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes.{ + SbtVersionKey, + ScalaVersionKey +} +import sbt.librarymanagement.{ CrossVersion, ModuleDescriptorConfiguration } + +object IvyModuleSpec extends BaseIvySpecification { + + test("The Scala binary version of a Scala module should be appended to its name") { + val m = module( + defaultModuleId.withCrossVersion(CrossVersion.Binary()), + Vector.empty, + Some("2.13.10") + ) + m.moduleSettings match { + case configuration: ModuleDescriptorConfiguration => + assert(configuration.module.name == "foo_2.13") + case _ => fail() + } + } + + test("The sbt cross-version should be appended to the name of an sbt plugin") { + val m = module( + defaultModuleId.extra(SbtVersionKey -> "1.0", ScalaVersionKey -> "2.12"), + Vector.empty, + Some("2.12.17"), + appendSbtCrossVersion = true + ) + m.moduleSettings match { + case configuration: ModuleDescriptorConfiguration => + assert(configuration.module.name == "foo_2.12_1.0") + case _ => fail() + } + } + +} From 286467d351e47930396faaaf5116ae66e42054df Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 19 Oct 2022 01:31:12 -0400 Subject: [PATCH 0963/1030] sjson-new 0.13.0 --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 30beafe34..87b8cab37 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,13 +5,13 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.15" val scala213 = "2.13.6" - val scala3 = "3.1.3" + val scala3 = "3.2.1" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.6.0") - private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha3") + private val ioVersion = nightlyVersion.getOrElse("1.7.0") + private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha5") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion @@ -56,7 +56,7 @@ object Dependencies { val scalaTest = ("org.scalatest" %% "scalatest" % "3.2.10").cross(CrossVersion.for3Use2_13) val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" - val sjsonNewVersion = "0.11.0" + val sjsonNewVersion = "0.13.0" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } From d2ddd9d7a98e18912187a6d1b9cec63f86950358 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 11 Aug 2022 23:40:40 -0400 Subject: [PATCH 0964/1030] Use scala-xml_3 --- project/Dependencies.scala | 4 ++-- project/build.properties | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 87b8cab37..0f165a66f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -52,8 +52,8 @@ object Dependencies { val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } - val scalaXml = ("org.scala-lang.modules" % "scala-xml" % "2.0.1").cross(CrossVersion.for3Use2_13) - val scalaTest = ("org.scalatest" %% "scalatest" % "3.2.10").cross(CrossVersion.for3Use2_13) + val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.1.0" + val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" val sjsonNewVersion = "0.13.0" diff --git a/project/build.properties b/project/build.properties index 563a014da..8b9a0b0ab 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.7.2 +sbt.version=1.8.0 From 3fa547d1b43577d48a77b49f71f6e6205632e53e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 19 Jan 2023 04:59:14 -0500 Subject: [PATCH 0965/1030] Cast module --- .../main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala index dc15ba7a9..6e0d02aa8 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyPublisher.scala @@ -29,9 +29,7 @@ class IvyPublisher private[sbt] (val ivySbt: IvySbt) extends PublisherInterface IvyActions.publish(toModule(module), configuration, log) private[sbt] def toModule(module: ModuleDescriptor): Module = - module match { - case m: Module @unchecked => m - } + module.asInstanceOf[Module] } object IvyPublisher { From 3cee90bd55c9d1dfd279c9a4a37589f51a050f03 Mon Sep 17 00:00:00 2001 From: Arman Bilge Date: Mon, 13 Feb 2023 04:05:10 +0000 Subject: [PATCH 0966/1030] Add `POM_RELEASE_NOTES_KEY` --- .../librarymanagement/mavenint/SbtPomExtraProperties.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java index 8bc61d549..b7033925c 100644 --- a/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java +++ b/core/src/main/java/sbt/internal/librarymanagement/mavenint/SbtPomExtraProperties.java @@ -14,6 +14,7 @@ public class SbtPomExtraProperties { public static final String POM_SBT_VERSION = "sbtVersion"; public static final String POM_API_KEY = "info.apiURL"; public static final String VERSION_SCHEME_KEY = "info.versionScheme"; + public static final String POM_RELEASE_NOTES_KEY = "info.releaseNotesUrl"; public static final String LICENSE_COUNT_KEY = "license.count"; From 63d3dccb9efc2b8d683dd5b0bb460fc046063789 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Sat, 18 Feb 2023 10:42:21 +0100 Subject: [PATCH 0967/1030] Add Apache Maven Snapshots Repository --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index e08b97f31..7e16ee39b 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -180,6 +180,11 @@ private[librarymanagement] abstract class ResolverFunctions { ) def jcenterRepo = JCenterRepository + val ApacheMavenSnapshotsRepo = MavenRepository( + "apache-snapshots", + "https://repository.apache.org/content/repositories/snapshots/" + ) + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) From 5581b0c31c08ec5bb706dc2c44b98f147f7c01bf Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 19 Jan 2023 04:59:14 -0500 Subject: [PATCH 0968/1030] Cast module --- .../sbt/librarymanagement/ivy/IvyDependencyResolution.scala | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala index bc72f4bc2..0b727e51f 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/IvyDependencyResolution.scala @@ -23,9 +23,7 @@ class IvyDependencyResolution private[sbt] (val ivySbt: IvySbt) IvyActions.updateEither(toModule(module), configuration, uwconfig, log) private[sbt] def toModule(module: ModuleDescriptor): Module = - module match { - case m: Module @unchecked => m - } + module.asInstanceOf[Module] } object IvyDependencyResolution { From f0c54a9fe91d6d715c54d89d3bc03d21038ef7d5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Mar 2023 00:01:48 -0500 Subject: [PATCH 0969/1030] Make some tests working --- .../sbt/librarymanagement/EvictionError.scala | 2 +- .../librarymanagement/EvictionWarning.scala | 39 +++++++++---------- .../ComponentManagerTest.scala | 3 ++ .../librarymanagement/CredentialsSpec.scala | 2 +- .../librarymanagement/EvictionErrorSpec.scala | 3 +- .../EvictionWarningSpec.scala | 3 +- .../librarymanagement/ResolutionSpec.scala | 7 ++-- .../librarymanagement/ScalaOverrideTest.scala | 2 + .../librarymanagement/TestShowLInes.scala | 9 +++++ 9 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/TestShowLInes.scala diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 01fcb3bc5..c2fab10c3 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -135,7 +135,7 @@ object EvictionError { ) } - implicit val evictionErrorLines: ShowLines[EvictionError] = ShowLines { (a: EvictionError) => + given evictionErrorLines: ShowLines[EvictionError] = ShowLines { (a: EvictionError) => a.toLines } } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index 33899306a..98cbe008e 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -394,29 +394,28 @@ object EvictionWarning { ) } - implicit val evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { - (a: EvictionWarning) => - import ShowLines._ - val out: mutable.ListBuffer[String] = mutable.ListBuffer() - if (a.options.warnEvictionSummary && a.binaryIncompatibleEvictionExists) { - out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." - } + given evictionWarningLines: ShowLines[EvictionWarning] = ShowLines { (a: EvictionWarning) => + import ShowLines._ + val out: mutable.ListBuffer[String] = mutable.ListBuffer() + if (a.options.warnEvictionSummary && a.binaryIncompatibleEvictionExists) { + out += "There may be incompatibilities among your library dependencies; run 'evicted' to see detailed eviction warnings." + } - if (a.scalaEvictions.nonEmpty) { - out += "Scala version was updated by one of library dependencies:" - out ++= (a.scalaEvictions flatMap { _.lines }) - out += "To force scalaVersion, add the following:" - out += "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" - } + if (a.scalaEvictions.nonEmpty) { + out += "Scala version was updated by one of library dependencies:" + out ++= (a.scalaEvictions flatMap { _.lines }) + out += "To force scalaVersion, add the following:" + out += "\tscalaModuleInfo ~= (_.map(_.withOverrideScalaVersion(true)))" + } - if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { - out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" - out += "" - out ++= (a.directEvictions flatMap { _.lines }) - out ++= (a.transitiveEvictions flatMap { _.lines }) - } + if (a.directEvictions.nonEmpty || a.transitiveEvictions.nonEmpty) { + out += "Found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" + out += "" + out ++= (a.directEvictions flatMap { _.lines }) + out ++= (a.transitiveEvictions flatMap { _.lines }) + } - out.toList + out.toList } private[sbt] def infoAllTheThings(a: EvictionWarning): List[String] = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index 15a68f70e..f7e392aa8 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -15,6 +15,8 @@ import verify.BasicTestSuite object ComponentManagerTest extends BasicTestSuite { val TestID = "manager-test" + + /* test( "Component manager should throw an exception if 'file' is called for a non-existing component" ) { @@ -166,4 +168,5 @@ object ComponentManagerTest extends BasicTestSuite { f(mgr) } } + */ } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala index 13189de5b..101991df4 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -19,7 +19,7 @@ class CredentialsSpec extends AnyFunSuite { Files.write(credentialsFile.toPath(), content.getBytes()) - val Right(credentials) = Credentials.loadCredentials(credentialsFile) + val Right(credentials) = Credentials.loadCredentials(credentialsFile): @unchecked assert(credentials.realm == null) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index 5e67681ea..6b864a2ca 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -8,7 +8,8 @@ import sbt.util.Level object EvictionErrorSpec extends BaseIvySpecification { // This is a specification to check the eviction errors - import sbt.util.ShowLines._ + import TestShowLines.* + import EvictionError.given test("Eviction error should detect binary incompatible Scala libraries") { val deps = Vector(`scala2.10.4`, `akkaActor2.1.4`, `akkaActor2.3.0`) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 4f8ded23f..0dedc0d14 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -7,7 +7,8 @@ import sbt.librarymanagement.syntax._ object EvictionWarningSpec extends BaseIvySpecification { // This is a specification to check the eviction warnings - import sbt.util.ShowLines._ + import TestShowLines.* + def scalaVersionDeps = Vector(scala2102, akkaActor230) test("Eviction of non-overridden scala-library whose scalaVersion should be detected") { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala index 6b8fc49bc..e7f1aefee 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolutionSpec.scala @@ -6,7 +6,8 @@ import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ abstract class ResolutionSpec extends AbstractEngineSpec { - import ShowLines._ + + import TestShowLines.* test("Resolving the same module twice should work") { cleanCache() @@ -93,11 +94,11 @@ abstract class ResolutionSpec extends AbstractEngineSpec { Some("2.12.3") ) assert( - update(module013).configurations.head.modules.map(_.toString).loneElement + update(module013).configurations.head.modules.map(_.toString) contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.10, sbtVersion=0.13)" ) assert( - update(module10).configurations.head.modules.map(_.toString).loneElement + update(module10).configurations.head.modules.map(_.toString) contains "com.github.gseitz:sbt-release:1.0.6 (scalaVersion=2.12, sbtVersion=1.0)" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala index 37a82432f..7f9289e81 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ScalaOverrideTest.scala @@ -9,6 +9,7 @@ import sbt.librarymanagement.ScalaArtifacts._ import verify.BasicTestSuite object ScalaOverrideTest extends BasicTestSuite { + /* val OtherOrgID = "other.org" private val scalaConfigs = @@ -271,4 +272,5 @@ object ScalaOverrideTest extends BasicTestSuite { "3.0.0" ) } + */ } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/TestShowLInes.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/TestShowLInes.scala new file mode 100644 index 000000000..8e318ff53 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/TestShowLInes.scala @@ -0,0 +1,9 @@ +package sbt.internal.librarymanagement + +import sbt.util.ShowLines + +object TestShowLines: + extension [A: ShowLines](a: A) + inline def lines: Seq[String] = + implicitly[ShowLines[A]].showLines(a) +end TestShowLines From 47ef80eadfca10c65e9bb004b6a4efa729337c06 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Mar 2023 00:01:32 -0500 Subject: [PATCH 0970/1030] Subsume platform cross building Problem In sbt 1, platform cross building is implemented using in the user-land using `%%%` operator, which clevery handles both Scala cross building and appending platform suffix like sjs1. However, in general symbolic `%%%` is confusing, and hard to explain. Solution In sbt 2, we should subsume the idea of platform cross building, so `%%` can act as the current `%%%` operator. This adds a new field called `platformOpt` to `ModuleID`, which by default will be set to `None`. `ScalaModuleInfo` will also add a new field called `platform`, which can be set to `None`, `Some(sjs1)` etc. As part of module transformation (like adding `_2.13`), the library management engine can transform `ModuleID` to `sjs1` etc. `("com.github.scopt" %% "scopt" % "4.1.0").platform(jvm)` will explicitly use the JVM version of dependency (equivalent to today's `%%`). --- .../sbt/librarymanagement/ModuleID.scala | 18 +++-- .../librarymanagement/ModuleIDFormats.scala | 4 +- .../librarymanagement/ScalaModuleInfo.scala | 20 ++++-- .../ScalaModuleInfoFormats.scala | 4 +- .../main/contraband/librarymanagement.json | 11 ++- .../sbt/librarymanagement/ModuleIDExtra.scala | 3 + .../sbt/librarymanagement/Platform.scala | 7 ++ .../sbt/internal/librarymanagement/Ivy.scala | 33 ++++++--- .../BaseIvySpecification.scala | 6 +- .../PlatformResolutionSpec.scala | 70 +++++++++++++++++++ 10 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 core/src/main/scala/sbt/librarymanagement/Platform.scala create mode 100644 ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala index 49ef7ff34..ed282ac6e 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleID.scala @@ -17,22 +17,24 @@ final class ModuleID private ( val exclusions: Vector[sbt.librarymanagement.InclExclRule], val extraAttributes: Map[String, String], val crossVersion: sbt.librarymanagement.CrossVersion, - val branchName: Option[String]) extends sbt.librarymanagement.ModuleIDExtra with Serializable { + val branchName: Option[String], + val platformOpt: Option[String]) extends sbt.librarymanagement.ModuleIDExtra with Serializable { - private def this(organization: String, name: String, revision: String) = this(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None) + private def this(organization: String, name: String, revision: String) = this(organization, name, revision, None, false, true, false, Vector.empty, Vector.empty, Vector.empty, Map.empty, sbt.librarymanagement.Disabled(), None, None) + private def this(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, isForce: Boolean, explicitArtifacts: Vector[sbt.librarymanagement.Artifact], inclusions: Vector[sbt.librarymanagement.InclExclRule], exclusions: Vector[sbt.librarymanagement.InclExclRule], extraAttributes: Map[String, String], crossVersion: sbt.librarymanagement.CrossVersion, branchName: Option[String]) = this(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: ModuleID => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.configurations == x.configurations) && (this.isChanging == x.isChanging) && (this.isTransitive == x.isTransitive) && (this.isForce == x.isForce) && (this.explicitArtifacts == x.explicitArtifacts) && (this.inclusions == x.inclusions) && (this.exclusions == x.exclusions) && (this.extraAttributes == x.extraAttributes) && (this.crossVersion == x.crossVersion) && (this.branchName == x.branchName) + case x: ModuleID => (this.organization == x.organization) && (this.name == x.name) && (this.revision == x.revision) && (this.configurations == x.configurations) && (this.isChanging == x.isChanging) && (this.isTransitive == x.isTransitive) && (this.isForce == x.isForce) && (this.explicitArtifacts == x.explicitArtifacts) && (this.inclusions == x.inclusions) && (this.exclusions == x.exclusions) && (this.extraAttributes == x.extraAttributes) && (this.crossVersion == x.crossVersion) && (this.branchName == x.branchName) && (this.platformOpt == x.platformOpt) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ModuleID".##) + organization.##) + name.##) + revision.##) + configurations.##) + isChanging.##) + isTransitive.##) + isForce.##) + explicitArtifacts.##) + inclusions.##) + exclusions.##) + extraAttributes.##) + crossVersion.##) + branchName.##) + platformOpt.##) } override def toString: String = { this.toStringImpl } - private[this] def copy(organization: String = organization, name: String = name, revision: String = revision, configurations: Option[String] = configurations, isChanging: Boolean = isChanging, isTransitive: Boolean = isTransitive, isForce: Boolean = isForce, explicitArtifacts: Vector[sbt.librarymanagement.Artifact] = explicitArtifacts, inclusions: Vector[sbt.librarymanagement.InclExclRule] = inclusions, exclusions: Vector[sbt.librarymanagement.InclExclRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion, branchName: Option[String] = branchName): ModuleID = { - new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) + private[this] def copy(organization: String = organization, name: String = name, revision: String = revision, configurations: Option[String] = configurations, isChanging: Boolean = isChanging, isTransitive: Boolean = isTransitive, isForce: Boolean = isForce, explicitArtifacts: Vector[sbt.librarymanagement.Artifact] = explicitArtifacts, inclusions: Vector[sbt.librarymanagement.InclExclRule] = inclusions, exclusions: Vector[sbt.librarymanagement.InclExclRule] = exclusions, extraAttributes: Map[String, String] = extraAttributes, crossVersion: sbt.librarymanagement.CrossVersion = crossVersion, branchName: Option[String] = branchName, platformOpt: Option[String] = platformOpt): ModuleID = { + new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName, platformOpt) } def withOrganization(organization: String): ModuleID = { copy(organization = organization) @@ -73,9 +75,13 @@ final class ModuleID private ( def withBranchName(branchName: Option[String]): ModuleID = { copy(branchName = branchName) } + def withPlatformOpt(platformOpt: Option[String]): ModuleID = { + copy(platformOpt = platformOpt) + } } object ModuleID extends sbt.librarymanagement.ModuleIDFunctions { def apply(organization: String, name: String, revision: String): ModuleID = new ModuleID(organization, name, revision) def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, isForce: Boolean, explicitArtifacts: Vector[sbt.librarymanagement.Artifact], inclusions: Vector[sbt.librarymanagement.InclExclRule], exclusions: Vector[sbt.librarymanagement.InclExclRule], extraAttributes: Map[String, String], crossVersion: sbt.librarymanagement.CrossVersion, branchName: Option[String]): ModuleID = new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) + def apply(organization: String, name: String, revision: String, configurations: Option[String], isChanging: Boolean, isTransitive: Boolean, isForce: Boolean, explicitArtifacts: Vector[sbt.librarymanagement.Artifact], inclusions: Vector[sbt.librarymanagement.InclExclRule], exclusions: Vector[sbt.librarymanagement.InclExclRule], extraAttributes: Map[String, String], crossVersion: sbt.librarymanagement.CrossVersion, branchName: Option[String], platformOpt: Option[String]): ModuleID = new ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName, platformOpt) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala index bb0df05a5..62e93e147 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleIDFormats.scala @@ -24,8 +24,9 @@ implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = n val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val crossVersion = unbuilder.readField[sbt.librarymanagement.CrossVersion]("crossVersion") val branchName = unbuilder.readField[Option[String]]("branchName") + val platformOpt = unbuilder.readField[Option[String]]("platformOpt") unbuilder.endObject() - sbt.librarymanagement.ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName) + sbt.librarymanagement.ModuleID(organization, name, revision, configurations, isChanging, isTransitive, isForce, explicitArtifacts, inclusions, exclusions, extraAttributes, crossVersion, branchName, platformOpt) case None => deserializationError("Expected JsObject but found None") } @@ -45,6 +46,7 @@ implicit lazy val ModuleIDFormat: JsonFormat[sbt.librarymanagement.ModuleID] = n builder.addField("extraAttributes", obj.extraAttributes) builder.addField("crossVersion", obj.crossVersion) builder.addField("branchName", obj.branchName) + builder.addField("platformOpt", obj.platformOpt) builder.endObject() } } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala index 772d7b9ee..0e4db8751 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfo.scala @@ -12,22 +12,24 @@ final class ScalaModuleInfo private ( val filterImplicit: Boolean, val overrideScalaVersion: Boolean, val scalaOrganization: String, - val scalaArtifacts: scala.Vector[String]) extends Serializable { + val scalaArtifacts: scala.Vector[String], + val platform: Option[String]) extends Serializable { - private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts) + private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, sbt.librarymanagement.ScalaArtifacts.Organization, sbt.librarymanagement.ScalaArtifacts.Artifacts, None) + private def this(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]) = this(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: ScalaModuleInfo => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) + case x: ScalaModuleInfo => (this.scalaFullVersion == x.scalaFullVersion) && (this.scalaBinaryVersion == x.scalaBinaryVersion) && (this.configurations == x.configurations) && (this.checkExplicit == x.checkExplicit) && (this.filterImplicit == x.filterImplicit) && (this.overrideScalaVersion == x.overrideScalaVersion) && (this.scalaOrganization == x.scalaOrganization) && (this.scalaArtifacts == x.scalaArtifacts) && (this.platform == x.platform) case _ => false }) override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) + 37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.librarymanagement.ScalaModuleInfo".##) + scalaFullVersion.##) + scalaBinaryVersion.##) + configurations.##) + checkExplicit.##) + filterImplicit.##) + overrideScalaVersion.##) + scalaOrganization.##) + scalaArtifacts.##) + platform.##) } override def toString: String = { - "ScalaModuleInfo(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ")" + "ScalaModuleInfo(" + scalaFullVersion + ", " + scalaBinaryVersion + ", " + configurations + ", " + checkExplicit + ", " + filterImplicit + ", " + overrideScalaVersion + ", " + scalaOrganization + ", " + scalaArtifacts + ", " + platform + ")" } - private[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts): ScalaModuleInfo = { - new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + private[this] def copy(scalaFullVersion: String = scalaFullVersion, scalaBinaryVersion: String = scalaBinaryVersion, configurations: Vector[sbt.librarymanagement.Configuration] = configurations, checkExplicit: Boolean = checkExplicit, filterImplicit: Boolean = filterImplicit, overrideScalaVersion: Boolean = overrideScalaVersion, scalaOrganization: String = scalaOrganization, scalaArtifacts: scala.Vector[String] = scalaArtifacts, platform: Option[String] = platform): ScalaModuleInfo = { + new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts, platform) } def withScalaFullVersion(scalaFullVersion: String): ScalaModuleInfo = { copy(scalaFullVersion = scalaFullVersion) @@ -53,9 +55,13 @@ final class ScalaModuleInfo private ( def withScalaArtifacts(scalaArtifacts: scala.Vector[String]): ScalaModuleInfo = { copy(scalaArtifacts = scalaArtifacts) } + def withPlatform(platform: Option[String]): ScalaModuleInfo = { + copy(platform = platform) + } } object ScalaModuleInfo { def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion) def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String]): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + def apply(scalaFullVersion: String, scalaBinaryVersion: String, configurations: Vector[sbt.librarymanagement.Configuration], checkExplicit: Boolean, filterImplicit: Boolean, overrideScalaVersion: Boolean, scalaOrganization: String, scalaArtifacts: scala.Vector[String], platform: Option[String]): ScalaModuleInfo = new ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts, platform) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala index 8977be68d..2c2602605 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScalaModuleInfoFormats.scala @@ -19,8 +19,9 @@ implicit lazy val ScalaModuleInfoFormat: JsonFormat[sbt.librarymanagement.ScalaM val overrideScalaVersion = unbuilder.readField[Boolean]("overrideScalaVersion") val scalaOrganization = unbuilder.readField[String]("scalaOrganization") val scalaArtifacts = unbuilder.readField[scala.Vector[String]]("scalaArtifacts") + val platform = unbuilder.readField[Option[String]]("platform") unbuilder.endObject() - sbt.librarymanagement.ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts) + sbt.librarymanagement.ScalaModuleInfo(scalaFullVersion, scalaBinaryVersion, configurations, checkExplicit, filterImplicit, overrideScalaVersion, scalaOrganization, scalaArtifacts, platform) case None => deserializationError("Expected JsObject but found None") } @@ -35,6 +36,7 @@ implicit lazy val ScalaModuleInfoFormat: JsonFormat[sbt.librarymanagement.ScalaM builder.addField("overrideScalaVersion", obj.overrideScalaVersion) builder.addField("scalaOrganization", obj.scalaOrganization) builder.addField("scalaArtifacts", obj.scalaArtifacts) + builder.addField("platform", obj.platform) builder.endObject() } } diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 59767a820..6b210d34c 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -294,7 +294,13 @@ { "name": "filterImplicit", "type": "boolean" }, { "name": "overrideScalaVersion", "type": "boolean" }, { "name": "scalaOrganization", "type": "String", "default": "sbt.librarymanagement.ScalaArtifacts.Organization", "since": "0.0.1" }, - { "name": "scalaArtifacts", "type": "scala.Vector[String]", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" } + { "name": "scalaArtifacts", "type": "scala.Vector[String]", "default": "sbt.librarymanagement.ScalaArtifacts.Artifacts", "since": "0.0.1" }, + { + "name": "platform", + "type": "Option[String]", + "default": "None", + "since": "2.0.0" + } ] }, { @@ -332,7 +338,8 @@ { "name": "exclusions", "type": "sbt.librarymanagement.InclExclRule*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "crossVersion", "type": "sbt.librarymanagement.CrossVersion", "default": "sbt.librarymanagement.Disabled()", "since": "0.0.1" }, - { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" } + { "name": "branchName", "type": "Option[String]", "default": "None", "since": "0.0.1" }, + { "name": "platformOpt", "type": "Option[String]", "default": "None", "since": "2.0.0" } ], "toString": [ "this.toStringImpl" diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 022d919de..94aeba123 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -33,6 +33,7 @@ private[librarymanagement] abstract class ModuleIDExtra { def withExtraAttributes(extraAttributes: Map[String, String]): ModuleID def withCrossVersion(crossVersion: CrossVersion): ModuleID def withBranchName(branchName: Option[String]): ModuleID + def withPlatformOpt(platformOpt: Option[String]): ModuleID protected def toStringImpl: String = s"""$organization:$name:$revision""" + @@ -205,6 +206,8 @@ private[librarymanagement] abstract class ModuleIDExtra { def branch(branchName: String): ModuleID = withBranchName(Some(branchName)) def branch(branchName: Option[String]): ModuleID = withBranchName(branchName) + + def platform(platform: String): ModuleID = withPlatformOpt(Some(platform)) } private[librarymanagement] abstract class ModuleIDFunctions { diff --git a/core/src/main/scala/sbt/librarymanagement/Platform.scala b/core/src/main/scala/sbt/librarymanagement/Platform.scala new file mode 100644 index 000000000..3a9555686 --- /dev/null +++ b/core/src/main/scala/sbt/librarymanagement/Platform.scala @@ -0,0 +1,7 @@ +package sbt.librarymanagement + +object Platform: + val sjs1: String = "sjs1" + val jvm: String = "jvm" + val native0_4: String = "native0.4" +end Platform diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 78b31d531..c8e4d3592 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -40,6 +40,7 @@ import scala.collection.mutable import scala.util.{ Success, Failure } import sbt.util._ import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } +import sbt.librarymanagement.Platform import sbt.librarymanagement.ivy._ import sbt.librarymanagement.syntax._ @@ -706,29 +707,45 @@ private[sbt] object IvySbt { private def substituteCross(m: ModuleSettings): ModuleSettings = { m.scalaModuleInfo match { case None => m - case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion) + case Some(is) => substituteCross(m, is.scalaFullVersion, is.scalaBinaryVersion, is.platform) } } private def substituteCross( m: ModuleSettings, scalaFullVersion: String, - scalaBinaryVersion: String - ): ModuleSettings = { + scalaBinaryVersion: String, + platform: Option[String], + ): ModuleSettings = m match { case ic: InlineConfiguration => - val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) + val applyPlatform: ModuleID => ModuleID = substitutePlatform(platform) + val transform: ModuleID => ModuleID = (m: ModuleID) => + val applyCross = CrossVersion(scalaFullVersion, scalaBinaryVersion) + applyCross(applyPlatform(m)) def propagateCrossVersion(moduleID: ModuleID): ModuleID = { val crossExclusions: Vector[ExclusionRule] = - moduleID.exclusions.map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) - applyCross(moduleID) + moduleID.exclusions + .map(CrossVersion.substituteCross(_, ic.scalaModuleInfo)) + transform(moduleID) .withExclusions(crossExclusions) } - ic.withModule(applyCross(ic.module)) + ic.withModule(transform(ic.module)) .withDependencies(ic.dependencies.map(propagateCrossVersion)) - .withOverrides(ic.overrides map applyCross) + .withOverrides(ic.overrides map transform) case _ => m } + + private def substitutePlatform(platform: Option[String]): ModuleID => ModuleID = { + def addSuffix(m: ModuleID, platformName: String): ModuleID = + platformName match + case "" | Platform.jvm => m + case _ => m.withName(s"${m.name}_$platformName") + (m: ModuleID) => + (platform, m.platformOpt) match + case (Some(p), None) => addSuffix(m, p) + case (_, Some(p)) => addSuffix(m, p) + case _ => m } private def toIvyArtifact( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala index f6bcba917..c9de27b3a 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/BaseIvySpecification.scala @@ -18,6 +18,8 @@ trait BaseIvySpecification extends AbstractEngineSpec { def defaultModuleId: ModuleID = ModuleID("com.example", "foo", "0.1.0").withConfigurations(Some("compile")) + def scala2_13 = "2.13.10" + lazy val log = ConsoleLogger() def lmEngine(uo: UpdateOptions = UpdateOptions()): DependencyResolution = IvyDependencyResolution(mkIvyConfiguration(uo)) @@ -37,7 +39,8 @@ trait BaseIvySpecification extends AbstractEngineSpec { deps: Vector[ModuleID], scalaFullVersion: Option[String], uo: UpdateOptions = UpdateOptions(), - overrideScalaVersion: Boolean = true + overrideScalaVersion: Boolean = true, + platform: Option[String] = None, ): IvySbt#Module = { val scalaModuleInfo = scalaFullVersion map { fv => ScalaModuleInfo( @@ -48,6 +51,7 @@ trait BaseIvySpecification extends AbstractEngineSpec { filterImplicit = false, overrideScalaVersion = overrideScalaVersion ) + .withPlatform(platform) } val moduleSetting: ModuleSettings = ModuleDescriptorConfiguration(moduleId, ModuleInfo("foo")) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala new file mode 100644 index 000000000..2d40e0147 --- /dev/null +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala @@ -0,0 +1,70 @@ +package sbt.internal.librarymanagement + +import sbt.util.ShowLines +import sbt.librarymanagement.* +import sbt.librarymanagement.syntax.* +import sbt.librarymanagement.Platform.* + +object PlatformResolutionSpec extends BaseIvySpecification { + + import TestShowLines.* + + test("None platform resolves %% as JVM") { + cleanCache() + val m = exampleAutoModule(platform = None) + assert( + update(m).configurations.head.modules.map(_.toString).mkString + contains "com.github.scopt:scopt_2.13:4.1.0" + ) + } + + test("sjs1 platform resolves %% as sjs1") { + cleanCache() + val m = exampleAutoModule(platform = Some("sjs1")) + assert( + update(m).configurations.head.modules.map(_.toString).mkString + contains "com.github.scopt:scopt_sjs1_2.13" + ) + } + + test("None platform can specify .platform(sjs1) depenency") { + cleanCache() + val m = module( + exampleModuleId("0.6.0"), + deps = Vector(scopt.platform(sjs1)), + Some(scala2_13), + platform = None, + ) + assert( + update(m).configurations.head.modules.map(_.toString).mkString + contains "com.github.scopt:scopt_sjs1_2.13" + ) + } + + test("sjs1 platform can specify .platform(jvm) depenency") { + cleanCache() + val m = module( + exampleModuleId("0.6.0"), + deps = Vector(scopt.platform(jvm)), + Some(scala2_13), + platform = None, + ) + assert( + update(m).configurations.head.modules.map(_.toString).mkString + contains "com.github.scopt:scopt_2.13:4.1.0" + ) + } + + def exampleAutoModule(platform: Option[String]): ModuleDescriptor = module( + exampleModuleId("0.6.0"), + deps = Vector(scopt), + Some(scala2_13), + platform = platform, + ) + + def exampleModuleId(v: String): ModuleID = ("com.example" % "foo" % v % Compile) + def scopt = ("com.github.scopt" %% "scopt" % "4.1.0" % Compile) + override val resolvers = Vector( + Resolver.mavenCentral, + ) +} From 6fee91bbffbdfa9bbecdc5e58b3ec9a3ed632fa1 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 12 Mar 2023 19:06:18 -0400 Subject: [PATCH 0971/1030] Don't apply platform substitution to % --- .../librarymanagement/ScalaArtifacts.scala | 22 +++++++++++-------- .../sbt/internal/librarymanagement/Ivy.scala | 11 ++++++---- .../PlatformResolutionSpec.scala | 15 +++++++++++++ 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala index 82c454e24..3dc2b71c4 100644 --- a/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala +++ b/core/src/main/scala/sbt/librarymanagement/ScalaArtifacts.scala @@ -57,12 +57,12 @@ object ScalaArtifacts { def libraryDependency(version: String): ModuleID = libraryDependency(Organization, version) - def libraryDependency(org: String, version: String): ModuleID = { - if (isScala3(version)) - ModuleID(org, Scala3LibraryID, version).withCrossVersion(CrossVersion.binary) - else - ModuleID(org, LibraryID, version) - } + def libraryDependency(org: String, version: String): ModuleID = + if isScala3(version) then + ModuleID(org, Scala3LibraryID, version) + .withCrossVersion(CrossVersion.binary) + .platform(Platform.jvm) + else ModuleID(org, LibraryID, version).platform(Platform.jvm) private[sbt] def docToolDependencies( org: String, @@ -79,6 +79,7 @@ object ScalaArtifacts { ModuleID(org, ScaladocID, version) .withConfigurations(Some(Configurations.ScalaDocTool.name + "->default(compile)")) .withCrossVersion(CrossVersion.binary) + .platform(Platform.jvm) ) else Seq.empty @@ -91,6 +92,7 @@ object ScalaArtifacts { ModuleID(org, Scala3CompilerID, version) .withConfigurations(Some(Configurations.ScalaTool.name + "->default(compile)")) .withCrossVersion(CrossVersion.binary) + .platform(Platform.jvm) ) else Seq( @@ -99,9 +101,11 @@ object ScalaArtifacts { ) private[this] def scala2ToolDependency(org: String, id: String, version: String): ModuleID = - ModuleID(org, id, version).withConfigurations( - Some(Configurations.ScalaTool.name + "->default,optional(default)") - ) + ModuleID(org, id, version) + .withConfigurations( + Some(Configurations.ScalaTool.name + "->default,optional(default)") + ) + .platform(Platform.jvm) } object SbtArtifacts { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index c8e4d3592..4f2de8e1c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -742,10 +742,13 @@ private[sbt] object IvySbt { case "" | Platform.jvm => m case _ => m.withName(s"${m.name}_$platformName") (m: ModuleID) => - (platform, m.platformOpt) match - case (Some(p), None) => addSuffix(m, p) - case (_, Some(p)) => addSuffix(m, p) - case _ => m + m.crossVersion match + case _: Disabled => m + case _ => + (platform, m.platformOpt) match + case (Some(p), None) => addSuffix(m, p) + case (_, Some(p)) => addSuffix(m, p) + case _ => m } private def toIvyArtifact( diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala index 2d40e0147..39cc3d8c7 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/PlatformResolutionSpec.scala @@ -27,6 +27,20 @@ object PlatformResolutionSpec extends BaseIvySpecification { ) } + test("sjs1 platform resolves % as JVM") { + cleanCache() + val m = module( + exampleModuleId("0.6.0"), + deps = Vector(junit), + Some(scala2_13), + platform = Some(sjs1), + ) + assert( + update(m).configurations.head.modules.map(_.toString).mkString + contains "junit:junit:4.13.1" + ) + } + test("None platform can specify .platform(sjs1) depenency") { cleanCache() val m = module( @@ -64,6 +78,7 @@ object PlatformResolutionSpec extends BaseIvySpecification { def exampleModuleId(v: String): ModuleID = ("com.example" % "foo" % v % Compile) def scopt = ("com.github.scopt" %% "scopt" % "4.1.0" % Compile) + def junit = ("junit" % "junit" % "4.13.1" % Compile) override val resolvers = Vector( Resolver.mavenCentral, ) From e8cce49ba622c88059477b0c34c182b96e08c6d2 Mon Sep 17 00:00:00 2001 From: Nicolas Rinaudo Date: Sun, 9 Apr 2023 15:46:23 +0200 Subject: [PATCH 0972/1030] Expand properties found in maven settings --- .../sbt/librarymanagement/ResolverExtra.scala | 13 +++++- .../librarymanagement/ResolverExtraTest.scala | 43 +++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 7e16ee39b..10dd77e8f 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -391,6 +391,17 @@ private[librarymanagement] abstract class ResolverFunctions { def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" + private[librarymanagement] def expandMavenSettings(str: String): String = { + // Aren't regular expressions beautifully clear and concise. + // This means "find all ${...}" blocks, with the first group of each being the text between curly brackets. + val findQuoted = "\\$\\{([^\\}]*)\\}".r + val env = "env\\.(.*)".r + + findQuoted.replaceAllIn(str, _.group(1) match { + case env(variable) => sys.env.getOrElse(variable, "") + case property => sys.props.getOrElse(property, "") + }) + } private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { @@ -399,7 +410,7 @@ private[librarymanagement] abstract class ResolverFunctions { else ((XML.loadFile(file) \ "localRepository").text match { case "" => None - case e @ _ => Some(new File(e)) + case e @ _ => Some(new File(expandMavenSettings(e))) }) } catch { // Occurs inside File constructor when property or environment variable does not exist diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala new file mode 100644 index 000000000..10cad9012 --- /dev/null +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -0,0 +1,43 @@ +package sbt.librarymanagement + +import verify.BasicTestSuite +import scala.annotation.nowarn + +@nowarn // Necessary because our test cases look like interpolated strings. +object ResolverExtraTest extends BasicTestSuite { + test("expandMavenSettings should expand existing environment variables") { + assertExpansion( + input = "User home: ${env.HOME}", + expected = s"User home: ${env("HOME")}" + ) + } + + test("expandMavenSettings should expand existing system properties") { + assertExpansion( + input = "User dir: ${user.dir}", + expected = s"User dir: ${prop("user.dir")}" + ) + } + + test("expandMavenSettings should expand unknown system properties to the empty string") { + assertExpansion( + input = "Unknown system property: ${IF_THIS_EXISTS_WE_NEED_TO_HAVE_A_CHAT}", + expected = s"Unknown system property: " + ) + } + + test("expandMavenSettings should expand unknown environment variables to the empty string") { + assertExpansion( + input = "Unknown environment variable: ${IF_THIS_EXISTS_I_WORRY_ABOUT_YOU}", + expected = s"Unknown environment variable: " + ) + } + + // - Helper functions ---------------------------------------------------------------------------- + // ----------------------------------------------------------------------------------------------- + def assertExpansion(input: String, expected: String) = + assert(Resolver.expandMavenSettings(input) == s"$expected") + + def env(name: String) = sys.env.getOrElse(name, "") + def prop(name: String) = sys.props.getOrElse(name, "") +} From 7d052bde8f7944e9f949fd4688e37fb77e1d1d3d Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 24 Apr 2023 00:23:43 -0400 Subject: [PATCH 0973/1030] Deprecate IntegrationTest We plan to remove IntegrationTest configuration. See https://eed3si9n.com/sbt-drop-custom-config/ for details. --- .../scala/sbt/librarymanagement/ConfigurationExtra.scala | 6 +++++- .../sbt/librarymanagement/LibraryManagementSyntax.scala | 1 + project/build.properties | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala index 7431e8950..ecdd2d875 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConfigurationExtra.scala @@ -3,7 +3,7 @@ */ package sbt.librarymanagement -import scala.annotation.tailrec +import scala.annotation.{ nowarn, tailrec } import scala.language.experimental.macros object Configurations { @@ -19,9 +19,11 @@ object Configurations { lazy val RuntimeInternal = optionalInternal(Runtime) lazy val TestInternal = fullInternal(Test) + @nowarn lazy val IntegrationTestInternal = fullInternal(IntegrationTest) lazy val CompileInternal = fullInternal(Compile) + @nowarn def internalMap(c: Configuration) = c match { case Compile => CompileInternal case Test => TestInternal @@ -39,6 +41,7 @@ object Configurations { lazy val Default = Configuration.of("Default", "default") lazy val Compile = Configuration.of("Compile", "compile") + @deprecated("Create a separate subproject for testing instead", "1.9.0") lazy val IntegrationTest = Configuration.of("IntegrationTest", "it") extend (Runtime) lazy val Provided = Configuration.of("Provided", "provided") lazy val Runtime = Configuration.of("Runtime", "runtime") extend (Compile) @@ -67,6 +70,7 @@ object Configurations { ) /** Returns true if the configuration should be under the influence of scalaVersion. */ + @nowarn private[sbt] def underScalaVersion(c: Configuration): Boolean = c match { case Default | Compile | IntegrationTest | Provided | Runtime | Test | Optional | diff --git a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala index 8d177c835..1ab5629d7 100644 --- a/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala +++ b/core/src/main/scala/sbt/librarymanagement/LibraryManagementSyntax.scala @@ -28,6 +28,7 @@ trait LibraryManagementSyntax final val Compile = C.Compile final val Test = C.Test final val Runtime = C.Runtime + @deprecated("Create a separate subproject for testing instead", "1.9.0") final val IntegrationTest = C.IntegrationTest final val Default = C.Default final val Provided = C.Provided diff --git a/project/build.properties b/project/build.properties index 5b12c1dc6..46e43a97e 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.7.0 +sbt.version=1.8.2 From 2821443c80582f22adddebc73eb1283efffef94e Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 0974/1030] Simplify processEvictions by inlining calculateCompatible --- .../sbt/librarymanagement/EvictionError.scala | 64 +++++++++---------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 6d0d0c274..52b056e6d 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -83,47 +83,43 @@ object EvictionError { } }: _*) - def calculateCompatible(p: EvictionPair): (Boolean, String, Boolean, String) = { - val winnerOpt = p.winner map { _.module } - val extraAttributes = ((p.winner match { - case Some(r) => r.extraAttributes.toMap - case _ => Map.empty - }): collection.immutable.Map[String, String]) ++ (winnerOpt match { - case Some(w) => w.extraAttributes.toMap - case _ => Map.empty - }) - // prioritize user-defined version scheme to allow overriding the real scheme - val schemeOpt = userDefinedSchemes - .get((p.organization, p.name)) - .orElse(userDefinedSchemes.get((p.organization, "*"))) - .orElse(VersionSchemes.extractFromExtraAttributes(extraAttributes)) - .orElse(userDefinedSchemes.get(("*", "*"))) - val f = (winnerOpt, schemeOpt) match { - case (Some(_), Some(scheme)) => VersionSchemes.evalFunc(scheme) - case _ => EvictionWarningOptions.guessTrue - } - val scheme = - if (isNameScalaSuffixed(p.name)) assumedVersionScheme - else assumedVersionSchemeJava - val guess = VersionSchemes.evalFunc(scheme) - (p.evicteds forall { r => - f((r.module, winnerOpt, module.scalaModuleInfo)) - }, schemeOpt.getOrElse("?"), p.evicteds forall { r => - guess((r.module, winnerOpt, module.scalaModuleInfo)) - }, scheme) - } pairs foreach { // don't report on a transitive eviction that does not have a winner // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => - val r = calculateCompatible(p) - if (!r._1) { - incompatibleEvictions += (p -> r._2) - } else if (!r._3) { - assumedIncompatEvictions += (p -> r._4) + val winner = p.winner.get + def lookupUserDefined(org: String = "*", mod: String = "*") = + userDefinedSchemes.get((org, mod)) + def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( + winner.extraAttributes.toMap ++ winner.module.extraAttributes + ) + // prioritize user-defined version scheme to allow overriding the real scheme + val userDefinedSchemeOrFromPom = + lookupUserDefined(p.organization, p.name) + .orElse(lookupUserDefined(p.organization)) + .orElse(fromWinnerPom) + .orElse(lookupUserDefined()) + + val assumedScheme = + if (isNameScalaSuffixed(p.name)) assumedVersionScheme + else assumedVersionSchemeJava + + def hasIncompatibleVersionForScheme(scheme: Option[String]) = { + val isCompat = + scheme.map(VersionSchemes.evalFunc).getOrElse(EvictionWarningOptions.guessTrue) + p.evicteds.exists { r => + !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) + } } + + if (hasIncompatibleVersionForScheme(userDefinedSchemeOrFromPom)) + incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) + else if (hasIncompatibleVersionForScheme(Some(assumedScheme))) + assumedIncompatEvictions += (p -> assumedScheme) + case _ => () } + new EvictionError( incompatibleEvictions.toList, assumedIncompatEvictions.toList, From 87f8089ba8b647e76b2102658959d32fbcbcb8f9 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 0975/1030] More readability for processEvictions --- .../sbt/librarymanagement/EvictionError.scala | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 52b056e6d..9711a4d6f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -88,33 +88,34 @@ object EvictionError { // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => val winner = p.winner.get - def lookupUserDefined(org: String = "*", mod: String = "*") = + def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = userDefinedSchemes.get((org, mod)) def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( winner.extraAttributes.toMap ++ winner.module.extraAttributes ) // prioritize user-defined version scheme to allow overriding the real scheme val userDefinedSchemeOrFromPom = - lookupUserDefined(p.organization, p.name) - .orElse(lookupUserDefined(p.organization)) + fromLibraryDependencySchemes(p.organization, p.name) + .orElse(fromLibraryDependencySchemes(p.organization)) .orElse(fromWinnerPom) - .orElse(lookupUserDefined()) + .orElse(fromLibraryDependencySchemes()) val assumedScheme = if (isNameScalaSuffixed(p.name)) assumedVersionScheme else assumedVersionSchemeJava - def hasIncompatibleVersionForScheme(scheme: Option[String]) = { + def hasIncompatibleVersionForScheme(scheme: String) = { val isCompat = - scheme.map(VersionSchemes.evalFunc).getOrElse(EvictionWarningOptions.guessTrue) + VersionSchemes.evalFunc(scheme) p.evicteds.exists { r => !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) } } - if (hasIncompatibleVersionForScheme(userDefinedSchemeOrFromPom)) + val userDefinedSchemeOrAlways = userDefinedSchemeOrFromPom.getOrElse(VersionSchemes.Always) + if (hasIncompatibleVersionForScheme(userDefinedSchemeOrAlways)) incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) - else if (hasIncompatibleVersionForScheme(Some(assumedScheme))) + else if (hasIncompatibleVersionForScheme(assumedScheme)) assumedIncompatEvictions += (p -> assumedScheme) case _ => () From 998df8b692415bdfad5bb6af2a4853dcb45e0967 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 4 May 2023 21:04:29 +0200 Subject: [PATCH 0976/1030] Allow user to suppress eviction errors for a specific library ... even if they would result in an incompatible eviction based on the assumed version scheme. --- .../sbt/librarymanagement/EvictionError.scala | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 9711a4d6f..27333fb2f 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -88,35 +88,43 @@ object EvictionError { // https://github.com/sbt/sbt/issues/4946 case p if p.winner.isDefined => val winner = p.winner.get - def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = - userDefinedSchemes.get((org, mod)) - def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( - winner.extraAttributes.toMap ++ winner.module.extraAttributes - ) - // prioritize user-defined version scheme to allow overriding the real scheme - val userDefinedSchemeOrFromPom = - fromLibraryDependencySchemes(p.organization, p.name) - .orElse(fromLibraryDependencySchemes(p.organization)) - .orElse(fromWinnerPom) - .orElse(fromLibraryDependencySchemes()) - - val assumedScheme = - if (isNameScalaSuffixed(p.name)) assumedVersionScheme - else assumedVersionSchemeJava def hasIncompatibleVersionForScheme(scheme: String) = { - val isCompat = - VersionSchemes.evalFunc(scheme) + val isCompat = VersionSchemes.evalFunc(scheme) p.evicteds.exists { r => !isCompat((r.module, Some(winner.module), module.scalaModuleInfo)) } } - val userDefinedSchemeOrAlways = userDefinedSchemeOrFromPom.getOrElse(VersionSchemes.Always) - if (hasIncompatibleVersionForScheme(userDefinedSchemeOrAlways)) - incompatibleEvictions += (p -> userDefinedSchemeOrFromPom.getOrElse("?")) - else if (hasIncompatibleVersionForScheme(assumedScheme)) - assumedIncompatEvictions += (p -> assumedScheme) + // from libraryDependencyScheme or defined in the pom using the `info.versionScheme` attribute + val userDefinedSchemeOrFromPom = { + def fromLibraryDependencySchemes(org: String = "*", mod: String = "*") = + userDefinedSchemes.get((org, mod)) + def fromWinnerPom = VersionSchemes.extractFromExtraAttributes( + winner.extraAttributes.toMap ++ winner.module.extraAttributes + ) + + fromLibraryDependencySchemes(p.organization, p.name) // by org and name + .orElse(fromLibraryDependencySchemes(p.organization)) // for whole org + .orElse(fromWinnerPom) // from pom + .orElse(fromLibraryDependencySchemes()) // global + } + + // We want the user to be able to suppress eviction errors for a specific library, + // which would result in an incompatible eviction based on the assumed version scheme. + // So, only fall back to the assumed scheme if there is no given scheme by the user or the pom. + userDefinedSchemeOrFromPom match { + case Some(givenScheme) => + if (hasIncompatibleVersionForScheme(givenScheme)) + incompatibleEvictions += (p -> givenScheme) + case None => + val assumedScheme = + if (isNameScalaSuffixed(p.name)) assumedVersionScheme + else assumedVersionSchemeJava + + if (hasIncompatibleVersionForScheme(assumedScheme)) + assumedIncompatEvictions += (p -> assumedScheme) + } case _ => () } From d4296d3e919709ac3bc53b5291275648c1d8ad04 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 6 May 2023 22:52:59 -0400 Subject: [PATCH 0977/1030] Reproduce sbt/sbt#6745 --- .../librarymanagement/EvictionErrorSpec.scala | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index a6b97c99e..f4b2c53e2 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -97,6 +97,23 @@ object EvictionErrorSpec extends BaseIvySpecification { assert(EvictionError(report, m, overrideRules).incompatibleEvictions.isEmpty) } + test("it should selectively allow opt-out from the error despite assumed scheme") { + val deps = Vector(`scala2.12.17`, `akkaActor2.6.0`, `swagger-akka-http1.4.0`) + val m = module(defaultModuleId, deps, Some("2.12.17")) + val report = ivyUpdate(m) + val overrideRules = List("org.scala-lang.modules" %% "scala-java8-compat" % "always") + assert( + EvictionError( + report = report, + module = m, + schemes = overrideRules, + assumedVersionScheme = "early-semver", + assumedVersionSchemeJava = "always", + assumedEvictionErrorLevel = Level.Error, + ).assumedIncompatibleEvictions.isEmpty + ) + } + // older Akka was on pvp def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") @@ -104,8 +121,12 @@ object EvictionErrorSpec extends BaseIvySpecification { ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary lazy val `akkaActor2.3.0` = ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + lazy val `akkaActor2.6.0` = + ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations(Some("compile")) cross CrossVersion.binary lazy val `scala2.10.4` = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) + lazy val `scala2.12.17` = + ModuleID("org.scala-lang", "scala-library", "2.12.17").withConfigurations(Some("compile")) lazy val `scala2.13.3` = ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) lazy val `bananaSesame0.4` = @@ -122,6 +143,9 @@ object EvictionErrorSpec extends BaseIvySpecification { ("org.typelevel" %% "cats-parse" % "0.1.0").withConfigurations(Some("compile")) lazy val `cats-parse0.2.0` = ("org.typelevel" %% "cats-parse" % "0.2.0").withConfigurations(Some("compile")) + lazy val `swagger-akka-http1.4.0` = + ("com.github.swagger-akka-http" %% "swagger-akka-http" % "1.4.0") + .withConfigurations(Some("compile")) def dummyScalaModuleInfo(v: String): ScalaModuleInfo = ScalaModuleInfo( From b2ecf69b96d05ccf3c5bc8e5953dcc74d1c16529 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 2 Jun 2023 01:36:05 -0400 Subject: [PATCH 0978/1030] util 1.9.0 --- project/Dependencies.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7424830d9..cd168495a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -3,14 +3,14 @@ import Keys._ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { - val scala212 = "2.12.17" - val scala213 = "2.13.8" + val scala212 = "2.12.18" + val scala213 = "2.13.10" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.8.0") - private val utilVersion = nightlyVersion.getOrElse("1.8.0") + private val ioVersion = nightlyVersion.getOrElse("1.9.0") + private val utilVersion = nightlyVersion.getOrElse("1.9.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 363c0fe015a2492bb9e8c4ec84eb3cdf9eafb644 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 09:46:39 +0900 Subject: [PATCH 0979/1030] avoid deprecated `java.net.URL` constructor - https://bugs.openjdk.org/browse/JDK-8295949 - openjdk/jdk@4338f52 --- core/src/main/scala/sbt/librarymanagement/License.scala | 9 +++++---- .../main/scala/sbt/librarymanagement/ModuleIDExtra.scala | 4 ++-- .../main/scala/sbt/librarymanagement/ResolverExtra.scala | 9 +++++---- .../test/scala/sbt/librarymanagement/ResolverTest.scala | 4 ++-- .../sbt/internal/librarymanagement/ConvertResolver.scala | 6 +++--- .../sbt/internal/librarymanagement/FakeResolver.scala | 4 ++-- .../internal/librarymanagement/DMSerializationSpec.scala | 4 ++-- .../sbt/internal/librarymanagement/ResolverSpec.scala | 4 ++-- 8 files changed, 23 insertions(+), 21 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/License.scala b/core/src/main/scala/sbt/librarymanagement/License.scala index 6f335fb24..a8ac31088 100644 --- a/core/src/main/scala/sbt/librarymanagement/License.scala +++ b/core/src/main/scala/sbt/librarymanagement/License.scala @@ -1,6 +1,7 @@ package sbt.librarymanagement import java.net.URL +import java.net.URI /** * Commonly used software licenses @@ -9,16 +10,16 @@ import java.net.URL */ object License { lazy val Apache2: (String, URL) = - ("Apache-2.0", new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")) + ("Apache-2.0", new URI("https://www.apache.org/licenses/LICENSE-2.0.txt").toURL) lazy val MIT: (String, URL) = - ("MIT", new URL("https://opensource.org/licenses/MIT")) + ("MIT", new URI("https://opensource.org/licenses/MIT").toURL) lazy val CC0: (String, URL) = - ("CC0-1.0", new URL("https://creativecommons.org/publicdomain/zero/1.0/legalcode")) + ("CC0-1.0", new URI("https://creativecommons.org/publicdomain/zero/1.0/legalcode").toURL) def PublicDomain: (String, URL) = CC0 lazy val GPL3_or_later: (String, URL) = - ("GPL-3.0-or-later", new URL("https://spdx.org/licenses/GPL-3.0-or-later.html")) + ("GPL-3.0-or-later", new URI("https://spdx.org/licenses/GPL-3.0-or-later.html").toURL) } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index cb68eaf78..912e832fa 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -3,7 +3,7 @@ */ package sbt.librarymanagement -import java.net.URL +import java.net.URI import sbt.internal.librarymanagement.mavenint.SbtPomExtraProperties import scala.collection.mutable.ListBuffer @@ -132,7 +132,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * It is not included in published metadata. */ def from(url: String, allowInsecureProtocol: Boolean): ModuleID = - artifacts(Artifact(name, new URL(url), allowInsecureProtocol)) + artifacts(Artifact(name, new URI(url).toURL, allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 10dd77e8f..998e66156 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -9,6 +9,7 @@ import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger +import java.net.URI final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -146,13 +147,13 @@ private[librarymanagement] abstract class ResolverFunctions { def typesafeRepo(status: String) = MavenRepository("typesafe-" + status, TypesafeRepositoryRoot + "/" + status) def typesafeIvyRepo(status: String) = - url("typesafe-ivy-" + status, new URL(TypesafeRepositoryRoot + "/ivy-" + status + "/"))( + url("typesafe-ivy-" + status, new URI(TypesafeRepositoryRoot + "/ivy-" + status + "/").toURL)( ivyStylePatterns ) def sbtIvyRepo(status: String) = - url(s"sbt-ivy-$status", new URL(s"$SbtRepositoryRoot/ivy-$status/"))(ivyStylePatterns) + url(s"sbt-ivy-$status", new URI(s"$SbtRepositoryRoot/ivy-$status/").toURL)(ivyStylePatterns) def sbtPluginRepo(status: String) = - url("sbt-plugin-" + status, new URL(SbtRepositoryRoot + "/sbt-plugin-" + status + "/"))( + url("sbt-plugin-" + status, new URI(SbtRepositoryRoot + "/sbt-plugin-" + status + "/").toURL)( ivyStylePatterns ) @deprecated( @@ -175,7 +176,7 @@ private[librarymanagement] abstract class ResolverFunctions { def bintrayRepo(owner: String, repo: String) = MavenRepository(s"bintray-$owner-$repo", s"https://dl.bintray.com/$owner/$repo/") def bintrayIvyRepo(owner: String, repo: String) = - url(s"bintray-$owner-$repo", new URL(s"https://dl.bintray.com/$owner/$repo/"))( + url(s"bintray-$owner-$repo", new URI(s"https://dl.bintray.com/$owner/$repo/").toURL)( Resolver.ivyStylePatterns ) def jcenterRepo = JCenterRepository diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala index 70f7c19cd..400162766 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverTest.scala @@ -1,6 +1,6 @@ package sbt.librarymanagement -import java.net.URL +import java.net.URI import sbt.internal.librarymanagement.UnitSpec @@ -10,7 +10,7 @@ object ResolverTest extends UnitSpec { val pats = Vector("[orgPath]") val patsExpected = Vector("http://foo.com/test/[orgPath]") val patterns = Resolver - .url("test", new URL("http://foo.com/test"))( + .url("test", new URI("http://foo.com/test").toURL)( Patterns( pats, pats, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 94e82974a..46a7b9f55 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -3,7 +3,7 @@ */ package sbt.internal.librarymanagement -import java.net.URL +import java.net.URI import java.util.Collections import org.apache.ivy.core.module.descriptor.DependencyDescriptor @@ -394,7 +394,7 @@ private[sbt] object ConvertResolver { private[this] val repo = new WarnOnOverwriteFileRepo() private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { - val url = new URL(source) + val url = new URI(source).toURL if (url.getProtocol == IO.FileScheme) new FileResource(repo, IO.toFile(url)) else @@ -402,7 +402,7 @@ private[sbt] object ConvertResolver { } override def put(source: File, destination: String, overwrite: Boolean): Unit = { - val url = new URL(destination) + val url = new URI(destination).toURL try { if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) else { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 794fff9e3..2edf7c872 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -1,7 +1,7 @@ package sbt import java.io.File -import java.net.URL +import java.net.URI import org.apache.ivy.core.cache.ArtifactOrigin import org.apache.ivy.core.cache.{ DefaultRepositoryCacheManager, RepositoryCacheManager } @@ -69,7 +69,7 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) - val path = new URL(artifact.getLocation).toURI.getPath + val path = new URI(artifact.getLocation).toURL.toURI.getPath val localFile = new File(path) if (path.nonEmpty && localFile.exists) { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 86cf43322..33b591b62 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -1,6 +1,6 @@ package sbt.internal.librarymanagement -import java.net.URL +import java.net.URI import java.io.File import sbt.librarymanagement._ @@ -43,7 +43,7 @@ object DMSerializationSpec extends BasicTestSuite { } test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { - roundtrip(Artifact("foo", new URL("http://example.com/"))) + roundtrip(Artifact("foo", new URI("http://example.com/").toURL)) } test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala index 92cb9fa32..6e7816ae9 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ResolverSpec.scala @@ -1,13 +1,13 @@ package sbttest -import java.net.URL +import java.net.URI import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ import verify.BasicTestSuite class ResolverSpec extends BasicTestSuite { test("Resolver.url") { - Resolver.url("Test Repo", new URL("http://example.com/"))(Resolver.ivyStylePatterns) + Resolver.url("Test Repo", new URI("http://example.com/").toURL)(Resolver.ivyStylePatterns) () } From f81974ecce9fc9edf77a1d05e44c73ba508294b3 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 09:53:06 +0900 Subject: [PATCH 0980/1030] add LICENSE file --- LICENSE | 204 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..5c4a3cff9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (c) 2023, Scala Center + Copyright (c) 2011 - 2022, Lightbend, Inc. + Copyright (c) 2008 - 2010, Mark Harrah + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 9a1d836b4e79664cf6558c0f059f54e5e92410fa Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sun, 25 Jun 2023 10:10:11 +0900 Subject: [PATCH 0981/1030] update scalafmt --- .scalafmt.conf | 9 +- build.sbt | 11 +- .../internal/librarymanagement/JsonUtil.scala | 55 +++-- .../SemanticSelectorExtra.scala | 8 +- .../librarymanagement/VersionRange.scala | 2 +- .../librarymanagement/VersionSchemes.scala | 3 +- .../cross/CrossVersionUtil.scala | 3 +- .../sbt/librarymanagement/Configuration.scala | 10 +- .../librarymanagement/CrossVersionExtra.scala | 6 +- .../librarymanagement/DependencyFilter.scala | 4 +- .../DependencyResolution.scala | 14 +- .../sbt/librarymanagement/EvictionError.scala | 43 ++-- .../librarymanagement/EvictionWarning.scala | 14 +- .../sbt/librarymanagement/ModuleIDExtra.scala | 12 +- .../sbt/librarymanagement/ResolverExtra.scala | 46 ++-- .../librarymanagement/RichUpdateReport.scala | 25 +- .../librarymanagement/UnresolvedWarning.scala | 28 ++- .../librarymanagement/UpdateReportExtra.scala | 33 +-- .../sbt/librarymanagement/VersionNumber.scala | 9 +- core/src/test/scala/ConfigMacroSpec.scala | 2 +- .../librarymanagement/VersionNumberSpec.scala | 13 +- .../ReplaceMavenConfigurationMappings.scala | 2 - .../librarymanagement/ComponentManager.scala | 2 +- .../librarymanagement/ConvertResolver.scala | 202 +++++++-------- .../librarymanagement/CustomPomParser.scala | 25 +- .../librarymanagement/CustomXmlParser.scala | 4 +- .../librarymanagement/FakeResolver.scala | 4 +- .../sbt/internal/librarymanagement/Ivy.scala | 30 ++- .../librarymanagement/IvyActions.scala | 117 +++++---- .../internal/librarymanagement/IvyCache.scala | 18 +- .../librarymanagement/IvyLogger.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 24 +- .../librarymanagement/IvyScalaUtil.scala | 11 +- .../librarymanagement/ResolutionCache.scala | 3 +- .../CachedResolutionResolveEngine.scala | 229 ++++++++++-------- .../ivyint/ErrorMessageAuthenticator.scala | 31 ++- .../ivyint/IvyCredentialsLookup.scala | 4 +- .../ivyint/MergeDescriptors.scala | 16 +- .../ivyint/ParallelResolveEngine.scala | 25 +- .../ivyint/SbtChainResolver.scala | 87 +++---- .../librarymanagement/ivy/Credentials.scala | 4 +- .../librarymanagement/ivy/UpdateOptions.scala | 12 +- .../ComponentManagerTest.scala | 2 +- .../librarymanagement/CredentialsSpec.scala | 14 +- .../librarymanagement/EvictionErrorSpec.scala | 20 +- .../EvictionWarningSpec.scala | 40 ++- .../InconsistentDuplicateSpec.scala | 12 +- .../librarymanagement/IvyRepoSpec.scala | 28 +-- .../MergeDescriptorSpec.scala | 27 +-- .../librarymanagement/SftpRepoSpec.scala | 2 +- project/HouseRulesPlugin.scala | 4 +- project/Util.scala | 4 +- 52 files changed, 736 insertions(+), 619 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index e98e60599..4bcacf16e 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,11 +1,12 @@ -version = 2.0.0 +version = 3.7.4 maxColumn = 100 project.git = true project.excludeFilters = [ /sbt-test/, /input_sources/, /contraband-scala/ ] # http://docs.scala-lang.org/style/scaladoc.html recommends the JavaDoc style. # scala/scala is written that way too https://github.com/scala/scala/blob/v2.12.2/src/library/scala/Predef.scala -docstrings = JavaDoc +docstrings.style = Asterisk +docstrings.wrap = no # This also seems more idiomatic to include whitespace in import x.{ yyy } spaces.inImportCurlyBraces = true @@ -16,6 +17,8 @@ align.openParenCallSite = false align.openParenDefnSite = false # For better code clarity -danglingParentheses = true +danglingParentheses.preset = true trailingCommas = preserve + +runner.dialect = Scala212Source3 diff --git a/build.sbt b/build.sbt index b44f77bdb..c4db12bb1 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,7 @@ import Path._ import com.typesafe.tools.mima.core._, ProblemFilters._ val _ = { - //https://github.com/sbt/contraband/issues/122 + // https://github.com/sbt/contraband/issues/122 sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value @@ -90,11 +90,10 @@ val mimaSettings = Def settings ( "1.4.0", "1.5.0", "1.6.0", - ) map ( - version => - organization.value %% moduleName.value % version - cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) - ), + ) map (version => + organization.value %% moduleName.value % version + cross (if (crossPaths.value) CrossVersion.binary else CrossVersion.disabled) + ), ) lazy val lmRoot = (project in file(".")) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala index e7e087537..8d15a64cb 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/JsonUtil.scala @@ -34,34 +34,33 @@ private[sbt] object JsonUtil { UpdateReportLite(ur.configurations map { cr => ConfigurationReportLite( cr.configuration.name, - cr.details map { - oar => - OrganizationArtifactReport( - oar.organization, - oar.name, - oar.modules map { mr => - ModuleReport( - mr.module, - mr.artifacts, - mr.missingArtifacts, - mr.status, - mr.publicationDate, - mr.resolver, - mr.artifactResolver, - mr.evicted, - mr.evictedData, - mr.evictedReason, - mr.problem, - mr.homepage, - mr.extraAttributes, - mr.isDefault, - mr.branch, - mr.configurations, - mr.licenses, - filterOutArtificialCallers(mr.callers) - ) - } - ) + cr.details map { oar => + OrganizationArtifactReport( + oar.organization, + oar.name, + oar.modules map { mr => + ModuleReport( + mr.module, + mr.artifacts, + mr.missingArtifacts, + mr.status, + mr.publicationDate, + mr.resolver, + mr.artifactResolver, + mr.evicted, + mr.evictedData, + mr.evictedReason, + mr.problem, + mr.homepage, + mr.extraAttributes, + mr.isDefault, + mr.branch, + mr.configurations, + mr.licenses, + filterOutArtificialCallers(mr.callers) + ) + } + ) } ) }) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index 8fafce2a0..d9a7fb24f 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -58,8 +58,8 @@ private[librarymanagement] abstract class SemComparatorExtra { protected def toStringImpl: String = { val versionStr = Seq(major, minor, patch) - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") val tagsStr = if (tags.nonEmpty) s"-${tags.mkString("-")}" else "" @@ -177,8 +177,8 @@ private[librarymanagement] abstract class SemComparatorFunctions { } parse( numbers - .collect { - case Some(v) => v.toString + .collect { case Some(v) => + v.toString } .mkString(".") ) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala index 74c7ff253..3bf85a9e9 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionRange.scala @@ -71,7 +71,7 @@ object VersionRange { case _: NumberFormatException => // TODO - if the version doesn't meet our expectations, maybe we just issue a hard // error instead of softly ignoring the attempt to rewrite. - //sys.error(s"Could not fix version [$revision] into maven style version") + // sys.error(s"Could not fix version [$revision] into maven style version") revision } } diff --git a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala index e214cc377..112420028 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/VersionSchemes.scala @@ -36,7 +36,8 @@ private[sbt] object VersionSchemes { case x => sys.error(s"unknown version scheme: $x") } - /** info.versionScheme property will be included into POM after sbt 1.4.0. + /** + * info.versionScheme property will be included into POM after sbt 1.4.0. */ def extractFromId(mid: ModuleID): Option[String] = extractFromExtraAttributes(mid.extraAttributes) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index 8f84cad47..e8e518ec8 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -27,7 +27,8 @@ object CrossVersionUtil { private[sbt] val BinCompatV = raw"""$basicVersion(-$tagPattern)?-bin(-.*)?""".r private val CandidateV = raw"""$basicVersion(-RC\d+)""".r private val MilestonV = raw"""$basicVersion(-M$tagPattern)""".r - private val NonReleaseV_n = raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes + private val NonReleaseV_n = + raw"""$basicVersion((?:-$tagPattern)*)""".r // 0-n word suffixes, with leading dashes private val NonReleaseV_1 = raw"""$basicVersion(-$tagPattern)""".r // 1 word suffix, after a dash private[sbt] val PartialVersion = raw"""($longPattern)\.($longPattern)(?:\..+)?""".r diff --git a/core/src/main/scala/sbt/librarymanagement/Configuration.scala b/core/src/main/scala/sbt/librarymanagement/Configuration.scala index e82d7513e..53c409839 100644 --- a/core/src/main/scala/sbt/librarymanagement/Configuration.scala +++ b/core/src/main/scala/sbt/librarymanagement/Configuration.scala @@ -21,11 +21,11 @@ final class Configuration private[sbt] ( override def equals(o: Any): Boolean = o match { case x: Configuration => (this.id == x.id) && - (this.name == x.name) && - (this.description == x.description) && - (this.isPublic == x.isPublic) && - (this.extendsConfigs == x.extendsConfigs) && - (this.transitive == x.transitive) + (this.name == x.name) && + (this.description == x.description) && + (this.isPublic == x.isPublic) && + (this.extendsConfigs == x.extendsConfigs) && + (this.transitive == x.transitive) case _ => false } diff --git a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala index 03cd97e88..546089928 100644 --- a/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/CrossVersionExtra.scala @@ -37,13 +37,13 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def fullWith(prefix: String, suffix: String): CrossVersion = Full(prefix, suffix) - /** Cross-versions a module with the binary version (typically the binary Scala version). */ + /** Cross-versions a module with the binary version (typically the binary Scala version). */ def binary: CrossVersion = Binary() /** Disables cross versioning for a module. */ def disabled: CrossVersion = sbt.librarymanagement.Disabled - /** Cross-versions a module with a constant string (typically the binary Scala version). */ + /** Cross-versions a module with a constant string (typically the binary Scala version). */ def constant(value: String): CrossVersion = Constant(value) /** @@ -218,7 +218,7 @@ private[librarymanagement] abstract class CrossVersionFunctions { */ def scalaApiVersion(v: String): Option[(Long, Long)] = CrossVersionUtil.scalaApiVersion(v) - /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2.*/ + /** Regular expression that extracts the major and minor components of a version into matched groups 1 and 2. */ val PartialVersion = CrossVersionUtil.PartialVersion /** Extracts the major and minor components of a version string `s` or returns `None` if the version is improperly formatted. */ diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala index 2f2adf763..3aa96f30d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyFilter.scala @@ -29,7 +29,9 @@ trait DependencyFilterExtra { ): ArtifactFilter = new ArtifactFilter { def apply(a: Artifact): Boolean = - name.accept(a.name) && `type`.accept(a.`type`) && extension.accept(a.extension) && classifier + name.accept(a.name) && `type`.accept(a.`type`) && extension.accept( + a.extension + ) && classifier .accept(a.classifier getOrElse "") } diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index 500f569e5..1f2b37a2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -189,10 +189,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap Right(r.substitute { (conf, mid, artFileSeq) => - artFileSeq map { - case (art, f) => - // Deduce the classifier from the type if no classifier is present already - art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f + artFileSeq map { case (art, f) => + // Deduce the classifier from the type if no classifier is present already + art.withClassifier(art.classifier orElse typeClassifierMap.get(art.`type`)) -> f } }) case Left(w) => Left(w) @@ -200,10 +199,9 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface } protected def directDependenciesNames(module: ModuleDescriptor): String = - (module.directDependencies map { - case mID: ModuleID => - import mID._ - s"$organization % $name % $revision" + (module.directDependencies map { case mID: ModuleID => + import mID._ + s"$organization % $name % $revision" }).mkString(", ") } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 27333fb2f..3e73e37c7 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -157,30 +157,29 @@ final class EvictionError private[sbt] ( val out: mutable.ListBuffer[String] = mutable.ListBuffer() out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" - evictions.foreach({ - case (a, scheme) => - val revs = a.evicteds map { _.module.revision } - val revsStr = - if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" - val seen: mutable.Set[ModuleID] = mutable.Set() - val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => - val rev = r.module.revision - r.callers.toList flatMap { caller => - if (seen(caller.caller)) Nil - else { - seen += caller.caller - List(f"\t +- ${caller}%-50s (depends on $rev)") - } + evictions.foreach({ case (a, scheme) => + val revs = a.evicteds map { _.module.revision } + val revsStr = + if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" + val seen: mutable.Set[ModuleID] = mutable.Set() + val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => + val rev = r.module.revision + r.callers.toList flatMap { caller => + if (seen(caller.caller)) Nil + else { + seen += caller.caller + List(f"\t +- ${caller}%-50s (depends on $rev)") } } - val que = if (assumed) "?" else "" - val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" - case _ => " is evicted for all versions" - } - val title = s"\t* ${a.organization}:${a.name}$winnerRev" - val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") - out ++= lines + } + val que = if (assumed) "?" else "" + val winnerRev = a.winner match { + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" + case _ => " is evicted for all versions" + } + val title = s"\t* ${a.organization}:${a.name}$winnerRev" + val lines = title :: (if (a.showCallers) callers.reverse else Nil) ::: List("") + out ++= lines }) out.toList } diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index ae6c95638..df70eeffa 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -196,7 +196,7 @@ final class EvictionPair private[sbt] ( override def equals(o: Any): Boolean = o match { case o: EvictionPair => (this.organization == o.organization) && - (this.name == o.name) + (this.name == o.name) case _ => false } override def hashCode: Int = { @@ -279,10 +279,12 @@ object EvictionWarning { } confs flatMap { confReport => confReport.details map { detail => - if ((detail.modules exists { _.evicted }) && - !(buffer exists { x => - (x.organization == detail.organization) && (x.name == detail.name) - })) { + if ( + (detail.modules exists { _.evicted }) && + !(buffer exists { x => + (x.organization == detail.organization) && (x.name == detail.name) + }) + ) { buffer += detail } } @@ -298,7 +300,7 @@ object EvictionWarning { module.scalaModuleInfo match { case Some(s) => organization == s.scalaOrganization && - (name == LibraryID) || (name == CompilerID) + (name == LibraryID) || (name == CompilerID) case _ => false } diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index cb68eaf78..022d919de 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -37,10 +37,10 @@ private[librarymanagement] abstract class ModuleIDExtra { protected def toStringImpl: String = s"""$organization:$name:$revision""" + (configurations match { case Some(s) => ":" + s; case None => "" }) + { - val attr = attributeString - if (attr == "") "" - else " " + attr - } + + val attr = attributeString + if (attr == "") "" + else " " + attr + } + (if (extraAttributes.isEmpty) "" else " " + extraString) protected def attributeString: String = { @@ -95,10 +95,10 @@ private[librarymanagement] abstract class ModuleIDExtra { }) // () required for chaining - /** Do not follow dependencies of this module. Synonym for `intransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `intransitive`. */ def notTransitive(): ModuleID = intransitive() - /** Do not follow dependencies of this module. Synonym for `notTransitive`.*/ + /** Do not follow dependencies of this module. Synonym for `notTransitive`. */ def intransitive(): ModuleID = withIsTransitive(false) /** diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index 10dd77e8f..2f87d5d1e 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -185,7 +185,7 @@ private[librarymanagement] abstract class ResolverFunctions { "https://repository.apache.org/content/repositories/snapshots/" ) - /** Add the local and Maven Central repositories to the user repositories. */ + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) @@ -232,7 +232,10 @@ private[librarymanagement] abstract class ResolverFunctions { single(JCenterRepository, jcenter) ++ (xs.partition(_ == DefaultMavenRepository) match { case (_, xs) => - single(DefaultMavenRepository, mavenCentral) ++ xs // TODO - Do we need to filter out duplicates? + single( + DefaultMavenRepository, + mavenCentral + ) ++ xs // TODO - Do we need to filter out duplicates? }) }) } @@ -240,7 +243,7 @@ private[librarymanagement] abstract class ResolverFunctions { private def single[T](value: T, nonEmpty: Boolean): Vector[T] = if (nonEmpty) Vector(value) else Vector.empty - /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ + /** A base class for defining factories for interfaces to Ivy repositories that require a hostname , port, and patterns. */ sealed abstract class Define[RepositoryType <: SshBasedRepository] { /** Subclasses should implement this method to */ @@ -269,8 +272,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), None, Some(basePath)) @@ -278,8 +281,8 @@ private[librarymanagement] abstract class ResolverFunctions { * Constructs this repository type with the given `name`, `hostname`, and `port`. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), None) @@ -288,8 +291,8 @@ private[librarymanagement] abstract class ResolverFunctions { * patterns will be resolved. `basePatterns` are the initial patterns to use. * A ManagedProject has an implicit defining these initial patterns based on a setting for either Maven or Ivy style patterns. */ - def apply(name: String, hostname: String, port: Int, basePath: String)( - implicit basePatterns: Patterns + def apply(name: String, hostname: String, port: Int, basePath: String)(implicit + basePatterns: Patterns ): RepositoryType = apply(name, Some(hostname), Some(port), Some(basePath)) @@ -304,13 +307,13 @@ private[librarymanagement] abstract class ResolverFunctions { construct(name, SshConnection(None, hostname, port), resolvePatterns(basePath, basePatterns)) } - /** A factory to construct an interface to an Ivy SSH resolver.*/ + /** A factory to construct an interface to an Ivy SSH resolver. */ object ssh extends Define[SshRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SshRepository(name, connection, patterns, None) } - /** A factory to construct an interface to an Ivy SFTP resolver.*/ + /** A factory to construct an interface to an Ivy SFTP resolver. */ object sftp extends Define[SftpRepository] { protected def construct(name: String, connection: SshConnection, patterns: Patterns) = SftpRepository(name, connection, patterns) @@ -348,8 +351,8 @@ private[librarymanagement] abstract class ResolverFunctions { def apply(name: String, baseURL: URL)(implicit basePatterns: Patterns): URLRepository = baseRepository(baseURL.toURI.normalize.toString)(URLRepository(name, _)) } - private def baseRepository[T](base: String)(construct: Patterns => T)( - implicit basePatterns: Patterns + private def baseRepository[T](base: String)(construct: Patterns => T)(implicit + basePatterns: Patterns ): T = construct(resolvePatterns(base, basePatterns)) @@ -381,7 +384,7 @@ private[librarymanagement] abstract class ResolverFunctions { } def defaultFileConfiguration = FileConfiguration(true, None) def mavenStylePatterns = Patterns().withArtifactPatterns(Vector(mavenStyleBasePattern)) - def ivyStylePatterns = defaultIvyPatterns //Patterns(Nil, Nil, false) + def ivyStylePatterns = defaultIvyPatterns // Patterns(Nil, Nil, false) def defaultPatterns = mavenStylePatterns def mavenStyleBasePattern = @@ -397,10 +400,13 @@ private[librarymanagement] abstract class ResolverFunctions { val findQuoted = "\\$\\{([^\\}]*)\\}".r val env = "env\\.(.*)".r - findQuoted.replaceAllIn(str, _.group(1) match { - case env(variable) => sys.env.getOrElse(variable, "") - case property => sys.props.getOrElse(property, "") - }) + findQuoted.replaceAllIn( + str, + _.group(1) match { + case env(variable) => sys.env.getOrElse(variable, "") + case property => sys.props.getOrElse(property, "") + } + ) } private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = @@ -423,7 +429,9 @@ private[librarymanagement] abstract class ResolverFunctions { } sys.props.get("maven.repo.local").map(new File(_)) orElse loadHomeFromSettings(() => new File(sbt.io.Path.userHome, ".m2/settings.xml")) orElse - loadHomeFromSettings(() => new File(new File(System.getenv("M2_HOME")), "conf/settings.xml")) getOrElse + loadHomeFromSettings(() => + new File(new File(System.getenv("M2_HOME")), "conf/settings.xml") + ) getOrElse new File(sbt.io.Path.userHome, ".m2/repository") } // TODO - should this just be the *exact* same as mavenLocal? probably... diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index f66440bbb..9060f14b6 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -12,16 +12,15 @@ final class RichUpdateReport(report: UpdateReport) { private[sbt] def recomputeStamps(): UpdateReport = { val files = report.cachedDescriptor +: allFiles val stamps = files - .map( - f => - ( - f, - // TODO: The list of files may also contain some odd files that do not actually exist like: - // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". - // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such - // files to begin with, in principle. - IO.getModifiedTimeOrZero(f) - ) + .map(f => + ( + f, + // TODO: The list of files may also contain some odd files that do not actually exist like: + // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". + // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such + // files to begin with, in principle. + IO.getModifiedTimeOrZero(f) + ) ) .toMap UpdateReport(report.cachedDescriptor, report.configurations, report.stats, stamps) @@ -65,13 +64,13 @@ final class RichUpdateReport(report: UpdateReport) { file } - /** Constructs a new report that only contains files matching the specified filter.*/ + /** Constructs a new report that only contains files matching the specified filter. */ def filter(f: DependencyFilter): UpdateReport = moduleReportMap { (configuration, modReport) => modReport .withArtifacts( - modReport.artifacts filter { - case (art, _) => f(configuration, modReport.module, art) + modReport.artifacts filter { case (art, _) => + f(configuration, modReport.module, art) } ) .withMissingArtifacts( diff --git a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala index d871caa83..6f4aa832d 100644 --- a/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/UnresolvedWarning.scala @@ -10,9 +10,13 @@ final class ResolveException( val failedPaths: Map[ModuleID, Seq[ModuleID]] ) extends RuntimeException(messages.mkString("\n")) { def this(messages: Seq[String], failed: Seq[ModuleID]) = - this(messages, failed, Map(failed map { m => - m -> Nil - }: _*)) + this( + messages, + failed, + Map(failed map { m => + m -> Nil + }: _*) + ) } /** @@ -30,13 +34,12 @@ object UnresolvedWarning { config: UnresolvedWarningConfiguration ): UnresolvedWarning = { def modulePosition(m0: ModuleID): Option[SourcePosition] = - config.modulePositions.find { - case (m, _) => - (m.organization == m0.organization) && - (m0.name startsWith m.name) && - (m.revision == m0.revision) - } map { - case (_, p) => p + config.modulePositions.find { case (m, _) => + (m.organization == m0.organization) && + (m0.name startsWith m.name) && + (m.revision == m0.revision) + } map { case (_, p) => + p } val failedPaths = err.failed map { (x: ModuleID) => err.failedPaths(x).toList.reverse map { id => @@ -67,9 +70,8 @@ object UnresolvedWarning { if (path.nonEmpty) { val head = path.head buffer += "\t\t" + head._1.toString + sourcePosStr(head._2) - path.tail foreach { - case (m, pos) => - buffer += "\t\t +- " + m.toString + sourcePosStr(pos) + path.tail foreach { case (m, pos) => + buffer += "\t\t +- " + m.toString + sourcePosStr(pos) } } } diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 1ffba5008..910827703 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -29,9 +29,13 @@ private[librarymanagement] abstract class ConfigurationReportExtra { } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): ConfigurationReport = - ConfigurationReport(configuration, modules map { - _.retrieve((mid, art, file) => f(configuration, mid, art, file)) - }, details) + ConfigurationReport( + configuration, + modules map { + _.retrieve((mid, art, file) => f(configuration, mid, art, file)) + }, + details + ) } private[librarymanagement] abstract class ModuleReportExtra { @@ -124,24 +128,23 @@ private[librarymanagement] abstract class UpdateReportExtra { /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { - case (_, v) => - v reduceLeft { (agg, x) => - agg.withConfigurations( - (agg.configurations, x.configurations) match { - case (None, _) => x.configurations - case (Some(ac), None) => Some(ac) - case (Some(ac), Some(xc)) => Some(s"$ac;$xc") - } - ) - } + configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (None, _) => x.configurations + case (Some(ac), None) => Some(ac) + case (Some(ac), Some(xc)) => Some(s"$ac;$xc") + } + ) + } } } def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) - /** Gets the report for the given configuration, or `None` if the configuration was not resolved.*/ + /** Gets the report for the given configuration, or `None` if the configuration was not resolved. */ def configuration(s: ConfigRef) = configurations.find(_.configuration == s) /** Gets the names of all resolved configurations. This `UpdateReport` contains one `ConfigurationReport` for each configuration in this list. */ diff --git a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala index 8ce15c72d..1da91342e 100644 --- a/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala +++ b/core/src/main/scala/sbt/librarymanagement/VersionNumber.scala @@ -162,7 +162,8 @@ object VersionNumber { } } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -172,7 +173,8 @@ object VersionNumber { PackVer.isCompatible(v1, v2) } - /** A variant of SemVar that seems to be common among the Scala libraries. + /** + * A variant of SemVar that seems to be common among the Scala libraries. * The second segment (y in x.y.z) increments breaks the binary compatibility even when x > 0. * Also API compatibility is expected even when the first segment is zero. */ @@ -193,7 +195,8 @@ object VersionNumber { } } - /** A variant of SemVar that enforces API compatibility when the first segment is zero. + /** + * A variant of SemVar that enforces API compatibility when the first segment is zero. */ object EarlySemVer extends VersionNumberCompatibility { import SemVer._ diff --git a/core/src/test/scala/ConfigMacroSpec.scala b/core/src/test/scala/ConfigMacroSpec.scala index c35ab104b..ea409efa7 100644 --- a/core/src/test/scala/ConfigMacroSpec.scala +++ b/core/src/test/scala/ConfigMacroSpec.scala @@ -56,6 +56,6 @@ object ConfigMacroSpec extends Properties("ConfigMacroSpec") { s"Actual isPublic: ${c.isPublic}" |: (c.id == id) && (c.name == name) && - (c.isPublic == isPublic) + (c.isPublic == isPublic) } } diff --git a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala index 9f240f432..bf3465cce 100644 --- a/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala +++ b/core/src/test/scala/sbt/librarymanagement/VersionNumberSpec.scala @@ -148,13 +148,12 @@ class VersionNumberSpec extends AnyFreeSpec with Matchers with Inside { ts: Seq[String], es: Seq[String] ): Unit = - s"should parse to ($ns, $ts, $es)" in inside(v.value) { - case VersionNumber(ns1, ts1, es1) => - (ns1 shouldBe ns) - (ts1 shouldBe ts) - (es1 shouldBe es) - (VersionNumber(ns, ts, es).toString shouldBe v.value) - (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) + s"should parse to ($ns, $ts, $es)" in inside(v.value) { case VersionNumber(ns1, ts1, es1) => + (ns1 shouldBe ns) + (ts1 shouldBe ts) + (es1 shouldBe es) + (VersionNumber(ns, ts, es).toString shouldBe v.value) + (VersionNumber(ns, ts, es) shouldBe VersionNumber(ns, ts, es)) } private[this] def assertParsesToError(v: VersionString): Unit = diff --git a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala index 410bdcfb7..fb0b889d6 100644 --- a/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala +++ b/ivy/src/main/scala/org/apache/ivy/plugins/parser/m2/ReplaceMavenConfigurationMappings.scala @@ -21,8 +21,6 @@ import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; * * Also see: http://ant.apache.org/ivy/history/2.3.0/ivyfile/dependency.html * and: http://svn.apache.org/repos/asf/ant/ivy/core/tags/2.3.0/src/java/org/apache/ivy/plugins/parser/m2/PomModuleDescriptorBuilder.java - * - * */ object ReplaceMavenConfigurationMappings { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index ed42cd14c..710c120de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -56,7 +56,7 @@ class ComponentManager( /** This is used to lock the local cache in project/boot/. By checking the local cache first, we can avoid grabbing a global lock. */ private def lockLocalCache[T](action: => T): T = lock(provider.lockFile)(action) - /** This is used to ensure atomic access to components in the global Ivy cache.*/ + /** This is used to ensure atomic access to components in the global Ivy cache. */ private def lockGlobalCache[T](action: => T): T = lock(ivyCache.lockFile)(action) private def lock[T](file: File)(action: => T): T = globalLock(file, new Callable[T] { def call = action }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 94e82974a..2009fd2a8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -157,109 +157,108 @@ private[sbt] object ConvertResolver { (updateOptions.resolverConverter orElse defaultConvert)((r, settings, log)) /** The default implementation of converter. */ - lazy val defaultConvert: ResolverConverter = { - case (r, settings, log) => - val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { - case Some(x) => x.toBoolean - case _ => false - } - r match { - case repo: MavenRepository => { - val pattern = Collections.singletonList( - Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) - ) - final class PluginCapableResolver - extends IBiblioResolver - with ChecksumFriendlyURLResolver - with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - def setPatterns(): Unit = { - // done this way for access to protected methods. - setArtifactPatterns(pattern) - setIvyPatterns(pattern) - } - override protected def findResourceUsingPattern( - mrid: ModuleRevisionId, - pattern: String, - artifact: IArtifact, - rmdparser: ResourceMDParser, - date: Date - ): ResolvedResource = { - val extraAttributes = - mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] - getSbtPluginCrossVersion(extraAttributes) match { - case Some(sbtCrossVersion) => - // if the module is an sbt plugin - // we first try to resolve the artifact with the sbt cross version suffix - // and we fallback to the one without the suffix - val newArtifact = DefaultArtifact.cloneWithAnotherName( - artifact, - artifact.getName + sbtCrossVersion - ) - val resolved = - super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) - if (resolved != null) resolved - else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) - case None => - super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) - } + lazy val defaultConvert: ResolverConverter = { case (r, settings, log) => + val managedChecksums = Option(settings.getVariable(ManagedChecksums)) match { + case Some(x) => x.toBoolean + case _ => false + } + r match { + case repo: MavenRepository => { + val pattern = Collections.singletonList( + Resolver.resolvePattern(repo.root, Resolver.mavenStyleBasePattern) + ) + final class PluginCapableResolver + extends IBiblioResolver + with ChecksumFriendlyURLResolver + with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + def setPatterns(): Unit = { + // done this way for access to protected methods. + setArtifactPatterns(pattern) + setIvyPatterns(pattern) + } + override protected def findResourceUsingPattern( + mrid: ModuleRevisionId, + pattern: String, + artifact: IArtifact, + rmdparser: ResourceMDParser, + date: Date + ): ResolvedResource = { + val extraAttributes = + mrid.getExtraAttributes.asScala.toMap.asInstanceOf[Map[String, String]] + getSbtPluginCrossVersion(extraAttributes) match { + case Some(sbtCrossVersion) => + // if the module is an sbt plugin + // we first try to resolve the artifact with the sbt cross version suffix + // and we fallback to the one without the suffix + val newArtifact = DefaultArtifact.cloneWithAnotherName( + artifact, + artifact.getName + sbtCrossVersion + ) + val resolved = + super.findResourceUsingPattern(mrid, pattern, newArtifact, rmdparser, date) + if (resolved != null) resolved + else super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) + case None => + super.findResourceUsingPattern(mrid, pattern, artifact, rmdparser, date) } } - val resolver = new PluginCapableResolver - if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) - initializeMavenStyle(resolver, repo.name, repo.root) - resolver - .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns - resolver } - case repo: SshRepository => { - val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - initializeSSHResolver(resolver, repo, settings) - repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) - resolver - } - case repo: SftpRepository => { - val resolver = new SFTPResolver with ThreadSafeSshBasedResolver - initializeSSHResolver(resolver, repo, settings) - resolver - } - case repo: FileRepository => { - val resolver = new FileSystemResolver with DescriptorRequired { - // Workaround for #1156 - // Temporarily in sbt 0.13.x we deprecate overwriting - // in local files for non-changing revisions. - // This will be fully enforced in sbt 1.0. - setRepository(new WarnOnOverwriteFileRepo()) - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - import repo.configuration.{ isLocal, isTransactional } - resolver.setLocal(isLocal) - isTransactional.foreach(value => resolver.setTransactional(value.toString)) - resolver - } - case repo: URLRepository => { - val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { - override val managedChecksumsEnabled: Boolean = managedChecksums - override def getResource(resource: Resource, dest: File): Long = get(resource, dest) - } - resolver.setName(repo.name) - initializePatterns(resolver, repo.patterns, settings) - resolver - } - case repo: ChainedResolver => - IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) - case repo: RawRepository => - repo.resolver match { - case r: DependencyResolver => r - } + val resolver = new PluginCapableResolver + if (repo.localIfFile) resolver.setRepository(new LocalIfFileRepo) + initializeMavenStyle(resolver, repo.name, repo.root) + resolver + .setPatterns() // has to be done after initializeMavenStyle, which calls methods that overwrite the patterns + resolver } + case repo: SshRepository => { + val resolver = new SshResolver with DescriptorRequired with ThreadSafeSshBasedResolver { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + initializeSSHResolver(resolver, repo, settings) + repo.publishPermissions.foreach(perm => resolver.setPublishPermissions(perm)) + resolver + } + case repo: SftpRepository => { + val resolver = new SFTPResolver with ThreadSafeSshBasedResolver + initializeSSHResolver(resolver, repo, settings) + resolver + } + case repo: FileRepository => { + val resolver = new FileSystemResolver with DescriptorRequired { + // Workaround for #1156 + // Temporarily in sbt 0.13.x we deprecate overwriting + // in local files for non-changing revisions. + // This will be fully enforced in sbt 1.0. + setRepository(new WarnOnOverwriteFileRepo()) + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + import repo.configuration.{ isLocal, isTransactional } + resolver.setLocal(isLocal) + isTransactional.foreach(value => resolver.setTransactional(value.toString)) + resolver + } + case repo: URLRepository => { + val resolver = new URLResolver with ChecksumFriendlyURLResolver with DescriptorRequired { + override val managedChecksumsEnabled: Boolean = managedChecksums + override def getResource(resource: Resource, dest: File): Long = get(resource, dest) + } + resolver.setName(repo.name) + initializePatterns(resolver, repo.patterns, settings) + resolver + } + case repo: ChainedResolver => + IvySbt.resolverChain(repo.name, repo.resolvers, settings, log) + case repo: RawRepository => + repo.resolver match { + case r: DependencyResolver => r + } + } } private def getSbtPluginCrossVersion(extraAttributes: Map[String, String]): Option[String] = { @@ -329,8 +328,9 @@ private[sbt] object ConvertResolver { override def getDependency(dd: DependencyDescriptor, data: ResolveData) = { val prev = descriptorString(isAllownomd) setDescriptor(descriptorString(hasExplicitURL(dd))) - val t = try super.getDependency(dd, data) - finally setDescriptor(prev) + val t = + try super.getDependency(dd, data) + finally setDescriptor(prev) t } def descriptorString(optional: Boolean) = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index 3ec3282f6..eb9378880 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -64,7 +64,7 @@ object CustomPomParser { // Evil hackery to override the default maven pom mappings. ReplaceMavenConfigurationMappings.init() - /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution.*/ + /** The key prefix that indicates that this is used only to store extra information and is not intended for dependency resolution. */ val InfoKeyPrefix = SbtPomExtraProperties.POM_INFO_KEY_PREFIX val ApiURLKey = SbtPomExtraProperties.POM_API_KEY val VersionSchemeKey = SbtPomExtraProperties.VERSION_SCHEME_KEY @@ -75,7 +75,8 @@ object CustomPomParser { private[this] val unqualifiedKeys = Set(SbtVersionKey, ScalaVersionKey, ExtraAttributesKey, ApiURLKey, VersionSchemeKey) - /** In the new POM format of sbt plugins, the dependency to an sbt plugin + /** + * In the new POM format of sbt plugins, the dependency to an sbt plugin * contains the sbt cross-version _2.12_1.0. The reason is we want Maven to be able * to resolve the dependency using the pattern: * /_2.12_1.0//_2.12_1.0-.pom @@ -134,7 +135,9 @@ object CustomPomParser { val MyHash = MakeTransformHash(md) // sbt 0.13.1 used "sbtTransformHash" instead of "e:sbtTransformHash" until #1192 so read both Option(extraInfo).isDefined && - ((Option(extraInfo get TransformedHashKey) orElse Option(extraInfo get oldTransformedHashKey)) match { + ((Option(extraInfo get TransformedHashKey) orElse Option( + extraInfo get oldTransformedHashKey + )) match { case Some(MyHash) => true case _ => false }) @@ -297,17 +300,23 @@ object CustomPomParser { for (l <- md.getLicenses) dmd.addLicense(l) for ((key, value) <- md.getExtraInfo.asInstanceOf[java.util.Map[String, String]].asScala) dmd.addExtraInfo(key, value) - dmd.addExtraInfo(TransformedHashKey, MakeTransformHash(md)) // mark as transformed by this version, so we don't need to do it again - for ((key, value) <- md.getExtraAttributesNamespaces - .asInstanceOf[java.util.Map[String, String]] - .asScala) dmd.addExtraAttributeNamespace(key, value) + dmd.addExtraInfo( + TransformedHashKey, + MakeTransformHash(md) + ) // mark as transformed by this version, so we don't need to do it again + for ( + (key, value) <- md.getExtraAttributesNamespaces + .asInstanceOf[java.util.Map[String, String]] + .asScala + ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) val withExtra = md.getDependencies map { dd => addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = - if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } else withExtra + if (LMSysProp.modifyVersionRange) withExtra map { stripVersionRange } + else withExtra val unique = IvySbt.mergeDuplicateDefinitions(withVersionRangeMod) unique foreach dmd.addDependency diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala index 0498828be..a72a65339 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomXmlParser.scala @@ -15,7 +15,7 @@ import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser import org.apache.ivy.plugins.repository.Resource import org.apache.ivy.plugins.repository.url.URLResource -/** Subclasses the default Ivy file parser in order to provide access to protected methods.*/ +/** Subclasses the default Ivy file parser in order to provide access to protected methods. */ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { import XmlModuleDescriptorParser.Parser class CustomParser(settings: IvySettings, defaultConfig: Option[String]) @@ -26,7 +26,7 @@ private[sbt] object CustomXmlParser extends XmlModuleDescriptorParser { } def setInput(bytes: Array[Byte]): Unit = setInput(new ByteArrayInputStream(bytes)) - /** Overridden because the super implementation overwrites the module descriptor.*/ + /** Overridden because the super implementation overwrites the module descriptor. */ override def setResource(res: Resource): Unit = () override def setMd(md: DefaultModuleDescriptor) = { super.setMd(md) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 794fff9e3..df4a7d66b 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -178,8 +178,8 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module val artifact = for { artifacts <- modules get ((moduleOrganisation, moduleName, moduleRevision)) - artifact <- artifacts find ( - a => a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt + artifact <- artifacts find (a => + a.name == art.getName && a.tpe == art.getType && a.ext == art.getExt ) } yield new ArtifactOrigin(art, /* isLocal = */ true, artifact.file.toURI.toURL.toString) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 270d08546..4fbdbce4a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -135,7 +135,8 @@ final class IvySbt( is } - /** Defines a parallel [[CachedResolutionResolveEngine]]. + /** + * Defines a parallel [[CachedResolutionResolveEngine]]. * * This is defined here because it needs access to [[mkIvy]]. */ @@ -154,8 +155,10 @@ final class IvySbt( } } - /** Provides a default ivy implementation that decides which resolution - * engine to use depending on the passed ivy configuration options. */ + /** + * Provides a default ivy implementation that decides which resolution + * engine to use depending on the passed ivy configuration options. + */ private class IvyImplementation extends Ivy { private val loggerEngine = new SbtMessageLoggerEngine override def getLoggerEngine: SbtMessageLoggerEngine = loggerEngine @@ -195,7 +198,7 @@ final class IvySbt( // ========== End Configuration/Setup ============ - /** Uses the configured Ivy instance within a safe context.*/ + /** Uses the configured Ivy instance within a safe context. */ def withIvy[T](log: Logger)(f: Ivy => T): T = withIvy(new IvyLoggerInterface(log))(f) @@ -333,7 +336,7 @@ final class IvySbt( mod } - /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`.*/ + /** Parses the Maven pom 'pomFile' from the given `PomConfiguration`. */ private def configurePom(pc: PomConfiguration) = { val md = CustomPomParser.default.parseDescriptor(settings, toURL(pc.file), pc.validate) val dmd = IvySbt.toDefaultModuleDescriptor(md) @@ -347,7 +350,7 @@ final class IvySbt( (dmd, defaultConf) } - /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`.*/ + /** Parses the Ivy file 'ivyFile' from the given `IvyFileConfiguration`. */ private def configureIvyFile(ifc: IvyFileConfiguration) = { val parser = new CustomXmlParser.CustomParser(settings, None) parser.setValidate(ifc.validate) @@ -703,7 +706,7 @@ private[sbt] object IvySbt { moduleID.addConflictManager(mid, matcher, manager) } - /** Converts the given sbt module id into an Ivy ModuleRevisionId.*/ + /** Converts the given sbt module id into an Ivy ModuleRevisionId. */ def toID(m: ModuleID) = { import m._ ModuleRevisionId.newInstance( @@ -783,7 +786,8 @@ private[sbt] object IvySbt { } private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { import scala.collection.JavaConverters._ - val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m + val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } + else m if (map.isEmpty) null else map.asJava } @@ -814,8 +818,8 @@ private[sbt] object IvySbt { elem: scala.xml.Elem, extra: Map[String, String] ): scala.xml.Elem = - extra.foldLeft(elem) { - case (e, (key, value)) => e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) + extra.foldLeft(elem) { case (e, (key, value)) => + e % new scala.xml.UnprefixedAttribute(key, value, scala.xml.Null) } private def hasInfo(module: ModuleID, x: scala.xml.NodeSeq) = { val info = {x} \ "info" @@ -943,7 +947,7 @@ private[sbt] object IvySbt { } } - /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor.*/ + /** Transforms an sbt ModuleID into an Ivy DefaultDependencyDescriptor. */ def convertDependency( moduleID: DefaultModuleDescriptor, dependency: ModuleID, @@ -961,7 +965,9 @@ private[sbt] object IvySbt { dependency.configurations match { case None => // The configuration for this dependency was not explicitly specified, so use the default parser.parseDepsConfs(parser.getDefaultConf, dependencyDescriptor) - case Some(confs) => // The configuration mapping (looks like: test->default) was specified for this dependency + case Some( + confs + ) => // The configuration mapping (looks like: test->default) was specified for this dependency parser.parseDepsConfs(confs, dependencyDescriptor) } for (artifact <- dependency.explicitArtifacts) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 6d223287c..42a0eed7f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -29,7 +29,7 @@ import sbt.internal.librarymanagement.IvyUtil.TransientNetworkException object IvyActions { - /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'.*/ + /** Installs the dependencies of the given 'module' from the resolver named 'from' to the resolver named 'to'. */ def install(module: IvySbt#Module, from: String, to: String, log: Logger): Unit = { module.withModule(log) { (ivy, md, _) => for (dependency <- md.getDependencies) { @@ -57,7 +57,7 @@ object IvyActions { module.owner.cleanCachedResolutionCache() } - /** Creates a Maven pom from the given Ivy configuration*/ + /** Creates a Maven pom from the given Ivy configuration */ def makePomFile(module: IvySbt#Module, configuration: MakePomConfiguration, log: Logger): File = { import configuration.{ allRepositories, @@ -91,13 +91,12 @@ object IvyActions { val deliverIvyPattern = configuration.deliverIvyPattern .getOrElse(sys.error("deliverIvyPattern must be specified.")) val status = getDeliverStatus(configuration.status) - module.withModule(log) { - case (ivy, md, _) => - val revID = md.getModuleRevisionId - val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) - options.setConfs(getConfigurations(md, configuration.configurations)) - ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) - deliveredFile(ivy, deliverIvyPattern, md) + module.withModule(log) { case (ivy, md, _) => + val revID = md.getModuleRevisionId + val options = DeliverOptions.newInstance(ivy.getSettings).setStatus(status) + options.setConfs(getConfigurations(md, configuration.configurations)) + ivy.deliver(revID, revID.getRevision, deliverIvyPattern, options) + deliveredFile(ivy, deliverIvyPattern, md) } } @@ -130,18 +129,17 @@ object IvyActions { val artifacts = Map(configuration.artifacts: _*) val checksums = configuration.checksums - module.withModule(log) { - case (ivy, md, _) => - val resolver = ivy.getSettings.getResolver(resolverName) - if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") - val ivyArtifact = ivyFile map { file => - (MDArtifact.newIvyArtifact(md), file) - } - val cross = crossVersionMap(module.moduleSettings) - val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList - withChecksums(resolver, checksums) { - publish(md, as, resolver, overwrite = configuration.overwrite) - } + module.withModule(log) { case (ivy, md, _) => + val resolver = ivy.getSettings.getResolver(resolverName) + if (resolver eq null) sys.error("Undefined resolver '" + resolverName + "'") + val ivyArtifact = ivyFile map { file => + (MDArtifact.newIvyArtifact(md), file) + } + val cross = crossVersionMap(module.moduleSettings) + val as = mapArtifacts(md, cross, artifacts) ++ ivyArtifact.toList + withChecksums(resolver, checksums) { + publish(md, as, resolver, overwrite = configuration.overwrite) + } } } private[this] def withChecksums[T](resolver: DependencyResolver, checksums: Vector[String])( @@ -193,35 +191,36 @@ object IvyActions { uwconfig: UnresolvedWarningConfiguration, log: Logger ): Either[UnresolvedWarning, UpdateReport] = { - module.withModule(log) { - case (ivy, moduleDescriptor, _) => - // Warn about duplicated and inconsistent dependencies - val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) - iw.foreach(log.warn(_)) + module.withModule(log) { case (ivy, moduleDescriptor, _) => + // Warn about duplicated and inconsistent dependencies + val iw = IvySbt.inconsistentDuplicateWarning(moduleDescriptor) + iw.foreach(log.warn(_)) - val metadataDirectory = configuration.metadataDirectory + val metadataDirectory = configuration.metadataDirectory - // Create inputs, resolve and retrieve the module descriptor - val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) - val resolutionResult: Either[ResolveException, UpdateReport] = { - if (module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined) { - val cache = - metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) - cachedResolveAndRetrieve(inputs, cache) - } else resolveAndRetrieve(inputs) - } + // Create inputs, resolve and retrieve the module descriptor + val inputs = ResolutionInputs(ivy, moduleDescriptor, configuration, log) + val resolutionResult: Either[ResolveException, UpdateReport] = { + if ( + module.owner.configuration.updateOptions.cachedResolution && metadataDirectory.isDefined + ) { + val cache = + metadataDirectory.getOrElse(sys.error("Missing directory for cached resolution.")) + cachedResolveAndRetrieve(inputs, cache) + } else resolveAndRetrieve(inputs) + } - // Convert to unresolved warning or retrieve update report - resolutionResult.fold( - exception => Left(UnresolvedWarning(exception, uwconfig)), - ur0 => { - val ur = configuration.retrieveManaged match { - case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) - case _ => ur0 - } - Right(ur) + // Convert to unresolved warning or retrieve update report + resolutionResult.fold( + exception => Left(UnresolvedWarning(exception, uwconfig)), + ur0 => { + val ur = configuration.retrieveManaged match { + case Some(retrieveConf) => retrieve(log, ivy, ur0, retrieveConf) + case _ => ur0 } - ) + Right(ur) + } + ) } } @@ -252,11 +251,10 @@ object IvyActions { exclude.getOrElse(restrictedCopy(id, false), Set.empty[String]) def extractExcludes(report: UpdateReport): Map[ModuleID, Set[String]] = - report.allMissing flatMap { - case (_, mod, art) => - art.classifier.map { c => - (restrictedCopy(mod, false), c) - } + report.allMissing flatMap { case (_, mod, art) => + art.classifier.map { c => + (restrictedCopy(mod, false), c) + } } groupBy (_._1) map { case (mod, pairs) => (mod, pairs.map(_._2).toSet) } /** @@ -275,8 +273,8 @@ object IvyActions { ) implicit def toIvyFilter(f: ArtifactTypeFilter): IvyFilter = new IvyFilter { - override def accept(o: Object): Boolean = Option(o) exists { - case a: IArtifact => applyFilter(a) + override def accept(o: Object): Boolean = Option(o) exists { case a: IArtifact => + applyFilter(a) } def applyFilter(a: IArtifact): Boolean = @@ -498,13 +496,12 @@ object IvyActions { checkFilesPresent(artifacts) try { resolver.beginPublishTransaction(module.getModuleRevisionId(), overwrite); - artifacts.foreach { - case (artifact, file) => - IvyUtil.retryWithBackoff( - resolver.publish(artifact, file, overwrite), - TransientNetworkException.apply, - maxAttempts = LMSysProp.maxPublishAttempts - ) + artifacts.foreach { case (artifact, file) => + IvyUtil.retryWithBackoff( + resolver.publish(artifact, file, overwrite), + TransientNetworkException.apply, + maxAttempts = LMSysProp.maxPublishAttempts + ) } resolver.commitPublishTransaction() } catch { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index f5ae6d8fb..756fb0686 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -31,11 +31,11 @@ private object NotInCache { } } -/** Provides methods for working at the level of a single jar file with the default Ivy cache.*/ +/** Provides methods for working at the level of a single jar file with the default Ivy cache. */ class IvyCache(val ivyHome: Option[File]) { def lockFile = new File(ivyHome getOrElse Path.userHome, ".sbt.cache.lock") - /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID.*/ + /** Caches the given 'file' with the given ID. It may be retrieved or cleared using this ID. */ def cacheJar( moduleID: ModuleID, file: File, @@ -52,7 +52,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Clears the cache of the jar for the given ID.*/ + /** Clears the cache of the jar for the given ID. */ def clearCachedJar(id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger): Unit = { try { withCachedJar(id, lock, log)(_.delete); () @@ -61,7 +61,7 @@ class IvyCache(val ivyHome: Option[File]) { } } - /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown.*/ + /** Copies the cached jar for the given ID to the directory 'toDirectory'. If the jar is not in the cache, NotInCache is thrown. */ def retrieveCachedJar( id: ModuleID, toDirectory: File, @@ -74,7 +74,7 @@ class IvyCache(val ivyHome: Option[File]) { copyTo } - /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown .*/ + /** Get the location of the cached jar for the given ID in the Ivy cache. If the jar is not in the cache, NotInCache is thrown . */ def withCachedJar[T](id: ModuleID, lock: Option[xsbti.GlobalLock], log: Logger)( f: File => T ): T = { @@ -89,7 +89,7 @@ class IvyCache(val ivyHome: Option[File]) { if (cachedFile.exists) f(cachedFile) else throw new NotInCache(id) } - /** Calls the given function with the default Ivy cache.*/ + /** Calls the given function with the default Ivy cache. */ def withDefaultCache[T](lock: Option[xsbti.GlobalLock], log: Logger)( f: DefaultRepositoryCacheManager => T ): T = { @@ -103,7 +103,7 @@ class IvyCache(val ivyHome: Option[File]) { } private def unknownOrigin(artifact: IvyArtifact) = ArtifactOrigin.unkwnown(artifact) - /** A minimal Ivy setup with only a local resolver and the current directory as the base directory.*/ + /** A minimal Ivy setup with only a local resolver and the current directory as the base directory. */ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal val paths = IvyPaths(new File("."), ivyHome) @@ -115,12 +115,12 @@ class IvyCache(val ivyHome: Option[File]) { (new IvySbt(conf), local) } - /** Creates a default jar artifact based on the given ID.*/ + /** Creates a default jar artifact based on the given ID. */ private def defaultArtifact(moduleID: ModuleID): IvyArtifact = new DefaultArtifact(IvySbt.toID(moduleID), null, moduleID.name, "jar", "jar") } -/** Required by Ivy for copying to the cache.*/ +/** Required by Ivy for copying to the cache. */ private class FileDownloader extends ResourceDownloader { def download(artifact: IvyArtifact, resource: Resource, dest: File): Unit = { if (dest.exists()) dest.delete() diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala index 29f61222a..dd0416399 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyLogger.scala @@ -19,7 +19,7 @@ private[sbt] final class IvyLoggerInterface(logger: Logger) extends MessageLogge case MSG_ERR => error(msg) } } - //DEBUG level messages are very verbose and rarely useful to users. + // DEBUG level messages are very verbose and rarely useful to users. // TODO: provide access to this information some other way def debug(msg: String): Unit = () def verbose(msg: String): Unit = logger.verbose(msg) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index a6d2604ce..3e1d5f32f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -54,14 +54,18 @@ object IvyRetrieve { private[sbt] def organizationArtifactReports( confReport: ConfigurationResolveReport ): Vector[OrganizationArtifactReport] = { - val moduleIds = confReport.getModuleIds.toArray.toVector collect { - case mId: IvyModuleId => mId + val moduleIds = confReport.getModuleIds.toArray.toVector collect { case mId: IvyModuleId => + mId } def organizationArtifact(mid: IvyModuleId): OrganizationArtifactReport = { val deps = confReport.getNodes(mid).toArray.toVector collect { case node: IvyNode => node } - OrganizationArtifactReport(mid.getOrganisation, mid.getName, deps map { - moduleRevisionDetail(confReport, _) - }) + OrganizationArtifactReport( + mid.getOrganisation, + mid.getName, + deps map { + moduleRevisionDetail(confReport, _) + } + ) } moduleIds map { organizationArtifact } } @@ -141,9 +145,13 @@ object IvyRetrieve { val edOpt = Option(dep.getEvictedData(confReport.getConfiguration)) edOpt match { case Some(ed) => - (true, nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { - "transitive" - }), nonEmptyString(ed.getDetail)) + ( + true, + nonEmptyString(Option(ed.getConflictManager) map { _.toString } getOrElse { + "transitive" + }), + nonEmptyString(ed.getDetail) + ) case None => (true, None, None) } case _ => (false, None, None) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala index 3ea763301..bb2701818 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyScalaUtil.scala @@ -67,9 +67,11 @@ object IvyScalaUtil { new NamespaceTransformer { def transform(mrid: ModuleRevisionId): ModuleRevisionId = { if (mrid == null) mrid - else if ((isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && - configQualifies && - dependeeQualifies) { + else if ( + (isScala2Artifact(mrid.getName) || isScala3Artifact(mrid.getName)) && + configQualifies && + dependeeQualifies + ) { // do not override the binary incompatible Scala version because: // - the artifacts compiled with Scala 3 depends on the Scala 2.13 scala-library // - the Scala 2 TASTy reader can consume the Scala 3 artifacts @@ -152,7 +154,8 @@ object IvyScalaUtil { .forall(bv => bv.startsWith("3") || bv.startsWith("2.13")) def matchesOneOfTheConfigs = dep.getModuleConfigurations exists { scalaVersionConfigs } - val mismatched = isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs + val mismatched = + isScalaLangOrg && isScalaArtifact && hasBinVerMismatch && matchesOneOfTheConfigs if (mismatched) Some( "Binary version (" + depBinaryVersion + ") for dependency " + id + diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala index c6d3da447..5c381913a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ResolutionCache.scala @@ -102,5 +102,6 @@ private[sbt] object ResolutionCache { private val Name = "sbt-resolution-cache" // use sbt-specific extra attributes so that resolved xml files do not get overwritten when using different Scala/sbt versions - private val ResolvedPattern = "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" + private val ResolvedPattern = + "[organisation]/[module]/" + Resolver.PluginPattern + "([branch]/)[revision]/[artifact].[ext]" } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 7d94bca6d..7dc600e13 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -105,7 +105,7 @@ private[sbt] class CachedResolutionResolveCache { s"""Include(${rule.getId},${rule.getConfigurations.mkString(",")},${rule.getMatcher})""" def artifactString(dad: DependencyArtifactDescriptor): String = s"""Artifact(${dad.getName},${dad.getType},${dad.getExt},${dad.getUrl},${dad.getConfigurations - .mkString(",")},${dad.getExtraAttributes})""" + .mkString(",")},${dad.getExtraAttributes})""" val mrid = dd.getDependencyRevisionId val confMap = (dd.getModuleConfigurations map { conf => conf + "->(" + dd.getDependencyConfigurations(conf).mkString(",") + ")" @@ -127,9 +127,13 @@ private[sbt] class CachedResolutionResolveCache { val mesStr = (mes map excludeRuleString).mkString(",") val os = extractOverrides(parent) val moduleLevel = s"""dependencyOverrides=${os.mkString(",")};moduleExclusions=$mesStr""" - val depsString = s"""$mrid;${confMap.mkString(",")};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + - s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString(",")};explicitArtifacts=${explicitArtifacts - .mkString(",")};$moduleLevel;""" + val depsString = s"""$mrid;${confMap.mkString( + "," + )};isForce=${dd.isForce};isChanging=${dd.isChanging};isTransitive=${dd.isTransitive};""" + + s"""exclusions=${exclusions.mkString(",")};inclusions=${inclusions.mkString( + "," + )};explicitArtifacts=${explicitArtifacts + .mkString(",")};$moduleLevel;""" val sha1 = Hash.toHex( Hash(s"""graphVersion=${CachedResolutionResolveCache.graphVersion};$depsString""") ) @@ -158,15 +162,14 @@ private[sbt] class CachedResolutionResolveCache { md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { case (k, _) => k.toString - } collect { - case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => - val attr: Map[Any, Any] = k.getAttributes.asScala.toMap - val module = IvyModuleId.newInstance( - attr(IvyPatternHelper.ORGANISATION_KEY).toString, - attr(IvyPatternHelper.MODULE_KEY).toString - ) - val pm = k.getPatternMatcher - IvyOverride(module, pm, v) + } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => + val attr: Map[Any, Any] = k.getAttributes.asScala.toMap + val module = IvyModuleId.newInstance( + attr(IvyPatternHelper.ORGANISATION_KEY).toString, + attr(IvyPatternHelper.MODULE_KEY).toString + ) + val pm = k.getPatternMatcher + IvyOverride(module, pm, v) } } def getOrElseUpdateMiniGraph( @@ -200,8 +203,10 @@ private[sbt] class CachedResolutionResolveCache { } val staticGraphDirectory = miniGraphPath / "static" val dynamicGraphDirectory = miniGraphPath / "dynamic" - val staticGraphPath = staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" - val dynamicGraphPath = dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val staticGraphPath = + staticGraphDirectory / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" + val dynamicGraphPath = + dynamicGraphDirectory / todayStr / logicalClock.toString / pathScalaVersion / pathSbtVersion / pathOrg / pathName / pathRevision / "graphs" / "graph.json" def cleanDynamicGraph(): Unit = { val list = IO.listFiles(dynamicGraphDirectory, DirectoryFilter).toList list filterNot { d => @@ -282,9 +287,12 @@ private[sbt] class CachedResolutionResolveCache { val moduleIdMap = Map(conflicts map { x => x.module -> x }: _*) - (surviving map moduleIdMap, evicted map moduleIdMap map { - _.withEvicted(true).withEvictedReason(Some(mgr.toString)) - }) + ( + surviving map moduleIdMap, + evicted map moduleIdMap map { + _.withEvicted(true).withEvictedReason(Some(mgr.toString)) + } + ) } (conflictCache get ((cf0, cf1))) match { case Some((surviving, evicted, mgr)) => reconstructReports(surviving, evicted, mgr) @@ -410,59 +418,58 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { Left(new ResolveException(messages, failed, failedPaths)) } } - val (internal, external) = mds.partition { - case (_, _, dd) => cache.internalDependency(dd, projectResolver).isDefined + val (internal, external) = mds.partition { case (_, _, dd) => + cache.internalDependency(dd, projectResolver).isDefined } - val internalResults = internal map { - case (md, changing, dd) => - cache.getOrElseUpdateMiniGraph( - md, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md, dd) - } + val internalResults = internal map { case (md, changing, dd) => + cache.getOrElseUpdateMiniGraph( + md, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md, dd) + } } - val externalResults = external map { - case (md0, changing, dd) => - val configurationsInInternal = internalResults flatMap { - case Right(ur) => - ur.allModules.flatMap { - case md => - val sameName = md.name == dd.getDependencyId.getName - val sameOrg = md.organization == dd.getDependencyId.getOrganisation - if (sameName && sameOrg) md.configurations - else None + val externalResults = external map { case (md0, changing, dd) => + val configurationsInInternal = internalResults flatMap { + case Right(ur) => + ur.allModules.flatMap { case md => + val sameName = md.name == dd.getDependencyId.getName + val sameOrg = md.organization == dd.getDependencyId.getOrganisation + if (sameName && sameOrg) md.configurations + else None + } + case _ => Nil + } + + dd match { + case d: DefaultDependencyDescriptor => + configurationsInInternal foreach { c => + val configurations = c.split(";").map(_.split("->")) + configurations foreach { conf => + try d.addDependencyConfiguration(conf(0), conf(1)) + catch { + case _: Throwable => () + } // An exception will be thrown if `conf(0)` doesn't exist. } - case _ => Nil - } + } - dd match { - case d: DefaultDependencyDescriptor => - configurationsInInternal foreach { c => - val configurations = c.split(";").map(_.split("->")) - configurations foreach { conf => - try d.addDependencyConfiguration(conf(0), conf(1)) - catch { case _: Throwable => () } // An exception will be thrown if `conf(0)` doesn't exist. - } - } + case _ => () + } - case _ => () - } - - cache.getOrElseUpdateMiniGraph( - md0, - changing, - logicalClock, - miniGraphPath, - cachedDescriptor, - log - ) { - doWork(md0, dd) - } + cache.getOrElseUpdateMiniGraph( + md0, + changing, + logicalClock, + miniGraphPath, + cachedDescriptor, + log + ) { + doWork(md0, dd) + } } val results = internalResults ++ externalResults val uReport = @@ -485,21 +492,20 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { log: Logger ): Either[ResolveException, UpdateReport] = if (!missingOk && (results exists { _.isLeft })) - Left(mergeErrors(md0, results collect { case Left(re) => re })) + Left(mergeErrors(md0, results collect { case Left(re) => re })) else Right(mergeReports(md0, results collect { case Right(ur) => ur }, resolveTime, os, log)) def mergeErrors(md0: ModuleDescriptor, errors: Vector[ResolveException]): ResolveException = { val messages = errors flatMap { _.messages } val failed = errors flatMap { _.failed } val failedPaths = errors flatMap { - _.failedPaths.toList map { - case (failed, paths) => - if (paths.isEmpty) (failed, paths) - else - ( - failed, - List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail - ) + _.failedPaths.toList map { case (failed, paths) => + if (paths.isEmpty) (failed, paths) + else + ( + failed, + List(IvyRetrieve.toModuleID(md0.getResolvedModuleRevisionId)) ::: paths.toList.tail + ) } } new ResolveException(messages, failed, ListMap(failedPaths: _*)) @@ -579,12 +585,11 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // this might take up some memory, but it's limited to a single val reports1 = reports0 flatMap { filterReports } val allModules0: Map[(String, String), Vector[OrganizationArtifactReport]] = - Map(orgNamePairs map { - case (organization, name) => - val xs = reports1 filter { oar => - oar.organization == organization && oar.name == name - } - ((organization, name), xs) + Map(orgNamePairs map { case (organization, name) => + val xs = reports1 filter { oar => + oar.organization == organization && oar.name == name + } + ((organization, name), xs) }: _*) // this returns a List of Lists of (org, name). should be deterministic def detectLoops( @@ -766,8 +771,8 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { val completelyEvicted = xs forall { _.evicted } val allCallers = xs flatMap { _.callers } // Caller info is often repeated across the subprojects. We only need ModuleID info for later, so xs.head is ok. - val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { - case (_, xs) => xs.head + val distinctByModuleId = allCallers.groupBy({ _.caller }).toVector map { case (_, xs) => + xs.head } val allArtifacts = (xs flatMap { _.artifacts }).distinct xs.head @@ -777,10 +782,9 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) - }).toSeq.toVector flatMap { - case (_, xs) => - if (xs.size < 2) xs - else Vector(mergeModuleReports(xs)) + }).toSeq.toVector flatMap { case (_, xs) => + if (xs.size < 2) xs + else Vector(mergeModuleReports(xs)) } val conflicts = merged filter { m => !m.evicted && m.problem.isEmpty @@ -789,9 +793,12 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { else resolveConflict(rootModuleConf, conflicts, os, log) match { case (survivor, evicted) => - (survivor ++ (merged filter { m => - m.evicted || m.problem.isDefined - }), evicted) + ( + survivor ++ (merged filter { m => + m.evicted || m.problem.isDefined + }), + evicted + ) } } @@ -869,9 +876,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }) match { case Some(m) => log.debug(s"- directly forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("direct-force")) - }, "direct-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("direct-force")) + }, + "direct-force" + ) case None => (conflicts find { m => m.callers.exists { _.isForceDependency } @@ -879,18 +890,26 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { // Ivy translates pom.xml dependencies to forced="true", so transitive force is broken. case Some(m) if !ignoreTransitiveForce => log.debug(s"- transitively forced dependency: $m ${m.callers}") - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("transitive-force")) - }, "transitive-force") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("transitive-force")) + }, + "transitive-force" + ) case _ => val strategy = lcm.getStrategy val infos = conflicts map { ModuleReportArtifactInfo(_) } log.debug(s"- Using $strategy with $infos") Option(strategy.findLatest(infos.toArray, None.orNull)) match { case Some(ModuleReportArtifactInfo(m)) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some(lcm.toString)) - }, lcm.toString) + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some(lcm.toString)) + }, + lcm.toString + ) case _ => (conflicts, Vector(), lcm.toString) } } @@ -905,9 +924,13 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { mr.module.revision == ovrVersion } match { case Some(m) => - (Vector(m), conflicts filterNot { _ == m } map { - _.withEvicted(true).withEvictedReason(Some("override")) - }, "override") + ( + Vector(m), + conflicts filterNot { _ == m } map { + _.withEvicted(true).withEvictedReason(Some("override")) + }, + "override" + ) case None => sys.error( s"override dependency specifies $ovrVersion but no candidates were found: " + (conflicts map { @@ -925,7 +948,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }).mkString("(", ", ", ")")) ) case lcm: LatestConflictManager => useLatest(lcm) - case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") + case conflictManager => sys.error(s"Unsupported conflict manager $conflictManager") } } if (conflicts.size == 2 && os.isEmpty) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index 2ba03b741..478462e8d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -64,10 +64,14 @@ object ErrorMessageAuthenticator { ivyOriginalField.set(ivy, newOriginal) } - try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some(_: ErrorMessageAuthenticator) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) - } catch { + try + Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { + case Some( + _: ErrorMessageAuthenticator + ) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) + } + catch { case t: Throwable => Message.debug( "Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage @@ -135,16 +139,17 @@ private[sbt] final class ErrorMessageAuthenticator(original: Option[Authenticato // Grabs the authentication that would have been provided had we not been installed... def originalAuthentication: Option[PasswordAuthentication] = { Authenticator.setDefault(original.orNull) - try Option( - Authenticator.requestPasswordAuthentication( - getRequestingHost, - getRequestingSite, - getRequestingPort, - getRequestingProtocol, - getRequestingPrompt, - getRequestingScheme + try + Option( + Authenticator.requestPasswordAuthentication( + getRequestingHost, + getRequestingSite, + getRequestingPort, + getRequestingProtocol, + getRequestingPrompt, + getRequestingScheme + ) ) - ) finally Authenticator.setDefault(this) } originalAuthentication.orNull diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index 4d1e92420..9d8148323 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -56,8 +56,8 @@ private[sbt] object IvyCredentialsLookup { * A mapping of host -> realms in the ivy credentials store. */ def realmsForHost: Map[String, Set[String]] = - (keyringKeys collect { - case x: Realm => x + (keyringKeys collect { case x: Realm => + x } groupBy { realm => realm.host } mapValues { realms => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 1c9f2e7de..765360d90 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -13,14 +13,14 @@ private[sbt] object MergeDescriptors { a.isTransitive == b.isTransitive && a.getParentRevisionId == b.getParentRevisionId && a.getNamespace == b.getNamespace && { - val amrid = a.getDependencyRevisionId - val bmrid = b.getDependencyRevisionId - amrid == bmrid - } && { - val adyn = a.getDynamicConstraintDependencyRevisionId - val bdyn = b.getDynamicConstraintDependencyRevisionId - adyn == bdyn - } + val amrid = a.getDependencyRevisionId + val bmrid = b.getDependencyRevisionId + amrid == bmrid + } && { + val adyn = a.getDynamicConstraintDependencyRevisionId + val bdyn = b.getDynamicConstraintDependencyRevisionId + adyn == bdyn + } def apply(a: DependencyDescriptor, b: DependencyDescriptor): DependencyDescriptor = { assert(mergeable(a, b)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 9af7ef6cb..711e03225 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -48,17 +48,18 @@ private[sbt] class ParallelResolveEngine( } // Farm out the dependencies for parallel download implicit val ec = ParallelResolveEngine.resolveExecutionContext - val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { - case dep: IvyNode => - Future { - if (!(dep.isCompletelyEvicted || dep.hasProblem) && - dep.getModuleRevision != null) { - Some(downloadNodeArtifacts(dep, artifactFilter, options)) - } else None - } + val allDownloadsFuture = Future.traverse(report.getDependencies.asScala) { case dep: IvyNode => + Future { + if ( + !(dep.isCompletelyEvicted || dep.hasProblem) && + dep.getModuleRevision != null + ) { + Some(downloadNodeArtifacts(dep, artifactFilter, options)) + } else None + } } val allDownloads = Await.result(allDownloadsFuture, Duration.Inf) - //compute total downloaded size + // compute total downloaded size val totalSize = allDownloads.foldLeft(0L) { case (size, Some(download)) => val dependency = download.dep @@ -67,8 +68,10 @@ private[sbt] class ParallelResolveEngine( val configurationReport = report.getConfigurationReport(configuration) // Take into account artifacts required by the given configuration - if (dependency.isEvicted(configuration) || - dependency.isBlacklisted(configuration)) { + if ( + dependency.isEvicted(configuration) || + dependency.isBlacklisted(configuration) + ) { configurationReport.addDependency(dependency) } else configurationReport.addDependency(dependency, download.report) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 2314838ef..9dfd3b83f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -37,9 +37,9 @@ private[sbt] case class SbtChainResolver( override def equals(o: Any): Boolean = o match { case o: SbtChainResolver => this.name == o.name && - this.resolvers == o.resolvers && - this.settings == o.settings && - this.updateOptions == o.updateOptions + this.resolvers == o.resolvers && + this.settings == o.settings && + this.updateOptions == o.updateOptions case _ => false } @@ -124,7 +124,8 @@ private[sbt] case class SbtChainResolver( /** If None, module was not found. Otherwise, hit. */ type TriedResolution = Option[(ResolvedModuleRevision, DependencyResolver)] - /** Attempts to resolve the artifact from each of the resolvers in the chain. + /** + * Attempts to resolve the artifact from each of the resolvers in the chain. * * Contract: * 1. It doesn't resolve anything when there is a resolved module, `isReturnFirst` is @@ -155,8 +156,8 @@ private[sbt] case class SbtChainResolver( currentlyResolved = Option(resolver.getDependency(descriptor, data)) if (currentlyResolved eq previouslyResolved) None else if (useLatest) { - currentlyResolved.map( - x => (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) + currentlyResolved.map(x => + (reparseModuleDescriptor(descriptor, data, resolver, x), resolver) ) } else currentlyResolved.map(x => (forcedRevision(x), resolver)) } @@ -174,7 +175,8 @@ private[sbt] case class SbtChainResolver( val oldLatest: Option[LatestStrategy] = setLatestIfRequired(resolver, Option(getLatestStrategy)) try Right(performResolution(resolver)) - catch { case NonFatal(t) => reportError(t, resolver); Left(t) } finally { + catch { case NonFatal(t) => reportError(t, resolver); Left(t) } + finally { oldLatest.foreach(_ => doSetLatestStrategy(resolver, oldLatest)) checkInterrupted() } @@ -189,34 +191,33 @@ private[sbt] case class SbtChainResolver( data: ResolveData ): Option[ResolvedModuleRevision] = { - val sortedRevisions = foundRevisions.sortBy { - case (rmr, resolver) => - val publicationDate = rmr.getPublicationDate - val descriptorDate = rmr.getDescriptor.getPublicationDate - Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") - // Just issue warning about issues with publication date, and fake one on it for now - val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) - chosenPublicationDate match { - case Some(date) => date.getTime - case None => - val id = rmr.getId - val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) - resolvedResource match { - case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => - val resolvedPublicationDate = new java.util.Date(res.getLastModified) - Message.debug(s"No publication date from resolver $resolver for $id.") - Message.debug(s"Setting publication date to: $resolvedPublicationDate.") - dmd.setPublicationDate(resolvedPublicationDate) - res.getLastModified - case (ivf, dmd) => - // The dependency is specified by a direct URL or some sort of non-ivy file - if (ivf == null && descriptor.isChanging) - Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") - if (dmd == null) - Message.warn(s"$prefix: no publication date from resolver $resolver for $id") - 0L - } - } + val sortedRevisions = foundRevisions.sortBy { case (rmr, resolver) => + val publicationDate = rmr.getPublicationDate + val descriptorDate = rmr.getDescriptor.getPublicationDate + Message.warn(s"Sorting results from $rmr, using $publicationDate and $descriptorDate.") + // Just issue warning about issues with publication date, and fake one on it for now + val chosenPublicationDate = Option(publicationDate).orElse(Option(descriptorDate)) + chosenPublicationDate match { + case Some(date) => date.getTime + case None => + val id = rmr.getId + val resolvedResource = (resolver.findIvyFileRef(descriptor, data), rmr.getDescriptor) + resolvedResource match { + case (res: ResolvedResource, dmd: DefaultModuleDescriptor) => + val resolvedPublicationDate = new java.util.Date(res.getLastModified) + Message.debug(s"No publication date from resolver $resolver for $id.") + Message.debug(s"Setting publication date to: $resolvedPublicationDate.") + dmd.setPublicationDate(resolvedPublicationDate) + res.getLastModified + case (ivf, dmd) => + // The dependency is specified by a direct URL or some sort of non-ivy file + if (ivf == null && descriptor.isChanging) + Message.warn(s"$prefix: changing dependency $id with no ivy/pom file!") + if (dmd == null) + Message.warn(s"$prefix: no publication date from resolver $resolver for $id") + 0L + } + } } val firstHit = sortedRevisions.reverse.headOption @@ -233,7 +234,7 @@ private[sbt] case class SbtChainResolver( val (module, resolver) = h Message.info( s"Out of ${sortedRevisions.size} candidates we found for ${module.getId} in ${resolvers - .mkString(" and ")}, we are choosing ${resolver}." + .mkString(" and ")}, we are choosing ${resolver}." ) }) } else { @@ -277,12 +278,11 @@ private[sbt] case class SbtChainResolver( } /** Cleans unnecessary module id information not provided by [[IvyRetrieve.toModuleID()]]. */ - private final val moduleResolvers = updateOptions.moduleResolvers.map { - case (key, value) => - val cleanKey = ModuleID(key.organization, key.name, key.revision) - .withExtraAttributes(key.extraAttributes) - .withBranchName(key.branchName) - cleanKey -> value + private final val moduleResolvers = updateOptions.moduleResolvers.map { case (key, value) => + val cleanKey = ModuleID(key.organization, key.name, key.revision) + .withExtraAttributes(key.extraAttributes) + .withBranchName(key.branchName) + cleanKey -> value } /** @@ -309,7 +309,8 @@ private[sbt] case class SbtChainResolver( def findInterProjectResolver(resolvers: Seq[DependencyResolver]): Option[DependencyResolver] = resolvers.find(_.getName == ProjectResolver.InterProject) - /** Gets the dependency for a given descriptor with the pertinent resolve data. + /** + * Gets the dependency for a given descriptor with the pertinent resolve data. * * This is a custom sbt chain operation that produces better error output and deals with * cases that the conventional ivy resolver does not. It accumulates the resolution of diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 458972409..6d65f72f3 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -16,11 +16,11 @@ object Credentials { def apply(file: File): Credentials = new FileCredentials(file) - /** Add the provided credentials to Ivy's credentials cache.*/ + /** Add the provided credentials to Ivy's credentials cache. */ def add(realm: String, host: String, userName: String, passwd: String): Unit = CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd) - /** Load credentials from the given file into Ivy's credentials cache.*/ + /** Load credentials from the given file into Ivy's credentials cache. */ def add(path: File, log: Logger): Unit = loadCredentials(path) match { case Left(err) => log.warn(err) diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala index 0a41509bb..1fa856d0e 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/UpdateOptions.scala @@ -79,12 +79,12 @@ final class UpdateOptions private[sbt] ( override def equals(o: Any): Boolean = o match { case o: UpdateOptions => this.circularDependencyLevel == o.circularDependencyLevel && - this.interProjectFirst == o.interProjectFirst && - this.latestSnapshots == o.latestSnapshots && - this.cachedResolution == o.cachedResolution && - this.gigahorse == o.gigahorse && - this.resolverConverter == o.resolverConverter && - this.moduleResolvers == o.moduleResolvers + this.interProjectFirst == o.interProjectFirst && + this.latestSnapshots == o.latestSnapshots && + this.cachedResolution == o.cachedResolution && + this.gigahorse == o.gigahorse && + this.resolverConverter == o.resolverConverter && + this.moduleResolvers == o.moduleResolvers case _ => false } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala index dc2947e26..15a68f70e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ComponentManagerTest.scala @@ -121,7 +121,7 @@ object ComponentManagerTest extends BasicTestSuite { TestLogger { logger => withTemporaryDirectory { temp => // The actual classes we'll use at runtime. - //val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) + // val mgr = new ComponentManager(xsbt.boot.Locks, new xsbt.boot.ComponentProvider(temp, true), Some(ivyHome), logger) // A stub component manager object provider extends ComponentProvider { diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala index e546f9758..13189de5b 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/CredentialsSpec.scala @@ -28,12 +28,22 @@ class CredentialsSpec extends AnyFunSuite { test("DirectCredentials.toString") { assert( - Credentials(realm = null, host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = null, + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials(null, "example.org", "username", ****)""" ) assert( - Credentials(realm = "realm", host = "example.org", userName = "username", passwd = "password").toString == + Credentials( + realm = "realm", + host = "example.org", + userName = "username", + passwd = "password" + ).toString == """DirectCredentials("realm", "example.org", "username", ****)""" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala index f4b2c53e2..2d02e2896 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionErrorSpec.scala @@ -118,11 +118,17 @@ object EvictionErrorSpec extends BaseIvySpecification { def oldAkkaPvp = List("com.typesafe.akka" % "*" % "pvp") lazy val `akkaActor2.1.4` = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `akkaActor2.3.0` = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `akkaActor2.6.0` = - ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.6.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary lazy val `scala2.10.4` = ModuleID("org.scala-lang", "scala-library", "2.10.4").withConfigurations(Some("compile")) lazy val `scala2.12.17` = @@ -130,9 +136,13 @@ object EvictionErrorSpec extends BaseIvySpecification { lazy val `scala2.13.3` = ModuleID("org.scala-lang", "scala-library", "2.13.3").withConfigurations(Some("compile")) lazy val `bananaSesame0.4` = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 lazy val `akkaRemote2.3.4` = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 lazy val `http4s0.21.11` = ("org.http4s" %% "http4s-blaze-server" % "0.21.11").withConfigurations(Some("compile")) // https://repo1.maven.org/maven2/org/typelevel/cats-effect_2.13/3.0.0-M4/cats-effect_2.13-3.0.0-M4.pom diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala index 09975ba5f..4f8ded23f 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/EvictionWarningSpec.scala @@ -20,7 +20,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2"), overrideScalaVersion = false) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -79,7 +83,11 @@ object EvictionWarningSpec extends BaseIvySpecification { val m = module(defaultModuleId, scalaVersionDeps, Some("2.10.2")) val report = ivyUpdate(m) assert( - EvictionWarning(m, fullOptions.withWarnScalaVersionEviction(false), report).scalaEvictions.size == 0 + EvictionWarning( + m, + fullOptions.withWarnScalaVersionEviction(false), + report + ).scalaEvictions.size == 0 ) } @@ -302,11 +310,17 @@ object EvictionWarningSpec extends BaseIvySpecification { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor234 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def scala2102 = ModuleID("org.scala-lang", "scala-library", "2.10.2").withConfigurations(Some("compile")) def scala2103 = @@ -317,13 +331,21 @@ object EvictionWarningSpec extends BaseIvySpecification { def commonsIo14 = ModuleID("commons-io", "commons-io", "1.4").withConfigurations(Some("compile")) def commonsIo24 = ModuleID("commons-io", "commons-io", "2.4").withConfigurations(Some("compile")) def bnfparser10 = - ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations(Some("compile")) // uses commons-io 2.4 + ModuleID("ca.gobits.bnf", "bnfparser", "1.0").withConfigurations( + Some("compile") + ) // uses commons-io 2.4 def unfilteredUploads080 = - ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations(Some("compile")) cross CrossVersion.binary // uses commons-io 1.4 + ModuleID("net.databinder", "unfiltered-uploads", "0.8.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses commons-io 1.4 def bananaSesame04 = - ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.1.4 + ModuleID("org.w3", "banana-sesame", "0.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.1.4 def akkaRemote234 = - ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations(Some("compile")) cross CrossVersion.binary // uses akka-actor 2.3.4 + ModuleID("com.typesafe.akka", "akka-remote", "2.3.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary // uses akka-actor 2.3.4 def fullOptions = EvictionWarningOptions.full def javaLibDirectDeps = Vector(commonsIo14, commonsIo24) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala index db9344070..46e830c04 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InconsistentDuplicateSpec.scala @@ -24,9 +24,15 @@ object InconsistentDuplicateSpec extends BasicTestSuite { } def akkaActor214 = - ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.1.4").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230 = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("compile")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("compile") + ) cross CrossVersion.binary def akkaActor230Test = - ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations(Some("test")) cross CrossVersion.binary + ModuleID("com.typesafe.akka", "akka-actor", "2.3.0").withConfigurations( + Some("test") + ) cross CrossVersion.binary } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index 97515d9ef..c3235b934 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -17,7 +17,7 @@ object IvyRepoSpec extends BaseIvySpecification { module( ourModuleID, Vector(dep), - None //, UpdateOptions().withCachedResolution(true) + None // , UpdateOptions().withCachedResolution(true) ) } @@ -31,13 +31,11 @@ object IvyRepoSpec extends BaseIvySpecification { val report = ivyUpdate(m) import Inside._ - inside(report.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.`type` == "jar") - assert(ar.extension == "jar") - } + inside(report.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.`type` == "jar") + assert(ar.extension == "jar") + } } } @@ -90,14 +88,12 @@ object IvyRepoSpec extends BaseIvySpecification { .get import Inside._ - inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { - case Some(Seq(mr)) => - inside(mr.artifacts) { - case Seq((ar, _)) => - assert(ar.name == "libmodule-source") - assert(ar.`type` == "src") - assert(ar.extension == "jar") - } + inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => + inside(mr.artifacts) { case Seq((ar, _)) => + assert(ar.name == "libmodule-source") + assert(ar.`type` == "src") + assert(ar.extension == "jar") + } } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala index 898402224..780613096 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/MergeDescriptorSpec.scala @@ -14,20 +14,19 @@ object MergeDescriptorSpec extends BaseIvySpecification { None, UpdateOptions() ) - m.withModule(log) { - case (_, md, _) => - val deps = md.getDependencies - assert(deps.size == 1) - deps.headOption.getOrElse(sys.error("Dependencies not found")) match { - case dd @ MergedDescriptors(_, _) => - val arts = dd.getAllDependencyArtifacts - val a0: DependencyArtifactDescriptor = arts.toList(0) - val a1: DependencyArtifactDescriptor = arts.toList(1) - val configs0 = a0.getConfigurations.toList - val configs1 = a1.getConfigurations.toList - assert(configs0 == List("compile")) - assert(configs1 == List("test")) - } + m.withModule(log) { case (_, md, _) => + val deps = md.getDependencies + assert(deps.size == 1) + deps.headOption.getOrElse(sys.error("Dependencies not found")) match { + case dd @ MergedDescriptors(_, _) => + val arts = dd.getAllDependencyArtifacts + val a0: DependencyArtifactDescriptor = arts.toList(0) + val a1: DependencyArtifactDescriptor = arts.toList(1) + val configs0 = a0.getConfigurations.toList + val configs1 = a1.getConfigurations.toList + assert(configs0 == List("compile")) + assert(configs1 == List("test")) + } } } def guavaTest = diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala index 2bf13668d..c131e2900 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/SftpRepoSpec.scala @@ -13,7 +13,7 @@ import java.nio.file.Paths object SftpRepoSpec extends BaseIvySpecification { val repo: Option[String] = None // val repo: Option[String] = Some("some repo") - //a dependency which depends on another in the repo + // a dependency which depends on another in the repo def org(repo: String) = s"com.${repo}" def module(org: String) = org % "some-lib" % "version" diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index 4921e09fe..3d29c00d1 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -31,8 +31,8 @@ object HouseRulesPlugin extends AutoPlugin { scalacOptions += "-Ywarn-numeric-widen", scalacOptions += "-Ywarn-value-discard", scalacOptions ++= "-Ywarn-unused-import".ifScala(v => 11 <= v && v <= 12).value.toList - ) ++ Seq(Compile, Test).flatMap( - c => (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") + ) ++ Seq(Compile, Test).flatMap(c => + (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") ) private def scalaPartV = Def setting (CrossVersion partialVersion scalaVersion.value) diff --git a/project/Util.scala b/project/Util.scala index 172b36423..88517e668 100644 --- a/project/Util.scala +++ b/project/Util.scala @@ -30,7 +30,9 @@ object Util { val f = dir / "xsbt.version.properties" // TODO: replace lastModified() with sbt.io.IO.getModifiedTimeOrZero(), once the build // has been upgraded to a version of sbt that includes that call. - if (!f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version)) { + if ( + !f.exists || f.lastModified < lastCompilationTime(analysis) || !containsVersion(f, version) + ) { s.log.info("Writing version information to " + f + " :\n" + content) IO.write(f, content) } From 1dd9c5c0e7bf099447e958f045b50d768cad8fc4 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 25 Jun 2023 21:01:05 -0400 Subject: [PATCH 0982/1030] Util 1.9.1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index cd168495a..ae2fb420e 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.0") - private val utilVersion = nightlyVersion.getOrElse("1.9.0") + private val ioVersion = nightlyVersion.getOrElse("1.9.1") + private val utilVersion = nightlyVersion.getOrElse("1.9.1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From f12bd96ff1cbf6069f92e1ca95dc503663162a06 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 25 Jun 2023 21:02:59 -0400 Subject: [PATCH 0983/1030] CLA --- .github/workflows/cla.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/cla.yml diff --git a/.github/workflows/cla.yml b/.github/workflows/cla.yml new file mode 100644 index 000000000..abbf9f3ba --- /dev/null +++ b/.github/workflows/cla.yml @@ -0,0 +1,24 @@ +name: Scala CLA +on: [pull_request] +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Check CLA + env: + AUTHOR: ${{ github.event.pull_request.user.login }} + run: | + echo "Pull request submitted by $AUTHOR"; + signed=$(curl -s "https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR" | jq -r ".signed"); + if [ "$signed" = "true" ] ; then + echo "CLA check for $AUTHOR successful"; + else + echo "CLA check for $AUTHOR failed"; + echo "Please sign the Scala CLA to contribute to the Scala compiler."; + echo "Go to https://www.lightbend.com/contribute/cla/scala and then"; + echo "comment on the pull request to ask for a new check."; + echo ""; + echo "Check if CLA is signed: https://www.lightbend.com/contribute/cla/scala/check/$AUTHOR"; + exit 1; + fi; From 10a79d6001a6c43a9cdf66a7c5c96748222c8f61 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Thu, 27 Jul 2023 10:15:14 +0200 Subject: [PATCH 0984/1030] Add Apache staging repo --- .../src/main/scala/sbt/librarymanagement/ResolverExtra.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index a070c049c..ca980b7e8 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -186,6 +186,11 @@ private[librarymanagement] abstract class ResolverFunctions { "https://repository.apache.org/content/repositories/snapshots/" ) + val ApacheMavenStagingRepo = MavenRepository( + "apache-staging", + "https://repository.apache.org/content/groups/staging/" + ) + /** Add the local and Maven Central repositories to the user repositories. */ def combineDefaultResolvers(userResolvers: Vector[Resolver]): Vector[Resolver] = combineDefaultResolvers(userResolvers, mavenCentral = true) From 824cca75d23fb2aab7108450fe44a907beddf96c Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 24 Aug 2023 10:36:27 -0400 Subject: [PATCH 0985/1030] Bump to Ivy 2.3.0-sbt-396a783bba347016e7fe30dacc60d355be607fe2 --- build.sbt | 2 +- project/Dependencies.scala | 2 +- project/build.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index c4db12bb1..70ffc1741 100644 --- a/build.sbt +++ b/build.sbt @@ -7,7 +7,7 @@ val _ = { sys.props += ("line.separator" -> "\n") } Global / semanticdbEnabled := !(Global / insideCI).value -// Global / semanticdbVersion := "4.5.9" +Global / semanticdbVersion := "4.7.8" ThisBuild / version := { val old = (ThisBuild / version).value nightlyVersion match { diff --git a/project/Dependencies.scala b/project/Dependencies.scala index ae2fb420e..f44188027 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -43,7 +43,7 @@ object Dependencies { def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" - val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-a8f9eb5bf09d0539ea3658a2c2d4e09755b5133e" + val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-396a783bba347016e7fe30dacc60d355be607fe2" val sbtV = "1.0" val scalaV = "2.12" diff --git a/project/build.properties b/project/build.properties index 46e43a97e..52413ab79 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.8.2 +sbt.version=1.9.3 From cf5fc207b0e6db1ad12577a54b7caff029ff5b3c Mon Sep 17 00:00:00 2001 From: Kunal Date: Wed, 30 Aug 2023 18:36:44 +0530 Subject: [PATCH 0986/1030] Update CrossVersionUtil.scala (#426) --- .../librarymanagement/cross/CrossVersionUtil.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index e8e518ec8..eef2d1a23 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -64,10 +64,10 @@ object CrossVersionUtil { * Compatible versions include 2.10.0-1 and 2.10.1-M1 for Some(2, 10), but not 2.10.0-RC1. */ private[sbt] def scalaApiVersion(v: String): Option[(Long, Long)] = v match { - case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) - case BinCompatV(x, y, _, _, _) => Some((x.toLong, y.toLong)) - case NonReleaseV_1(x, y, z, _) if z.toInt > 0 => Some((x.toLong, y.toLong)) - case _ => None + case ReleaseV(x, y, _, _) => Some((x.toLong, y.toLong)) + case BinCompatV(x, y, _, _, _) => Some((x.toLong, y.toLong)) + case NonReleaseV_1(x, y, z, _) if z.toLong > 0 => Some((x.toLong, y.toLong)) + case _ => None } private[sbt] def partialVersion(s: String): Option[(Long, Long)] = From fd3b33b4727779af6702ee7648319aa7e82b1f12 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 00:50:13 +0200 Subject: [PATCH 0987/1030] Add allModuleReports to UpdateReport --- .../librarymanagement/UpdateReportExtra.scala | 20 +++++++++++++++++-- .../FakeResolverSpecification.scala | 2 ++ .../librarymanagement/FrozenModeSpec.scala | 9 +++++++++ .../librarymanagement/InclExclSpec.scala | 12 +++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 910827703..b54058e8c 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -125,10 +125,11 @@ private[librarymanagement] abstract class UpdateReportExtra { def stats: UpdateStats private[sbt] def stamps: Map[File, Long] + private[sbt] def moduleKey(m: ModuleID) = (m.organization, m.name, m.revision) + /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { - val key = (m: ModuleID) => (m.organization, m.name, m.revision) - configurations.flatMap(_.allModules).groupBy(key).toVector map { case (_, v) => + configurations.flatMap(_.allModules).groupBy(moduleKey).toVector map { case (_, v) => v reduceLeft { (agg, x) => agg.withConfigurations( (agg.configurations, x.configurations) match { @@ -141,6 +142,21 @@ private[librarymanagement] abstract class UpdateReportExtra { } } + def allModuleReports: Vector[ModuleReport] = { + configurations.flatMap(_.modules).groupBy(mR => moduleKey(mR.module)).toVector map { + case (_, v) => + v reduceLeft { (agg, x) => + agg.withConfigurations( + (agg.configurations, x.configurations) match { + case (v, _) if v.isEmpty => x.configurations + case (ac, v) if v.isEmpty => ac + case (ac, xc) => ac ++ xc + } + ) + } + } + } + def retrieve(f: (ConfigRef, ModuleID, Artifact, File) => File): UpdateReport = UpdateReport(cachedDescriptor, configurations map { _ retrieve f }, stats, stamps) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala index 89095a51c..6ed8f1d7a 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FakeResolverSpecification.scala @@ -23,6 +23,7 @@ object FakeResolverSpecification extends BaseIvySpecification { val allFiles = getAllFiles(report) assert(report.allModules.length == 1) + assert(report.allModuleReports.length == 1) assert(report.configurations.length == 3) assert(allFiles.toSet.size == 1) assert(allFiles(1).getName == "artifact1-0.0.1-SNAPSHOT.jar") @@ -34,6 +35,7 @@ object FakeResolverSpecification extends BaseIvySpecification { val allFiles = getAllFiles(report).toSet assert(report.allModules.length == 1) + assert(report.allModuleReports.length == 1) assert(report.configurations.length == 3) assert(allFiles.toSet.size == 2) assert(allFiles.map(_.getName) == Set("artifact1-1.0.0.jar", "artifact2-1.0.0.txt")) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index cae7b3f48..ab6a93c90 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -35,6 +35,7 @@ object FrozenModeSpec extends BaseIvySpecification { val onlineResolution = update(toResolve, onlineConf) assert(onlineResolution.isRight) val numberResolved = onlineResolution.right.get.allModules.size + val numberReportsResolved = onlineResolution.right.get.allModuleReports.size cleanIvyCache() val singleFrozenResolution = update(toResolve, frozenConf) @@ -43,6 +44,10 @@ object FrozenModeSpec extends BaseIvySpecification { singleFrozenResolution.right.get.allModules.size == 1, s"The number of explicit modules in frozen mode should 1" ) + assert( + singleFrozenResolution.right.get.allModuleReports.size == 1, + s"The number of explicit module reports in frozen mode should 1" + ) cleanIvyCache() // This relies on the fact that stoml has 5 transitive dependencies @@ -53,5 +58,9 @@ object FrozenModeSpec extends BaseIvySpecification { frozenResolution.right.get.allModules.size == numberResolved, s"The number of explicit modules in frozen mode should be equal than $numberResolved" ) + assert( + frozenResolution.right.get.allModuleReports.size == numberReportsResolved, + s"The number of explicit module reports in frozen mode should be equal than $numberReportsResolved" + ) } } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala index d05f115ef..7305a2ddc 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/InclExclSpec.scala @@ -68,6 +68,10 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("lift-json")), "lift-json has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("lift-json")), + "lift-json has not been excluded." + ) } def testScalaLibraryIsMissing(report: UpdateReport): Unit = { @@ -75,6 +79,10 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("scala-library")), "scala-library has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("scala-library")), + "scala-library has not been excluded." + ) } def testScalahostIsMissing(report: UpdateReport): Unit = { @@ -82,5 +90,9 @@ object InclExclSpec extends BaseIvySpecification { !report.allModules.exists(_.name.contains("scalahost")), "scalahost has not been excluded." ) + assert( + !report.allModuleReports.exists(_.module.name.contains("scalahost")), + "scalahost has not been excluded." + ) } } From 9919feb8a1f70482069a779efd9a1a8e96ae89b1 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 11:11:55 +0200 Subject: [PATCH 0988/1030] Add JDK 17 to CI --- .github/workflows/ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ef1c3dab..4d4ad94d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,6 +14,9 @@ jobs: - os: ubuntu-latest java: 11 jobtype: 1 + - os: ubuntu-latest + java: 17 + jobtype: 1 runs-on: ${{ matrix.os }} env: # define Java options for both official sbt and sbt-extras From 96220355e25a5e030ee0976861287300c748d093 Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 11:12:59 +0200 Subject: [PATCH 0989/1030] Update github checkout action --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6ef1c3dab..95b392301 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: JVM_OPTS: -Xms2048M -Xmx2048M -Xss6M -XX:ReservedCodeCacheSize=256M steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup JDK uses: actions/setup-java@v3 with: From 47bdf1bcde9a43a246a1a8013b7efb18c4b20c2f Mon Sep 17 00:00:00 2001 From: Matthew de Detrich Date: Mon, 11 Sep 2023 12:02:37 +0200 Subject: [PATCH 0990/1030] Update Scala 2.13 version --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index f44188027..47ebbe2b5 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,7 +4,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.18" - val scala213 = "2.13.10" + val scala213 = "2.13.12" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") From fdb519b9e2a7aca05b72786ef29b8c4778b89659 Mon Sep 17 00:00:00 2001 From: Roberto Tyley Date: Sat, 16 Sep 2023 13:09:07 +0100 Subject: [PATCH 0991/1030] Avoid repeating versions in Eviction warning message As with https://github.com/sbt/librarymanagement/pull/386, which dealt with Eviction *errors*, this fixes the way Eviction *warnings* report the list of evicted versions - removing duplicate versions - and does a refactor so that both `EvictionError` & `EvictionWarning` are using the same logic to generate the revision string. The logic for the revisions string is moved to the new field `EvictionPair.evictedRevs`. Without this fix, we see Eviction warnings like this: ``` * org.scala-lang.modules:scala-java8-compat_2.13:1.0.2 is selected over {1.0.0, 1.0.0} ``` --- .../main/scala/sbt/librarymanagement/EvictionError.scala | 5 +---- .../scala/sbt/librarymanagement/EvictionWarning.scala | 9 ++++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala index 3e73e37c7..3662127be 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionError.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionError.scala @@ -158,9 +158,6 @@ final class EvictionError private[sbt] ( out += "found version conflict(s) in library dependencies; some are suspected to be binary incompatible:" out += "" evictions.foreach({ case (a, scheme) => - val revs = a.evicteds map { _.module.revision } - val revsStr = - if (revs.size <= 1) revs.mkString else "{" + revs.distinct.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => val rev = r.module.revision @@ -174,7 +171,7 @@ final class EvictionError private[sbt] ( } val que = if (assumed) "?" else "" val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${revsStr}" + case Some(r) => s":${r.module.revision} ($scheme$que) is selected over ${a.evictedRevs}" case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" diff --git a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala index df70eeffa..a7179c30c 100644 --- a/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/EvictionWarning.scala @@ -191,6 +191,11 @@ final class EvictionPair private[sbt] ( val includesDirect: Boolean, val showCallers: Boolean ) { + val evictedRevs: String = { + val revs = evicteds map { _.module.revision } + if (revs.size <= 1) revs.mkString else revs.distinct.mkString("{", ", ", "}") + } + override def toString: String = EvictionPair.evictionPairLines.showLines(this).mkString override def equals(o: Any): Boolean = o match { @@ -209,8 +214,6 @@ final class EvictionPair private[sbt] ( object EvictionPair { implicit val evictionPairLines: ShowLines[EvictionPair] = ShowLines { (a: EvictionPair) => - val revs = a.evicteds map { _.module.revision } - val revsStr = if (revs.size <= 1) revs.mkString else "{" + revs.mkString(", ") + "}" val seen: mutable.Set[ModuleID] = mutable.Set() val callers: List[String] = (a.evicteds.toList ::: a.winner.toList) flatMap { r => val rev = r.module.revision @@ -223,7 +226,7 @@ object EvictionPair { } } val winnerRev = a.winner match { - case Some(r) => s":${r.module.revision} is selected over ${revsStr}" + case Some(r) => s":${r.module.revision} is selected over ${a.evictedRevs}" case _ => " is evicted for all versions" } val title = s"\t* ${a.organization}:${a.name}$winnerRev" From 999b881ee7c61300ee8527177db108b61fb6f839 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Mon, 9 Oct 2023 07:51:32 +0900 Subject: [PATCH 0992/1030] fix warnings. Resolver.sonatypeRepo => Resolver.sonatypeOssRepos --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 70ffc1741..ef3d2f672 100644 --- a/build.sbt +++ b/build.sbt @@ -44,14 +44,14 @@ def commonSettings: Seq[Setting[_]] = Def.settings( scalaVersion := scala212, // publishArtifact in packageDoc := false, resolvers += Resolver.typesafeIvyRepo("releases"), - resolvers += Resolver.sonatypeRepo("snapshots"), + resolvers ++= Resolver.sonatypeOssRepos("snapshots"), resolvers += Resolver.sbtPluginRepo("releases"), testFrameworks += new TestFramework("verify.runner.Framework"), // concurrentRestrictions in Global += Util.testExclusiveRestriction, testOptions += Tests.Argument(TestFrameworks.ScalaCheck, "-w", "1"), compile / javacOptions ++= Seq("-Xlint", "-Xlint:-serial"), crossScalaVersions := Seq(scala212, scala213), - resolvers += Resolver.sonatypeRepo("public"), + resolvers ++= Resolver.sonatypeOssRepos("public"), scalacOptions := { val old = scalacOptions.value scalaVersion.value match { From 13f7bb250bbe8296bc84e74290adb559e47e43c9 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 29 Oct 2023 14:54:24 -0400 Subject: [PATCH 0993/1030] sjsonnew 0.14.0-M1 --- .../sbt/librarymanagement/UpdateReport.scala | 8 ++++---- .../librarymanagement/UpdateReportFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- .../sbt/librarymanagement/RichUpdateReport.scala | 2 +- .../librarymanagement/UpdateReportExtra.scala | 2 +- .../sbt/librarymanagement/ivy/IvyPaths.scala | 16 ++++++++-------- .../librarymanagement/ivy/IvyPathsFormats.scala | 4 ++-- ivy/src/main/contraband/lm-ivy.json | 4 ++-- .../sbt/internal/librarymanagement/Ivy.scala | 4 ++-- .../internal/librarymanagement/IvyCache.scala | 2 +- .../librarymanagement/IvyInternalDefaults.scala | 2 +- project/Dependencies.scala | 4 ++-- 12 files changed, 26 insertions(+), 26 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 0e3c68f1a..3e8bcbe1a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -16,7 +16,7 @@ final class UpdateReport private ( val cachedDescriptor: java.io.File, val configurations: Vector[sbt.librarymanagement.ConfigurationReport], val stats: sbt.librarymanagement.UpdateStats, - val stamps: Map[java.io.File, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { + val stamps: Map[String, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { @@ -30,7 +30,7 @@ final class UpdateReport private ( override def toString: String = { "Update report:\n\t" + stats + "\n" + configurations.mkString } - private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { + private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[String, Long] = stamps): UpdateReport = { new UpdateReport(cachedDescriptor, configurations, stats, stamps) } def withCachedDescriptor(cachedDescriptor: java.io.File): UpdateReport = { @@ -42,11 +42,11 @@ final class UpdateReport private ( def withStats(stats: sbt.librarymanagement.UpdateStats): UpdateReport = { copy(stats = stats) } - def withStamps(stamps: Map[java.io.File, Long]): UpdateReport = { + def withStamps(stamps: Map[String, Long]): UpdateReport = { copy(stamps = stamps) } } object UpdateReport { - def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[java.io.File, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) + def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[String, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala index 41951020d..36ea7c27a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -14,7 +14,7 @@ implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateRep val cachedDescriptor = unbuilder.readField[java.io.File]("cachedDescriptor") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigurationReport]]("configurations") val stats = unbuilder.readField[sbt.librarymanagement.UpdateStats]("stats") - val stamps = unbuilder.readField[Map[java.io.File, Long]]("stamps") + val stamps = unbuilder.readField[Map[String, Long]]("stamps") unbuilder.endObject() sbt.librarymanagement.UpdateReport(cachedDescriptor, configurations, stats, stamps) case None => diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 6b210d34c..89d20007d 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -814,7 +814,7 @@ "type": "sbt.librarymanagement.UpdateStats", "doc": [ "stats information about the update that produced this report" ] }, - { "name": "stamps", "type": "Map[java.io.File, Long]" } + { "name": "stamps", "type": "Map[String, Long]" } ], "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" }, diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 9060f14b6..321790def 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -14,7 +14,7 @@ final class RichUpdateReport(report: UpdateReport) { val stamps = files .map(f => ( - f, + f.toString, // TODO: The list of files may also contain some odd files that do not actually exist like: // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index 910827703..e3927bb30 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -123,7 +123,7 @@ private[librarymanagement] abstract class UpdateReportExtra { def cachedDescriptor: File def configurations: Vector[ConfigurationReport] def stats: UpdateStats - private[sbt] def stamps: Map[File, Long] + private[sbt] def stamps: Map[String, Long] /** All resolved modules in all configurations. */ def allModules: Vector[ModuleID] = { diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala index 574369bb0..74268a9d3 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPaths.scala @@ -5,8 +5,8 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement.ivy final class IvyPaths private ( - val baseDirectory: java.io.File, - val ivyHome: Option[java.io.File]) extends Serializable { + val baseDirectory: String, + val ivyHome: Option[String]) extends Serializable { @@ -20,21 +20,21 @@ final class IvyPaths private ( override def toString: String = { "IvyPaths(" + baseDirectory + ", " + ivyHome + ")" } - private[this] def copy(baseDirectory: java.io.File = baseDirectory, ivyHome: Option[java.io.File] = ivyHome): IvyPaths = { + private[this] def copy(baseDirectory: String = baseDirectory, ivyHome: Option[String] = ivyHome): IvyPaths = { new IvyPaths(baseDirectory, ivyHome) } - def withBaseDirectory(baseDirectory: java.io.File): IvyPaths = { + def withBaseDirectory(baseDirectory: String): IvyPaths = { copy(baseDirectory = baseDirectory) } - def withIvyHome(ivyHome: Option[java.io.File]): IvyPaths = { + def withIvyHome(ivyHome: Option[String]): IvyPaths = { copy(ivyHome = ivyHome) } - def withIvyHome(ivyHome: java.io.File): IvyPaths = { + def withIvyHome(ivyHome: String): IvyPaths = { copy(ivyHome = Option(ivyHome)) } } object IvyPaths { - def apply(baseDirectory: java.io.File, ivyHome: Option[java.io.File]): IvyPaths = new IvyPaths(baseDirectory, ivyHome) - def apply(baseDirectory: java.io.File, ivyHome: java.io.File): IvyPaths = new IvyPaths(baseDirectory, Option(ivyHome)) + def apply(baseDirectory: String, ivyHome: Option[String]): IvyPaths = new IvyPaths(baseDirectory, ivyHome) + def apply(baseDirectory: String, ivyHome: String): IvyPaths = new IvyPaths(baseDirectory, Option(ivyHome)) } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala index 1db14727e..1483f1d91 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyPathsFormats.scala @@ -11,8 +11,8 @@ implicit lazy val IvyPathsFormat: JsonFormat[sbt.librarymanagement.ivy.IvyPaths] __jsOpt match { case Some(__js) => unbuilder.beginObject(__js) - val baseDirectory = unbuilder.readField[java.io.File]("baseDirectory") - val ivyHome = unbuilder.readField[Option[java.io.File]]("ivyHome") + val baseDirectory = unbuilder.readField[String]("baseDirectory") + val ivyHome = unbuilder.readField[Option[String]]("ivyHome") unbuilder.endObject() sbt.librarymanagement.ivy.IvyPaths(baseDirectory, ivyHome) case None => diff --git a/ivy/src/main/contraband/lm-ivy.json b/ivy/src/main/contraband/lm-ivy.json index 383e17549..d6e90dc76 100644 --- a/ivy/src/main/contraband/lm-ivy.json +++ b/ivy/src/main/contraband/lm-ivy.json @@ -137,8 +137,8 @@ "target": "Scala", "type": "record", "fields": [ - { "name": "baseDirectory", "type": "java.io.File" }, - { "name": "ivyHome", "type": "java.io.File?" } + { "name": "baseDirectory", "type": "String" }, + { "name": "ivyHome", "type": "String?" } ] } ] diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 4f2de8e1c..2faa98678 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -131,10 +131,10 @@ final class IvySbt( IvySbt.loadURI(is, e.uri.getOrElse(sys.error("uri must be specified!"))) case i: InlineIvyConfiguration => val paths = getIvyPaths(i.paths) - is.setBaseDir(paths.baseDirectory) + is.setBaseDir(new File(paths.baseDirectory)) is.setVariable("ivy.checksums", i.checksums mkString ",") is.setVariable(ConvertResolver.ManagedChecksums, i.managedChecksums.toString) - paths.ivyHome foreach is.setDefaultIvyUserDir + paths.ivyHome.foreach { (h) => is.setDefaultIvyUserDir(new File(h)) } IvySbt.configureCache(is, i.resolutionCacheDir) IvySbt.setResolvers(is, i.resolvers, i.otherResolvers, configuration.updateOptions, log) IvySbt.setModuleConfigurations(is, i.moduleConfigurations, log) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala index cadd0e313..2eb2474f2 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyCache.scala @@ -106,7 +106,7 @@ class IvyCache(val ivyHome: Option[File]) { /** A minimal Ivy setup with only a local resolver and the current directory as the base directory. */ private def basicLocalIvy(lock: Option[xsbti.GlobalLock], log: Logger) = { val local = Resolver.defaultLocal - val paths = IvyPaths(new File("."), ivyHome) + val paths = IvyPaths(".", ivyHome.map(_.toString)) val conf = InlineIvyConfiguration() .withPaths(paths) .withResolvers(Vector(local)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala index e2d558baf..59f88ffc1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyInternalDefaults.scala @@ -21,7 +21,7 @@ object IvyInternalDefaults { opt.getOrElse(Logger.Null) def defaultIvyPaths: IvyPaths = - IvyPaths(defaultBaseDirectory, None) + IvyPaths(defaultBaseDirectory.toString, None) def getIvyPaths(opt: Option[IvyPaths]): IvyPaths = opt.getOrElse(defaultIvyPaths) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 0f165a66f..4f57a494a 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.15" val scala213 = "2.13.6" - val scala3 = "3.2.1" + val scala3 = "3.3.1" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -56,7 +56,7 @@ object Dependencies { val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" - val sjsonNewVersion = "0.13.0" + val sjsonNewVersion = "0.14.0-M1" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } From 3156ac253a1a8e84cc12ff922f208b9dc7c06a22 Mon Sep 17 00:00:00 2001 From: Alex Zolotko Date: Sat, 30 Mar 2024 17:30:57 +0100 Subject: [PATCH 0994/1030] Update jsch to 0.2.17 (the com.github.mwiede fork) --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 47ebbe2b5..e9e6735fc 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -48,7 +48,7 @@ object Dependencies { val sbtV = "1.0" val scalaV = "2.12" - val jsch = "com.jcraft" % "jsch" % "0.1.54" intransitive () + val jsch = "com.github.mwiede" % "jsch" % "0.2.17" intransitive () val scalaReflect = Def.setting { "org.scala-lang" % "scala-reflect" % scalaVersion.value } val scalaCompiler = Def.setting { "org.scala-lang" % "scala-compiler" % scalaVersion.value } val scalaXml = "org.scala-lang.modules" %% "scala-xml" % "2.1.0" From 04fcad6d9a79e8fc1b077c2a213ed6c6807c2f91 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 8 Apr 2024 22:06:49 -0400 Subject: [PATCH 0995/1030] Use 2 for binarySbtVersion in 2.x --- build.sbt | 9 ++++--- .../cross/CrossVersionUtil.scala | 8 +++++- .../librarymanagement/CrossVersionTest.scala | 27 +++++++++---------- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/build.sbt b/build.sbt index ef3d2f672..c4e1a1608 100644 --- a/build.sbt +++ b/build.sbt @@ -55,11 +55,12 @@ def commonSettings: Seq[Setting[_]] = Def.settings( scalacOptions := { val old = scalacOptions.value scalaVersion.value match { - case sv if sv.startsWith("2.10") => - old diff List("-Xfuture", "-Ywarn-unused", "-Ywarn-unused-import") - case sv if sv.startsWith("2.11") => old ++ List("-Ywarn-unused", "-Ywarn-unused-import") case sv if sv.startsWith("2.12") => - old ++ List("-Ywarn-unused", "-Ywarn-unused-import", "-YdisableFlatCpCaching") + old ++ List( + "-Ywarn-unused", + "-Ywarn-unused-import", + "-Ywarn-unused:-nowarn", + ) case _ => old } }, diff --git a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala index eef2d1a23..f2d467133 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/cross/CrossVersionUtil.scala @@ -117,7 +117,13 @@ object CrossVersionUtil { } def binarySbtVersion(full: String): String = - binaryVersionWithApi(full, TransitionSbtVersion)(sbtApiVersion) + sbtApiVersion(full) match { + case Some((0, minor)) if minor < 12 => full + case Some((0, minor)) => s"0.$minor" + case Some((1, minor)) => s"1.$minor" + case Some((major, _)) => major.toString + case _ => full + } private[this] def isNewer(major: Long, minor: Long, minMajor: Long, minMinor: Long): Boolean = major > minMajor || (major == minMajor && minor >= minMinor) diff --git a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala index 96b3d164f..c273653a0 100644 --- a/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/CrossVersionTest.scala @@ -96,23 +96,23 @@ class CrossVersionTest extends UnitSpec { "binarySbtVersion" should "for 0.11.3 return 0.11.3" in { binarySbtVersion("0.11.3") shouldBe "0.11.3" } - it should "for 0.12.0-M1 return 0.12.0-M1" in { - binarySbtVersion("0.12.0-M1") shouldBe "0.12.0-M1" + it should "for 2.0.0 return 2" in { + binarySbtVersion("2.0.0") shouldBe "2" } - it should "for 0.12.0-RC1 return 0.12" in { - binarySbtVersion("0.12.0-RC1") shouldBe "0.12" + it should "for 2.0.0-M1 return 2.0.0-M1" in { + binarySbtVersion("2.0.0-M1") shouldBe "2.0.0-M1" } - it should "for 0.12.0 return 0.12" in { - binarySbtVersion("0.12.0") shouldBe "0.12" + it should "for 2.0.0-RC1 return 2" in { + binarySbtVersion("2.0.0-RC1") shouldBe "2" } - it should "for 0.12.1-SNAPSHOT return 0.12" in { - binarySbtVersion("0.12.1-SNAPSHOT") shouldBe "0.12" + it should "for 2.1.0-M1 return 2" in { + binarySbtVersion("2.1.0-M1") shouldBe "2" } - it should "for 0.12.1-RC1 return 0.12" in { - binarySbtVersion("0.12.1-RC1") shouldBe "0.12" + it should "for 2.1.0 return 2" in { + binarySbtVersion("2.1.0") shouldBe "2" } - it should "for 0.12.1 return 0.12" in { - binarySbtVersion("0.12.1") shouldBe "0.12" + it should "for 0.13.1 return 0.13" in { + binarySbtVersion("0.13.1") shouldBe "0.13" } it should "for 1.0.0-M6 return 1.0.0-M6" in { binarySbtVersion("1.0.0-M6") shouldBe "1.0.0-M6" @@ -144,9 +144,6 @@ class CrossVersionTest extends UnitSpec { it should "for 1.10.0 return 1.0" in { binarySbtVersion("1.10.0") shouldBe "1.0" } - it should "for 2.0.0 return 2.0" in { - binarySbtVersion("2.0.0") shouldBe "2.0" - } "scalaApiVersion" should "for xyz return None" in { scalaApiVersion("xyz") shouldBe None From 6ab6c2baa95b1031ea7d465dbd6c708eaf7c7cef Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 8 Apr 2024 22:36:44 -0400 Subject: [PATCH 0996/1030] Util 1.10.0-RC1 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index e9e6735fc..b68ef80e2 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.1") - private val utilVersion = nightlyVersion.getOrElse("1.9.1") + private val ioVersion = nightlyVersion.getOrElse("1.9.9") + private val utilVersion = nightlyVersion.getOrElse("1.10.0-RC1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From dc460527b40a19424bdd0166b6865c1707547aae Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sun, 5 May 2024 17:53:08 -0400 Subject: [PATCH 0997/1030] Util 1.10.0 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b68ef80e2..43e8550be 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -9,8 +9,8 @@ object Dependencies { def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") - private val ioVersion = nightlyVersion.getOrElse("1.9.9") - private val utilVersion = nightlyVersion.getOrElse("1.10.0-RC1") + private val ioVersion = nightlyVersion.getOrElse("1.10.0") + private val utilVersion = nightlyVersion.getOrElse("1.10.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From b3edb6a405a10787839b2eef04d124b002b84202 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:04:26 +0200 Subject: [PATCH 0998/1030] Fix merge --- .scalafmt.conf | 2 -- .../ivyint/ErrorMessageAuthenticator.scala | 14 ++++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.scalafmt.conf b/.scalafmt.conf index 36996af92..dfdd36b0b 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -22,5 +22,3 @@ align.openParenDefnSite = false danglingParentheses.preset = true trailingCommas = preserve - -runner.dialect = Scala212Source3 diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala index f9f6ec04e..478462e8d 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ErrorMessageAuthenticator.scala @@ -64,12 +64,14 @@ object ErrorMessageAuthenticator { ivyOriginalField.set(ivy, newOriginal) } - try Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { - case Some( - _: ErrorMessageAuthenticator - ) => // We're already installed, no need to do the work again. - case originalOpt => installIntoIvyImpl(originalOpt) - } catch { + try + Option(ivyOriginalField.get(ivy).asInstanceOf[Authenticator]) match { + case Some( + _: ErrorMessageAuthenticator + ) => // We're already installed, no need to do the work again. + case originalOpt => installIntoIvyImpl(originalOpt) + } + catch { case t: Throwable => Message.debug( "Error occurred while trying to install debug messages into Ivy Authentication" + t.getMessage From f8ce2cdef698d31206defbe6b45ae1a15772cced Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:04:38 +0200 Subject: [PATCH 0999/1030] Update to Scala 3.3 --- project/Dependencies.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 4424008b0..d6e28cf91 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -5,7 +5,7 @@ import sbt.contraband.ContrabandPlugin.autoImport._ object Dependencies { val scala212 = "2.12.18" val scala213 = "2.13.12" - val scala3 = "3.2.1" + val scala3 = "3.3.3" def nightlyVersion: Option[String] = sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") @@ -63,5 +63,5 @@ object Dependencies { val sjsonnewScalaJson = Def.setting { "com.eed3si9n" %% "sjson-new-scalajson" % sjsonNewVersion } - val gigahorseOkhttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" + val gigahorseApacheHttp = "com.eed3si9n" %% "gigahorse-apache-http" % "0.7.0" } From 28b5db1465cdfb6d076a9e9306595775fd74df60 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Thu, 23 May 2024 17:09:12 +0200 Subject: [PATCH 1000/1030] fix Scala 3 compilation --- .../test/scala/sbt/librarymanagement/ResolverExtraTest.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala index 10cad9012..6aba7ec05 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -36,7 +36,7 @@ object ResolverExtraTest extends BasicTestSuite { // - Helper functions ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- def assertExpansion(input: String, expected: String) = - assert(Resolver.expandMavenSettings(input) == s"$expected") + assert(Resolver.expandMavenSettings(input) == expected) def env(name: String) = sys.env.getOrElse(name, "") def prop(name: String) = sys.props.getOrElse(name, "") From e140c8066730efb8170e87f7c944145af37f2408 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Tue, 28 May 2024 11:11:44 +0200 Subject: [PATCH 1001/1030] Bump sjson-new --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index d6e28cf91..824ae9b54 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -56,7 +56,7 @@ object Dependencies { val scalaTest = "org.scalatest" %% "scalatest" % "3.2.10" val scalaVerify = "com.eed3si9n.verify" %% "verify" % "1.0.0" val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.15.3" - val sjsonNewVersion = "0.13.0" + val sjsonNewVersion = "0.14.0-M1" val sjsonnew = Def.setting { "com.eed3si9n" %% "sjson-new-core" % sjsonNewVersion } From 1b3d5324bb4bd730d8a729e5e71be3bbb1015756 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 29 May 2024 10:35:34 +0200 Subject: [PATCH 1002/1030] Use String instead of File as key of stamps - regenerate contraband --- .../ChainedResolverFormats.scala | 15 +-------------- .../ConfigurationReportFormats.scala | 18 +----------------- .../ModuleConfigurationFormats.scala | 16 +--------------- .../PatternsBasedRepositoryFormats.scala | 12 +----------- .../PublishConfigurationFormats.scala | 8 +------- .../librarymanagement/ResolverFormats.scala | 15 +-------------- .../SftpRepositoryFormats.scala | 7 +------ .../SshBasedRepositoryFormats.scala | 9 +-------- .../SshConnectionFormats.scala | 5 +---- .../SshRepositoryFormats.scala | 7 +------ .../sbt/librarymanagement/UpdateReport.scala | 8 ++++---- .../UpdateReportFormats.scala | 2 +- .../src/main/contraband/librarymanagement.json | 2 +- .../librarymanagement/RichUpdateReport.scala | 2 +- .../librarymanagement/UpdateReportExtra.scala | 2 +- .../DMSerializationSpec.scala | 2 +- 16 files changed, 19 insertions(+), 111 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala index 25792d684..61cf796da 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ChainedResolverFormats.scala @@ -5,20 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ChainedResolverFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ChainedResolverFormat: JsonFormat[sbt.librarymanagement.ChainedResolver] = new JsonFormat[sbt.librarymanagement.ChainedResolver] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ChainedResolver = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala index 282877526..c8090c6e1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ConfigurationReportFormats.scala @@ -5,23 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with - sbt.librarymanagement.ModuleReportFormats with - sbt.librarymanagement.ModuleIDFormats with - sbt.librarymanagement.ArtifactFormats with - sbt.librarymanagement.ChecksumFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.InclExclRuleFormats with - sbt.librarymanagement.CrossVersionFormats with - sbt.librarymanagement.DisabledFormats with - sbt.librarymanagement.BinaryFormats with - sbt.librarymanagement.ConstantFormats with - sbt.librarymanagement.PatchFormats with - sbt.librarymanagement.FullFormats with - sbt.librarymanagement.For3Use2_13Formats with - sbt.librarymanagement.For2_13Use3Formats with - sbt.librarymanagement.CallerFormats with - sbt.librarymanagement.OrganizationArtifactReportFormats => +trait ConfigurationReportFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ModuleReportFormats with sbt.librarymanagement.ModuleIDFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.ChecksumFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.InclExclRuleFormats with sbt.librarymanagement.CrossVersionFormats with sbt.librarymanagement.DisabledFormats with sbt.librarymanagement.BinaryFormats with sbt.librarymanagement.ConstantFormats with sbt.librarymanagement.PatchFormats with sbt.librarymanagement.FullFormats with sbt.librarymanagement.For3Use2_13Formats with sbt.librarymanagement.For2_13Use3Formats with sbt.librarymanagement.CallerFormats with sbt.librarymanagement.OrganizationArtifactReportFormats => implicit lazy val ConfigurationReportFormat: JsonFormat[sbt.librarymanagement.ConfigurationReport] = new JsonFormat[sbt.librarymanagement.ConfigurationReport] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ConfigurationReport = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala index f562f1bb4..1f34ab28f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleConfigurationFormats.scala @@ -5,21 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.ChainedResolverFormats with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ModuleConfigurationFormats { self: sbt.librarymanagement.ResolverFormats with sjsonnew.BasicJsonProtocol => implicit lazy val ModuleConfigurationFormat: JsonFormat[sbt.librarymanagement.ModuleConfiguration] = new JsonFormat[sbt.librarymanagement.ModuleConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ModuleConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala index f49f0f9c6..843e70f3d 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PatternsBasedRepositoryFormats.scala @@ -6,16 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait PatternsBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val PatternsBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.PatternsBasedRepository] = flatUnionFormat4[sbt.librarymanagement.PatternsBasedRepository, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala index 8b2842ad8..d1fde3d18 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/PublishConfigurationFormats.scala @@ -5,13 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with - sbt.librarymanagement.ArtifactFormats with - sbt.librarymanagement.UpdateLoggingFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats with - sbt.librarymanagement.ChecksumFormats => +trait PublishConfigurationFormats { self: sbt.librarymanagement.ConfigRefFormats with sbt.librarymanagement.ArtifactFormats with sbt.librarymanagement.UpdateLoggingFormats with sjsonnew.BasicJsonProtocol => implicit lazy val PublishConfigurationFormat: JsonFormat[sbt.librarymanagement.PublishConfiguration] = new JsonFormat[sbt.librarymanagement.PublishConfiguration] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.PublishConfiguration = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala index 3f0a73150..5569ef568 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ResolverFormats.scala @@ -6,19 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.ChainedResolverFormats with - sbt.librarymanagement.MavenRepoFormats with - sbt.librarymanagement.MavenCacheFormats with - sbt.librarymanagement.PatternsFormats with - sbt.librarymanagement.FileConfigurationFormats with - sbt.librarymanagement.FileRepositoryFormats with - sbt.librarymanagement.URLRepositoryFormats with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait ResolverFormats { self: sjsonnew.BasicJsonProtocol with sbt.librarymanagement.ChainedResolverFormats with sbt.librarymanagement.MavenRepoFormats with sbt.librarymanagement.MavenCacheFormats with sbt.librarymanagement.PatternsFormats with sbt.librarymanagement.FileConfigurationFormats with sbt.librarymanagement.FileRepositoryFormats with sbt.librarymanagement.URLRepositoryFormats with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val ResolverFormat: JsonFormat[sbt.librarymanagement.Resolver] = flatUnionFormat7[sbt.librarymanagement.Resolver, sbt.librarymanagement.ChainedResolver, sbt.librarymanagement.MavenRepo, sbt.librarymanagement.MavenCache, sbt.librarymanagement.FileRepository, sbt.librarymanagement.URLRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala index 2a2f49073..9441ada31 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SftpRepositoryFormats.scala @@ -5,12 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SftpRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SftpRepositoryFormat: JsonFormat[sbt.librarymanagement.SftpRepository] = new JsonFormat[sbt.librarymanagement.SftpRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SftpRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala index b16f32821..8143d7239 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshBasedRepositoryFormats.scala @@ -6,13 +6,6 @@ package sbt.librarymanagement import _root_.sjsonnew.JsonFormat -trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.SshRepositoryFormats with - sbt.librarymanagement.SftpRepositoryFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshBasedRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats with sbt.librarymanagement.SshRepositoryFormats with sbt.librarymanagement.SftpRepositoryFormats => implicit lazy val SshBasedRepositoryFormat: JsonFormat[sbt.librarymanagement.SshBasedRepository] = flatUnionFormat2[sbt.librarymanagement.SshBasedRepository, sbt.librarymanagement.SshRepository, sbt.librarymanagement.SftpRepository]("type") } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala index db4ea41e5..9daea2940 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshConnectionFormats.scala @@ -5,10 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshConnectionFormats { self: sbt.librarymanagement.SshAuthenticationFormats with sjsonnew.BasicJsonProtocol => implicit lazy val SshConnectionFormat: JsonFormat[sbt.librarymanagement.SshConnection] = new JsonFormat[sbt.librarymanagement.SshConnection] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshConnection = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala index 2b3c4893b..861d359b1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SshRepositoryFormats.scala @@ -5,12 +5,7 @@ // DO NOT EDIT MANUALLY package sbt.librarymanagement import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } -trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with - sjsonnew.BasicJsonProtocol with - sbt.librarymanagement.SshConnectionFormats with - sbt.librarymanagement.SshAuthenticationFormats with - sbt.librarymanagement.PasswordAuthenticationFormats with - sbt.librarymanagement.KeyFileAuthenticationFormats => +trait SshRepositoryFormats { self: sbt.librarymanagement.PatternsFormats with sjsonnew.BasicJsonProtocol with sbt.librarymanagement.SshConnectionFormats with sbt.librarymanagement.SshAuthenticationFormats => implicit lazy val SshRepositoryFormat: JsonFormat[sbt.librarymanagement.SshRepository] = new JsonFormat[sbt.librarymanagement.SshRepository] { override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.SshRepository = { __jsOpt match { diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala index 0e3c68f1a..3e8bcbe1a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReport.scala @@ -16,7 +16,7 @@ final class UpdateReport private ( val cachedDescriptor: java.io.File, val configurations: Vector[sbt.librarymanagement.ConfigurationReport], val stats: sbt.librarymanagement.UpdateStats, - val stamps: Map[java.io.File, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { + val stamps: Map[String, Long]) extends sbt.librarymanagement.UpdateReportExtra with Serializable { @@ -30,7 +30,7 @@ final class UpdateReport private ( override def toString: String = { "Update report:\n\t" + stats + "\n" + configurations.mkString } - private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[java.io.File, Long] = stamps): UpdateReport = { + private[this] def copy(cachedDescriptor: java.io.File = cachedDescriptor, configurations: Vector[sbt.librarymanagement.ConfigurationReport] = configurations, stats: sbt.librarymanagement.UpdateStats = stats, stamps: Map[String, Long] = stamps): UpdateReport = { new UpdateReport(cachedDescriptor, configurations, stats, stamps) } def withCachedDescriptor(cachedDescriptor: java.io.File): UpdateReport = { @@ -42,11 +42,11 @@ final class UpdateReport private ( def withStats(stats: sbt.librarymanagement.UpdateStats): UpdateReport = { copy(stats = stats) } - def withStamps(stamps: Map[java.io.File, Long]): UpdateReport = { + def withStamps(stamps: Map[String, Long]): UpdateReport = { copy(stamps = stamps) } } object UpdateReport { - def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[java.io.File, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) + def apply(cachedDescriptor: java.io.File, configurations: Vector[sbt.librarymanagement.ConfigurationReport], stats: sbt.librarymanagement.UpdateStats, stamps: Map[String, Long]): UpdateReport = new UpdateReport(cachedDescriptor, configurations, stats, stamps) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala index 41951020d..36ea7c27a 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/UpdateReportFormats.scala @@ -14,7 +14,7 @@ implicit lazy val UpdateReportFormat: JsonFormat[sbt.librarymanagement.UpdateRep val cachedDescriptor = unbuilder.readField[java.io.File]("cachedDescriptor") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigurationReport]]("configurations") val stats = unbuilder.readField[sbt.librarymanagement.UpdateStats]("stats") - val stamps = unbuilder.readField[Map[java.io.File, Long]]("stamps") + val stamps = unbuilder.readField[Map[String, Long]]("stamps") unbuilder.endObject() sbt.librarymanagement.UpdateReport(cachedDescriptor, configurations, stats, stamps) case None => diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 6b210d34c..89d20007d 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -814,7 +814,7 @@ "type": "sbt.librarymanagement.UpdateStats", "doc": [ "stats information about the update that produced this report" ] }, - { "name": "stamps", "type": "Map[java.io.File, Long]" } + { "name": "stamps", "type": "Map[String, Long]" } ], "toString": "\"Update report:\\n\\t\" + stats + \"\\n\" + configurations.mkString" }, diff --git a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala index 9060f14b6..321790def 100644 --- a/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala +++ b/core/src/main/scala/sbt/librarymanagement/RichUpdateReport.scala @@ -14,7 +14,7 @@ final class RichUpdateReport(report: UpdateReport) { val stamps = files .map(f => ( - f, + f.toString, // TODO: The list of files may also contain some odd files that do not actually exist like: // "./target/ivyhome/resolution-cache/com.example/foo/0.4.0/resolved.xml.xml". // IO.getModifiedTimeOrZero() will just return zero, but the list of files should not contain such diff --git a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala index b54058e8c..c8b3ac69c 100644 --- a/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/UpdateReportExtra.scala @@ -123,7 +123,7 @@ private[librarymanagement] abstract class UpdateReportExtra { def cachedDescriptor: File def configurations: Vector[ConfigurationReport] def stats: UpdateStats - private[sbt] def stamps: Map[File, Long] + private[sbt] def stamps: Map[String, Long] private[sbt] def moduleKey(m: ModuleID) = (m.organization, m.name, m.revision) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index 7487252d1..bc035efa1 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -75,7 +75,7 @@ object DMSerializationSpec extends BasicTestSuite { new File("./foo"), Vector(configurationReportExample), UpdateStats(0, 0, 0, false), - Map(new File("./foo") -> 0) + Map("./foo" -> 0) ) lazy val configurationReportExample = ConfigurationReport( From 4251aa3ba00382ba4fb4005e6370ee1ce2c7b000 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 29 May 2024 13:39:22 +0200 Subject: [PATCH 1003/1030] Add lmIvy dependency to sjsonnew --- build.sbt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.sbt b/build.sbt index e947018be..a877f64f2 100644 --- a/build.sbt +++ b/build.sbt @@ -282,6 +282,8 @@ lazy val lmIvy = (project in file("ivy")) contrabandSjsonNewVersion := sjsonNewVersion, libraryDependencies ++= Seq( ivy, + sjsonnewScalaJson.value, + sjsonnew.value, scalaTest % Test, scalaCheck % Test, scalaVerify % Test, From d42bc8e6e3d67f6a73f5f5f4d5c85c6fa54092f5 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Thu, 30 May 2024 23:07:12 -0700 Subject: [PATCH 1004/1030] util 2.0.0-alpha10 --- project/Dependencies.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 824ae9b54..1488f7d73 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -11,7 +11,7 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.10.0") - private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha5") + private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha10") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From d078dc4772de3f892a1633a3bc3be0440b121097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Wed, 29 May 2024 14:37:50 +0100 Subject: [PATCH 1005/1030] Artifact --- .../sbt/librarymanagement/Artifact.scala | 12 +++++------ .../librarymanagement/ArtifactFormats.scala | 2 +- .../main/contraband/librarymanagement.json | 2 +- .../sbt/librarymanagement/ArtifactExtra.scala | 21 ++++++++++--------- .../sbt/librarymanagement/ModuleIDExtra.scala | 2 +- .../sbt/internal/librarymanagement/Ivy.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 2 +- .../DMSerializationSpec.scala | 2 +- 8 files changed, 23 insertions(+), 22 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 24764d0cb..e7d033043 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -10,13 +10,13 @@ final class Artifact private ( val extension: String, val classifier: Option[String], val configurations: Vector[sbt.librarymanagement.ConfigRef], - val url: Option[java.net.URL], + val url: Option[java.net.URI], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum], val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger) private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) - private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) + private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) @@ -28,7 +28,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URI] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } def withName(name: String): Artifact = { @@ -46,7 +46,7 @@ final class Artifact private ( def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): Artifact = { copy(configurations = configurations) } - def withUrl(url: Option[java.net.URL]): Artifact = { + def withUrl(url: Option[java.net.URI]): Artifact = { copy(url = url) } def withExtraAttributes(extraAttributes: Map[String, String]): Artifact = { @@ -62,6 +62,6 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index ae951d635..6b92852cf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -16,7 +16,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") - val url = unbuilder.readField[Option[java.net.URL]]("url") + val url = unbuilder.readField[Option[java.net.URI]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 89d20007d..8f87d7040 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -141,7 +141,7 @@ { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "url", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" }, { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 63a992d2d..411f486aa 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -4,7 +4,7 @@ package sbt.librarymanagement import java.io.File -import java.net.URL +import java.net.URI private[librarymanagement] abstract class ArtifactExtra { def extraAttributes: Map[String, String] @@ -26,15 +26,15 @@ private[librarymanagement] abstract class ArtifactFunctions { Artifact(name, `type`, extension, None, Vector.empty, None) def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) - def apply(name: String, url: URL): Artifact = Artifact(name, url, false) - def apply(name: String, url: URL, allowInsecureProtocol: Boolean): Artifact = + def apply(name: String, uri: URI): Artifact = Artifact(name, uri, false) + def apply(name: String, uri: URI, allowInsecureProtocol: Boolean): Artifact = Artifact( name, - extract(url, DefaultType), - extract(url, DefaultExtension), + extract(uri, DefaultType), + extract(uri, DefaultExtension), None, Vector.empty, - Some(url), + Some(uri), Map.empty, None, allowInsecureProtocol @@ -47,8 +47,9 @@ private[librarymanagement] abstract class ArtifactFunctions { extension: String, classifier: Option[String], configurations: Vector[ConfigRef], - url: Option[URL] - ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) + uri: Option[URI] + ): Artifact = + Artifact(name, `type`, extension, classifier, configurations, uri, empty, None) val DefaultExtension = "jar" val DefaultType = "jar" @@ -78,7 +79,7 @@ private[librarymanagement] abstract class ArtifactFunctions { assert(DefaultDocTypes contains DocType) assert(DefaultSourceTypes contains SourceType) - def extract(url: URL, default: String): String = extract(url.toString, default) + def extract(uri: URI, default: String): String = extract(uri.toString, default) def extract(name: String, default: String): String = { val i = name.lastIndexOf('.') if (i >= 0) @@ -96,7 +97,7 @@ private[librarymanagement] abstract class ArtifactFunctions { extract(name, DefaultExtension), None, Vector.empty, - Some(file.toURI.toURL) + Some(file.toURI) ) } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index f62f83d1b..4d9803394 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -133,7 +133,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * It is not included in published metadata. */ def from(url: String, allowInsecureProtocol: Boolean): ModuleID = - artifacts(Artifact(name, new URI(url).toURL, allowInsecureProtocol)) + artifacts(Artifact(name, new URI(url), allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 97bc40143..8c6350905 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -1000,7 +1000,7 @@ private[sbt] object IvySbt { name, `type`, extension, - url.orNull, + url.map(_.toURL).orNull, extraMap ) copyConfigurations(artifact, (ref: ConfigRef) => { ivyArtifact.addConfiguration(ref.name) }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index a1784ffd0..0560036d3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -229,7 +229,7 @@ object IvyRetrieve { getConfigurations.toVector map { (c: String) => ConfigRef(c) }, - Option(getUrl) + Option(getUrl).map(_.toURI) ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index bc035efa1..b380800fc 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -43,7 +43,7 @@ object DMSerializationSpec extends BasicTestSuite { } test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { - roundtrip(Artifact("foo", new URI("http://example.com/").toURL)) + roundtrip(Artifact("foo", new URI("http://example.com/"))) } test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { From 03f0288ae64dea773ac012828c64d295ab87496a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Wed, 29 May 2024 14:52:39 +0100 Subject: [PATCH 1006/1030] Developer --- .../sbt/librarymanagement/Developer.scala | 8 ++++---- .../sbt/librarymanagement/DeveloperFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index fc52d4e7b..0afb34a0f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -8,7 +8,7 @@ final class Developer private ( val id: String, val name: String, val email: String, - val url: java.net.URL) extends Serializable { + val url: java.net.URI) extends Serializable { @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URI = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { @@ -34,11 +34,11 @@ final class Developer private ( def withEmail(email: String): Developer = { copy(email = email) } - def withUrl(url: java.net.URL): Developer = { + def withUrl(url: java.net.URI): Developer = { copy(url = url) } } object Developer { - def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) + def apply(id: String, name: String, email: String, url: java.net.URI): Developer = new Developer(id, name, email, url) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index 381013ab0..3a7cdbf60 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -14,7 +14,7 @@ implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") val email = unbuilder.readField[String]("email") - val url = unbuilder.readField[java.net.URL]("url") + val url = unbuilder.readField[java.net.URI]("url") unbuilder.endObject() sbt.librarymanagement.Developer(id, name, email, url) case None => diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 8f87d7040..6954a4f5b 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -244,7 +244,7 @@ { "name": "id", "type": "String" }, { "name": "name", "type": "String" }, { "name": "email", "type": "String" }, - { "name": "url", "type": "java.net.URL" } + { "name": "url", "type": "java.net.URI" } ] }, { From b00e24274478862db3b070321a4957996508b9db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Wed, 29 May 2024 17:39:08 +0100 Subject: [PATCH 1007/1030] ScmInfo --- .../sbt/librarymanagement/ScmInfo.scala | 14 +++++++------- .../sbt/librarymanagement/ScmInfoFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 4fadcae1f..f91a5bbf1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -6,11 +6,11 @@ package sbt.librarymanagement /** Basic SCM information for a project module */ final class ScmInfo private ( - val browseUrl: java.net.URL, + val browseUrl: java.net.URI, val connection: String, val devConnection: Option[String]) extends Serializable { - private def this(browseUrl: java.net.URL, connection: String) = this(browseUrl, connection, None) + private def this(browseUrl: java.net.URI, connection: String) = this(browseUrl, connection, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ScmInfo => (this.browseUrl == x.browseUrl) && (this.connection == x.connection) && (this.devConnection == x.devConnection) @@ -22,10 +22,10 @@ final class ScmInfo private ( override def toString: String = { "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" } - private[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { + private[this] def copy(browseUrl: java.net.URI = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { new ScmInfo(browseUrl, connection, devConnection) } - def withBrowseUrl(browseUrl: java.net.URL): ScmInfo = { + def withBrowseUrl(browseUrl: java.net.URI): ScmInfo = { copy(browseUrl = browseUrl) } def withConnection(connection: String): ScmInfo = { @@ -40,7 +40,7 @@ final class ScmInfo private ( } object ScmInfo { - def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) - def apply(browseUrl: java.net.URL, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) - def apply(browseUrl: java.net.URL, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) + def apply(browseUrl: java.net.URI, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) + def apply(browseUrl: java.net.URI, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) + def apply(browseUrl: java.net.URI, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala index bacca95d8..70e7f40f0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala @@ -11,7 +11,7 @@ implicit lazy val ScmInfoFormat: JsonFormat[sbt.librarymanagement.ScmInfo] = new __jsOpt match { case Some(__js) => unbuilder.beginObject(__js) - val browseUrl = unbuilder.readField[java.net.URL]("browseUrl") + val browseUrl = unbuilder.readField[java.net.URI]("browseUrl") val connection = unbuilder.readField[String]("connection") val devConnection = unbuilder.readField[Option[String]]("devConnection") unbuilder.endObject() diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 6954a4f5b..42de1b0ae 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -728,7 +728,7 @@ "type": "record", "doc": "Basic SCM information for a project module", "fields": [ - { "name": "browseUrl", "type": "java.net.URL" }, + { "name": "browseUrl", "type": "java.net.URI" }, { "name": "connection", "type": "String" }, { "name": "devConnection", "type": "String?", "default": "None", "since": "0.0.1" } ] From cd393bb3183c63d8c8288ccede6b5afe45cbf7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Wed, 29 May 2024 17:42:23 +0100 Subject: [PATCH 1008/1030] ModuleInfo --- .../sbt/librarymanagement/ModuleInfo.scala | 16 ++++++++-------- .../librarymanagement/ModuleInfoFormats.scala | 6 +++--- core/src/main/contraband/librarymanagement.json | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index 383a144eb..46f2d6f7f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -8,11 +8,11 @@ package sbt.librarymanagement final class ModuleInfo private ( val nameFormal: String, val description: String, - val homepage: Option[java.net.URL], + val homepage: Option[java.net.URI], val startYear: Option[Int], - val licenses: Vector[scala.Tuple2[String, java.net.URL]], + val licenses: Vector[scala.Tuple2[String, java.net.URI]], val organizationName: String, - val organizationHomepage: Option[java.net.URL], + val organizationHomepage: Option[java.net.URI], val scmInfo: Option[sbt.librarymanagement.ScmInfo], val developers: Vector[sbt.librarymanagement.Developer]) extends Serializable { @@ -28,7 +28,7 @@ final class ModuleInfo private ( override def toString: String = { "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" } - private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { + private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URI] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URI]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URI] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } def withNameFormal(nameFormal: String): ModuleInfo = { @@ -37,19 +37,19 @@ final class ModuleInfo private ( def withDescription(description: String): ModuleInfo = { copy(description = description) } - def withHomepage(homepage: Option[java.net.URL]): ModuleInfo = { + def withHomepage(homepage: Option[java.net.URI]): ModuleInfo = { copy(homepage = homepage) } def withStartYear(startYear: Option[Int]): ModuleInfo = { copy(startYear = startYear) } - def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URL]]): ModuleInfo = { + def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URI]]): ModuleInfo = { copy(licenses = licenses) } def withOrganizationName(organizationName: String): ModuleInfo = { copy(organizationName = organizationName) } - def withOrganizationHomepage(organizationHomepage: Option[java.net.URL]): ModuleInfo = { + def withOrganizationHomepage(organizationHomepage: Option[java.net.URI]): ModuleInfo = { copy(organizationHomepage = organizationHomepage) } def withScmInfo(scmInfo: Option[sbt.librarymanagement.ScmInfo]): ModuleInfo = { @@ -62,5 +62,5 @@ final class ModuleInfo private ( object ModuleInfo { def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal) - def apply(nameFormal: String, description: String, homepage: Option[java.net.URL], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URL]], organizationName: String, organizationHomepage: Option[java.net.URL], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) + def apply(nameFormal: String, description: String, homepage: Option[java.net.URI], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URI]], organizationName: String, organizationHomepage: Option[java.net.URI], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala index 4707e0bd1..aa586ebca 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala @@ -13,11 +13,11 @@ implicit lazy val ModuleInfoFormat: JsonFormat[sbt.librarymanagement.ModuleInfo] unbuilder.beginObject(__js) val nameFormal = unbuilder.readField[String]("nameFormal") val description = unbuilder.readField[String]("description") - val homepage = unbuilder.readField[Option[java.net.URL]]("homepage") + val homepage = unbuilder.readField[Option[java.net.URI]]("homepage") val startYear = unbuilder.readField[Option[Int]]("startYear") - val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URL]]]("licenses") + val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URI]]]("licenses") val organizationName = unbuilder.readField[String]("organizationName") - val organizationHomepage = unbuilder.readField[Option[java.net.URL]]("organizationHomepage") + val organizationHomepage = unbuilder.readField[Option[java.net.URI]]("organizationHomepage") val scmInfo = unbuilder.readField[Option[sbt.librarymanagement.ScmInfo]]("scmInfo") val developers = unbuilder.readField[Vector[sbt.librarymanagement.Developer]]("developers") unbuilder.endObject() diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 42de1b0ae..37ede5b91 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -365,11 +365,11 @@ "fields": [ { "name": "nameFormal", "type": "String" }, { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "homepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "homepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "startYear", "type": "Option[Int]", "default": "None", "since": "0.0.1" }, - { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URI]*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "organizationHomepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "scmInfo", "type": "Option[sbt.librarymanagement.ScmInfo]", "default": "None", "since": "0.0.1" }, { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } ] From 861b8aa7921090f3abf1106d432181812d5fd6d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Wed, 29 May 2024 17:49:36 +0100 Subject: [PATCH 1009/1030] remove a few more java.net.URL --- .../librarymanagement/ComponentManager.scala | 5 +---- .../internal/librarymanagement/ConvertResolver.scala | 12 ++++++------ .../internal/librarymanagement/FakeResolver.scala | 2 +- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 710c120de..7f84c3bf8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -101,7 +101,7 @@ object IfMissing { object ComponentManager { lazy val (version, timestamp) = { val properties = new java.util.Properties - val propertiesStream = versionResource.openStream + val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") try { properties.load(propertiesStream) } finally { @@ -110,7 +110,4 @@ object ComponentManager { (properties.getProperty("version"), properties.getProperty("timestamp")) } lazy val stampedVersion = version + "_" + timestamp - - import java.net.URL - private def versionResource: URL = getClass.getResource("/xsbt.version.properties") } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 1bd0d7aad..ef59c2e02 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -394,17 +394,17 @@ private[sbt] object ConvertResolver { private[this] val repo = new WarnOnOverwriteFileRepo() private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { - val url = new URI(source).toURL - if (url.getProtocol == IO.FileScheme) - new FileResource(repo, IO.toFile(url)) + val uri = new URI(source) + if (uri.getScheme == IO.FileScheme) + new FileResource(repo, IO.toFile(uri)) else super.getResource(source) } override def put(source: File, destination: String, overwrite: Boolean): Unit = { - val url = new URI(destination).toURL + val uri = new URI(destination) try { - if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) + if (uri.getScheme != IO.FileScheme) super.put(source, destination, overwrite) else { // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler val resource = getResource(destination) @@ -417,7 +417,7 @@ private[sbt] object ConvertResolver { if (totalLength > 0) { progress.setTotalLength(totalLength); } - FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) + FileUtil.copy(source, new java.io.File(uri), progress, overwrite) () } catch { case ex: IOException => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 2d6ef89de..00c0275ae 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -69,7 +69,7 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) - val path = new URI(artifact.getLocation).toURL.toURI.getPath + val path = new URI(artifact.getLocation).getPath val localFile = new File(path) if (path.nonEmpty && localFile.exists) { From 649b6dffc21ad4c7f875f655468c0ecedab310ac Mon Sep 17 00:00:00 2001 From: Sam Desborough Date: Fri, 28 Jun 2024 13:05:54 +0100 Subject: [PATCH 1010/1030] Preserve backslashes in `expandMavenSettings` We use `expandMavenSettings` to turn environment variable expressions in `settings.xml` into their actual values. Before this change, if an environment variable value contained backslashes, they would have been treated as escape characters by `Regex.replaceAllIn` and removed from the returned string. This caused an issue when using backslashes for Windows paths. --- .../sbt/librarymanagement/ResolverExtra.scala | 25 +++++++++++++------ .../librarymanagement/ResolverExtraTest.scala | 7 ++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala index ca980b7e8..cb0eebe80 100644 --- a/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ResolverExtra.scala @@ -3,13 +3,15 @@ */ package sbt.librarymanagement -import java.io.{ IOException, File } +import java.io.{ File, IOException } import java.net.{ URI, URL } import scala.annotation.nowarn import scala.xml.XML import org.xml.sax.SAXParseException import sbt.util.Logger + import java.net.URI +import scala.util.matching.Regex final class RawRepository(val resolver: AnyRef, name: String) extends Resolver(name) { override def toString = "Raw(" + resolver.toString + ")" @@ -400,20 +402,29 @@ private[librarymanagement] abstract class ResolverFunctions { def defaultRetrievePattern = "[type]s/[organisation]/[module]/" + PluginPattern + "[artifact](-[revision])(-[classifier]).[ext]" final val PluginPattern = "(scala_[scalaVersion]/)(sbt_[sbtVersion]/)" - private[librarymanagement] def expandMavenSettings(str: String): String = { + + private[librarymanagement] def expandMavenSettings( + str: String, + envVars: Map[String, String] = sys.env, + props: Map[String, String] = sys.props.toMap + ): String = { // Aren't regular expressions beautifully clear and concise. // This means "find all ${...}" blocks, with the first group of each being the text between curly brackets. - val findQuoted = "\\$\\{([^\\}]*)\\}".r + val findQuoted = "\\$\\{([^}]*)}".r val env = "env\\.(.*)".r findQuoted.replaceAllIn( str, - _.group(1) match { - case env(variable) => sys.env.getOrElse(variable, "") - case property => sys.props.getOrElse(property, "") - } + regexMatch => + Regex.quoteReplacement { + regexMatch.group(1) match { + case env(variable) => envVars.getOrElse(variable, "") + case property => props.getOrElse(property, "") + } + } ) } + private[this] def mavenLocalDir: File = { def loadHomeFromSettings(f: () => File): Option[File] = try { diff --git a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala index 10cad9012..e1a06a944 100644 --- a/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala +++ b/core/src/test/scala/sbt/librarymanagement/ResolverExtraTest.scala @@ -33,6 +33,13 @@ object ResolverExtraTest extends BasicTestSuite { ) } + test("expandMavenSettings should preserve backslashes in environment variable values") { + val path = """C:\foo\bar\baz""" + val env = Map("SOME_PATH" -> path) + + assert(Resolver.expandMavenSettings("${env.SOME_PATH}", env) == path) + } + // - Helper functions ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------- def assertExpansion(input: String, expected: String) = From 765740c066320f700a588d4c9e23a71aeb87ddb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Sat, 6 Jul 2024 22:27:19 +0100 Subject: [PATCH 1011/1030] upgrade sbt-scalafmt (#440) Co-authored-by: eugene yokota --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 279b64f16..eaa324382 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,7 +1,7 @@ addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.0.0") addSbtPlugin("com.github.sbt" % "sbt-pgp" % "2.1.2") addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1") -addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.0.2") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.5.2") addSbtPlugin("org.scala-sbt" % "sbt-contraband" % "0.5.1") scalacOptions += "-language:postfixOps" From 598be45e2c9c8db2f8960ae9bac75080340433ad Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 6 Jul 2024 17:32:35 -0400 Subject: [PATCH 1012/1030] Update GitHub Actions --- .github/workflows/ci.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d938ee7f9..1f4f448c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,12 +10,15 @@ jobs: include: - os: ubuntu-latest java: 8 + distribution: zulu jobtype: 1 - os: ubuntu-latest java: 11 + distribution: temurin jobtype: 1 - - os: ubuntu-latest + - os: macos-latest java: 17 + distribution: temurin jobtype: 1 runs-on: ${{ matrix.os }} env: @@ -26,11 +29,13 @@ jobs: - name: Checkout uses: actions/checkout@v4 - name: Setup JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: - distribution: temurin + distribution: "${{ matrix.distribution }}" java-version: "${{ matrix.java }}" cache: sbt + - name: Setup sbt + uses: sbt/setup-sbt@v1 - name: Build and test (1) if: ${{ matrix.jobtype == 1 }} shell: bash From 3b3b155d1a3abf2d35938f14c4c119ca07dbd64a Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Sat, 6 Jul 2024 17:39:32 -0400 Subject: [PATCH 1013/1030] Relax the test --- .../sbt/internal/librarymanagement/ModuleResolversTest.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index d1b06b242..96f4c5b28 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -43,8 +43,7 @@ object ModuleResolversTest extends BaseIvySpecification { println(s"NORMAL RESOLUTION TIME $normalResolutionTime") println(s"FASTER RESOLUTION TIME $fasterResolutionTime") - // Check that faster resolution is at least 1/5 faster than normal resolution - // This is a conservative check just to make sure we don't regress -- speedup is higher - assert(fasterResolutionTime <= (normalResolutionTime * 0.80)) + // Check that faster resolution is faster + assert(fasterResolutionTime < normalResolutionTime) } } From 57254a6d32c0df3a965a9ae0db838518dccf6900 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 00:12:56 -0400 Subject: [PATCH 1014/1030] deps: bump util --- build.sbt | 2 +- project/Dependencies.scala | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/build.sbt b/build.sbt index 2c4f88214..a4ecadc13 100644 --- a/build.sbt +++ b/build.sbt @@ -271,7 +271,7 @@ lazy val lmCore = (project in file("core")) exclude[DirectMissingMethodProblem]("sbt.librarymanagement.ScalaArtifacts.toolDependencies*"), ), ) - .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache) + .configure(addSbtIO, addSbtUtilLogging, addSbtUtilPosition, addSbtUtilCache, addSbtCompilerInterface) lazy val lmIvy = (project in file("ivy")) // .enablePlugins(ContrabandPlugin, JsonCodecPlugin) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 860be2f06..776ac18f9 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -11,13 +11,16 @@ object Dependencies { sys.env.get("BUILD_VERSION") orElse sys.props.get("sbt.build.version") private val ioVersion = nightlyVersion.getOrElse("1.10.0") - private val utilVersion = nightlyVersion.getOrElse("2.0.0-alpha10") + private val utilVersion = nightlyVersion.getOrElse("2.0.0-M1") + private val zincVersion = nightlyVersion.getOrElse("2.0.0-M1") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion private val utilPosition = "org.scala-sbt" %% "util-position" % utilVersion private val utilLogging = "org.scala-sbt" %% "util-logging" % utilVersion - private val utilCache = "org.scala-sbt" %% "util-cache" % utilVersion + private val utilCache = ("org.scala-sbt" %% "util-cache" % utilVersion) + .exclude("org.scala-sbt", "compiler-interface") + private val compilerInterface = ("org.scala-sbt" % "compiler-interface" % zincVersion).force() def getSbtModulePath(key: String, name: String) = { val localProps = new java.util.Properties() @@ -29,6 +32,7 @@ object Dependencies { lazy val sbtIoPath = getSbtModulePath("sbtio.path", "sbt/io") lazy val sbtUtilPath = getSbtModulePath("sbtutil.path", "sbt/util") + lazy val sbtZincPath = getSbtModulePath("sbtzinc.path", "sbt/zinc") def addSbtModule(p: Project, path: Option[String], projectName: String, m: ModuleID) = path match { @@ -42,6 +46,8 @@ object Dependencies { def addSbtUtilLogging(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilLogging", utilLogging) def addSbtUtilCache(p: Project): Project = addSbtModule(p, sbtUtilPath, "utilCache", utilCache) + def addSbtCompilerInterface(p: Project) = + addSbtModule(p, sbtZincPath, "compilerInterface", compilerInterface) val launcherInterface = "org.scala-sbt" % "launcher-interface" % "1.0.0" val ivy = "org.scala-sbt.ivy" % "ivy" % "2.3.0-sbt-396a783bba347016e7fe30dacc60d355be607fe2" From dc8dbc61edb80e2a1f2387cfabf94a7e48c16839 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 00:18:39 -0400 Subject: [PATCH 1015/1030] Drop Ivy tests --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d938ee7f9..638973639 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,4 +35,4 @@ jobs: if: ${{ matrix.jobtype == 1 }} shell: bash run: | - sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll +test +packagedArtifacts + sbt -v -Dfile.encoding=UTF8 scalafmtCheckAll compile lmCore/test +packagedArtifacts From a01a2f8bacbdb77ef875b9f5c4c4dc6a8ea57cf2 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 04:08:09 -0400 Subject: [PATCH 1016/1030] Revert "remove a few more java.net.URL" This reverts commit 861b8aa7921090f3abf1106d432181812d5fd6d6. --- .../librarymanagement/ComponentManager.scala | 5 ++++- .../internal/librarymanagement/ConvertResolver.scala | 12 ++++++------ .../internal/librarymanagement/FakeResolver.scala | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 7f84c3bf8..710c120de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -101,7 +101,7 @@ object IfMissing { object ComponentManager { lazy val (version, timestamp) = { val properties = new java.util.Properties - val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") + val propertiesStream = versionResource.openStream try { properties.load(propertiesStream) } finally { @@ -110,4 +110,7 @@ object ComponentManager { (properties.getProperty("version"), properties.getProperty("timestamp")) } lazy val stampedVersion = version + "_" + timestamp + + import java.net.URL + private def versionResource: URL = getClass.getResource("/xsbt.version.properties") } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index ef59c2e02..1bd0d7aad 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -394,17 +394,17 @@ private[sbt] object ConvertResolver { private[this] val repo = new WarnOnOverwriteFileRepo() private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { - val uri = new URI(source) - if (uri.getScheme == IO.FileScheme) - new FileResource(repo, IO.toFile(uri)) + val url = new URI(source).toURL + if (url.getProtocol == IO.FileScheme) + new FileResource(repo, IO.toFile(url)) else super.getResource(source) } override def put(source: File, destination: String, overwrite: Boolean): Unit = { - val uri = new URI(destination) + val url = new URI(destination).toURL try { - if (uri.getScheme != IO.FileScheme) super.put(source, destination, overwrite) + if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) else { // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler val resource = getResource(destination) @@ -417,7 +417,7 @@ private[sbt] object ConvertResolver { if (totalLength > 0) { progress.setTotalLength(totalLength); } - FileUtil.copy(source, new java.io.File(uri), progress, overwrite) + FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) () } catch { case ex: IOException => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 00c0275ae..2d6ef89de 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -69,7 +69,7 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) - val path = new URI(artifact.getLocation).getPath + val path = new URI(artifact.getLocation).toURL.toURI.getPath val localFile = new File(path) if (path.nonEmpty && localFile.exists) { From 627cb888b20b0bb2419dad5541ee1d3015442218 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 04:09:21 -0400 Subject: [PATCH 1017/1030] Revert "ModuleInfo" This reverts commit cd393bb3183c63d8c8288ccede6b5afe45cbf7a7. --- .../sbt/librarymanagement/ModuleInfo.scala | 16 ++++++++-------- .../librarymanagement/ModuleInfoFormats.scala | 6 +++--- core/src/main/contraband/librarymanagement.json | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index 46f2d6f7f..383a144eb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -8,11 +8,11 @@ package sbt.librarymanagement final class ModuleInfo private ( val nameFormal: String, val description: String, - val homepage: Option[java.net.URI], + val homepage: Option[java.net.URL], val startYear: Option[Int], - val licenses: Vector[scala.Tuple2[String, java.net.URI]], + val licenses: Vector[scala.Tuple2[String, java.net.URL]], val organizationName: String, - val organizationHomepage: Option[java.net.URI], + val organizationHomepage: Option[java.net.URL], val scmInfo: Option[sbt.librarymanagement.ScmInfo], val developers: Vector[sbt.librarymanagement.Developer]) extends Serializable { @@ -28,7 +28,7 @@ final class ModuleInfo private ( override def toString: String = { "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" } - private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URI] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URI]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URI] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { + private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } def withNameFormal(nameFormal: String): ModuleInfo = { @@ -37,19 +37,19 @@ final class ModuleInfo private ( def withDescription(description: String): ModuleInfo = { copy(description = description) } - def withHomepage(homepage: Option[java.net.URI]): ModuleInfo = { + def withHomepage(homepage: Option[java.net.URL]): ModuleInfo = { copy(homepage = homepage) } def withStartYear(startYear: Option[Int]): ModuleInfo = { copy(startYear = startYear) } - def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URI]]): ModuleInfo = { + def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URL]]): ModuleInfo = { copy(licenses = licenses) } def withOrganizationName(organizationName: String): ModuleInfo = { copy(organizationName = organizationName) } - def withOrganizationHomepage(organizationHomepage: Option[java.net.URI]): ModuleInfo = { + def withOrganizationHomepage(organizationHomepage: Option[java.net.URL]): ModuleInfo = { copy(organizationHomepage = organizationHomepage) } def withScmInfo(scmInfo: Option[sbt.librarymanagement.ScmInfo]): ModuleInfo = { @@ -62,5 +62,5 @@ final class ModuleInfo private ( object ModuleInfo { def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal) - def apply(nameFormal: String, description: String, homepage: Option[java.net.URI], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URI]], organizationName: String, organizationHomepage: Option[java.net.URI], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) + def apply(nameFormal: String, description: String, homepage: Option[java.net.URL], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URL]], organizationName: String, organizationHomepage: Option[java.net.URL], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala index aa586ebca..4707e0bd1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala @@ -13,11 +13,11 @@ implicit lazy val ModuleInfoFormat: JsonFormat[sbt.librarymanagement.ModuleInfo] unbuilder.beginObject(__js) val nameFormal = unbuilder.readField[String]("nameFormal") val description = unbuilder.readField[String]("description") - val homepage = unbuilder.readField[Option[java.net.URI]]("homepage") + val homepage = unbuilder.readField[Option[java.net.URL]]("homepage") val startYear = unbuilder.readField[Option[Int]]("startYear") - val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URI]]]("licenses") + val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URL]]]("licenses") val organizationName = unbuilder.readField[String]("organizationName") - val organizationHomepage = unbuilder.readField[Option[java.net.URI]]("organizationHomepage") + val organizationHomepage = unbuilder.readField[Option[java.net.URL]]("organizationHomepage") val scmInfo = unbuilder.readField[Option[sbt.librarymanagement.ScmInfo]]("scmInfo") val developers = unbuilder.readField[Vector[sbt.librarymanagement.Developer]]("developers") unbuilder.endObject() diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 37ede5b91..42de1b0ae 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -365,11 +365,11 @@ "fields": [ { "name": "nameFormal", "type": "String" }, { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "homepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, + { "name": "homepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "startYear", "type": "Option[Int]", "default": "None", "since": "0.0.1" }, - { "name": "licenses", "type": "scala.Tuple2[String, java.net.URI]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "organizationHomepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "scmInfo", "type": "Option[sbt.librarymanagement.ScmInfo]", "default": "None", "since": "0.0.1" }, { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } ] From 7076596f26b6147b8827feab911e794df6710600 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 04:09:32 -0400 Subject: [PATCH 1018/1030] Revert "ScmInfo" This reverts commit b00e24274478862db3b070321a4957996508b9db. --- .../sbt/librarymanagement/ScmInfo.scala | 14 +++++++------- .../sbt/librarymanagement/ScmInfoFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index f91a5bbf1..4fadcae1f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -6,11 +6,11 @@ package sbt.librarymanagement /** Basic SCM information for a project module */ final class ScmInfo private ( - val browseUrl: java.net.URI, + val browseUrl: java.net.URL, val connection: String, val devConnection: Option[String]) extends Serializable { - private def this(browseUrl: java.net.URI, connection: String) = this(browseUrl, connection, None) + private def this(browseUrl: java.net.URL, connection: String) = this(browseUrl, connection, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ScmInfo => (this.browseUrl == x.browseUrl) && (this.connection == x.connection) && (this.devConnection == x.devConnection) @@ -22,10 +22,10 @@ final class ScmInfo private ( override def toString: String = { "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" } - private[this] def copy(browseUrl: java.net.URI = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { + private[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { new ScmInfo(browseUrl, connection, devConnection) } - def withBrowseUrl(browseUrl: java.net.URI): ScmInfo = { + def withBrowseUrl(browseUrl: java.net.URL): ScmInfo = { copy(browseUrl = browseUrl) } def withConnection(connection: String): ScmInfo = { @@ -40,7 +40,7 @@ final class ScmInfo private ( } object ScmInfo { - def apply(browseUrl: java.net.URI, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) - def apply(browseUrl: java.net.URI, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) - def apply(browseUrl: java.net.URI, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) + def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) + def apply(browseUrl: java.net.URL, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) + def apply(browseUrl: java.net.URL, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala index 70e7f40f0..bacca95d8 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala @@ -11,7 +11,7 @@ implicit lazy val ScmInfoFormat: JsonFormat[sbt.librarymanagement.ScmInfo] = new __jsOpt match { case Some(__js) => unbuilder.beginObject(__js) - val browseUrl = unbuilder.readField[java.net.URI]("browseUrl") + val browseUrl = unbuilder.readField[java.net.URL]("browseUrl") val connection = unbuilder.readField[String]("connection") val devConnection = unbuilder.readField[Option[String]]("devConnection") unbuilder.endObject() diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 42de1b0ae..6954a4f5b 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -728,7 +728,7 @@ "type": "record", "doc": "Basic SCM information for a project module", "fields": [ - { "name": "browseUrl", "type": "java.net.URI" }, + { "name": "browseUrl", "type": "java.net.URL" }, { "name": "connection", "type": "String" }, { "name": "devConnection", "type": "String?", "default": "None", "since": "0.0.1" } ] From 1d8280e8f2782959c9938fb27620c00837cc4b61 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 04:09:43 -0400 Subject: [PATCH 1019/1030] Revert "Developer" This reverts commit 03f0288ae64dea773ac012828c64d295ab87496a. --- .../sbt/librarymanagement/Developer.scala | 8 ++++---- .../sbt/librarymanagement/DeveloperFormats.scala | 2 +- core/src/main/contraband/librarymanagement.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index 0afb34a0f..fc52d4e7b 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -8,7 +8,7 @@ final class Developer private ( val id: String, val name: String, val email: String, - val url: java.net.URI) extends Serializable { + val url: java.net.URL) extends Serializable { @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URI = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { @@ -34,11 +34,11 @@ final class Developer private ( def withEmail(email: String): Developer = { copy(email = email) } - def withUrl(url: java.net.URI): Developer = { + def withUrl(url: java.net.URL): Developer = { copy(url = url) } } object Developer { - def apply(id: String, name: String, email: String, url: java.net.URI): Developer = new Developer(id, name, email, url) + def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index 3a7cdbf60..381013ab0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -14,7 +14,7 @@ implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") val email = unbuilder.readField[String]("email") - val url = unbuilder.readField[java.net.URI]("url") + val url = unbuilder.readField[java.net.URL]("url") unbuilder.endObject() sbt.librarymanagement.Developer(id, name, email, url) case None => diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 6954a4f5b..8f87d7040 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -244,7 +244,7 @@ { "name": "id", "type": "String" }, { "name": "name", "type": "String" }, { "name": "email", "type": "String" }, - { "name": "url", "type": "java.net.URI" } + { "name": "url", "type": "java.net.URL" } ] }, { From 18a9af89f7400a9aab8932b6be4b110670e70526 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 4 Oct 2024 04:09:53 -0400 Subject: [PATCH 1020/1030] Revert "Artifact" This reverts commit d078dc4772de3f892a1633a3bc3be0440b121097. --- .../sbt/librarymanagement/Artifact.scala | 12 +++++------ .../librarymanagement/ArtifactFormats.scala | 2 +- .../main/contraband/librarymanagement.json | 2 +- .../sbt/librarymanagement/ArtifactExtra.scala | 21 +++++++++---------- .../sbt/librarymanagement/ModuleIDExtra.scala | 2 +- .../sbt/internal/librarymanagement/Ivy.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 2 +- .../DMSerializationSpec.scala | 2 +- 8 files changed, 22 insertions(+), 23 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index e7d033043..24764d0cb 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -10,13 +10,13 @@ final class Artifact private ( val extension: String, val classifier: Option[String], val configurations: Vector[sbt.librarymanagement.ConfigRef], - val url: Option[java.net.URI], + val url: Option[java.net.URL], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum], val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger) private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) - private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) + private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) @@ -28,7 +28,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URI] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } def withName(name: String): Artifact = { @@ -46,7 +46,7 @@ final class Artifact private ( def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): Artifact = { copy(configurations = configurations) } - def withUrl(url: Option[java.net.URI]): Artifact = { + def withUrl(url: Option[java.net.URL]): Artifact = { copy(url = url) } def withExtraAttributes(extraAttributes: Map[String, String]): Artifact = { @@ -62,6 +62,6 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index 6b92852cf..ae951d635 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -16,7 +16,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") - val url = unbuilder.readField[Option[java.net.URI]]("url") + val url = unbuilder.readField[Option[java.net.URL]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 8f87d7040..89d20007d 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -141,7 +141,7 @@ { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "url", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, + { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" }, { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 411f486aa..63a992d2d 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -4,7 +4,7 @@ package sbt.librarymanagement import java.io.File -import java.net.URI +import java.net.URL private[librarymanagement] abstract class ArtifactExtra { def extraAttributes: Map[String, String] @@ -26,15 +26,15 @@ private[librarymanagement] abstract class ArtifactFunctions { Artifact(name, `type`, extension, None, Vector.empty, None) def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) - def apply(name: String, uri: URI): Artifact = Artifact(name, uri, false) - def apply(name: String, uri: URI, allowInsecureProtocol: Boolean): Artifact = + def apply(name: String, url: URL): Artifact = Artifact(name, url, false) + def apply(name: String, url: URL, allowInsecureProtocol: Boolean): Artifact = Artifact( name, - extract(uri, DefaultType), - extract(uri, DefaultExtension), + extract(url, DefaultType), + extract(url, DefaultExtension), None, Vector.empty, - Some(uri), + Some(url), Map.empty, None, allowInsecureProtocol @@ -47,9 +47,8 @@ private[librarymanagement] abstract class ArtifactFunctions { extension: String, classifier: Option[String], configurations: Vector[ConfigRef], - uri: Option[URI] - ): Artifact = - Artifact(name, `type`, extension, classifier, configurations, uri, empty, None) + url: Option[URL] + ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) val DefaultExtension = "jar" val DefaultType = "jar" @@ -79,7 +78,7 @@ private[librarymanagement] abstract class ArtifactFunctions { assert(DefaultDocTypes contains DocType) assert(DefaultSourceTypes contains SourceType) - def extract(uri: URI, default: String): String = extract(uri.toString, default) + def extract(url: URL, default: String): String = extract(url.toString, default) def extract(name: String, default: String): String = { val i = name.lastIndexOf('.') if (i >= 0) @@ -97,7 +96,7 @@ private[librarymanagement] abstract class ArtifactFunctions { extract(name, DefaultExtension), None, Vector.empty, - Some(file.toURI) + Some(file.toURI.toURL) ) } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 4d9803394..f62f83d1b 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -133,7 +133,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * It is not included in published metadata. */ def from(url: String, allowInsecureProtocol: Boolean): ModuleID = - artifacts(Artifact(name, new URI(url), allowInsecureProtocol)) + artifacts(Artifact(name, new URI(url).toURL, allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 8c6350905..97bc40143 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -1000,7 +1000,7 @@ private[sbt] object IvySbt { name, `type`, extension, - url.map(_.toURL).orNull, + url.orNull, extraMap ) copyConfigurations(artifact, (ref: ConfigRef) => { ivyArtifact.addConfiguration(ref.name) }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 0560036d3..a1784ffd0 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -229,7 +229,7 @@ object IvyRetrieve { getConfigurations.toVector map { (c: String) => ConfigRef(c) }, - Option(getUrl).map(_.toURI) + Option(getUrl) ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index b380800fc..bc035efa1 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -43,7 +43,7 @@ object DMSerializationSpec extends BasicTestSuite { } test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { - roundtrip(Artifact("foo", new URI("http://example.com/"))) + roundtrip(Artifact("foo", new URI("http://example.com/").toURL)) } test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { From 950d084f3533f68456930771e39cd9b24d606e34 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sat, 5 Oct 2024 06:58:09 +0900 Subject: [PATCH 1021/1030] update scalacOptions --- project/HouseRulesPlugin.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/project/HouseRulesPlugin.scala b/project/HouseRulesPlugin.scala index 3d29c00d1..a5f7d3b7f 100644 --- a/project/HouseRulesPlugin.scala +++ b/project/HouseRulesPlugin.scala @@ -11,11 +11,11 @@ object HouseRulesPlugin extends AutoPlugin { lazy val baseSettings: Seq[Def.Setting[_]] = Seq( scalacOptions ++= Seq("-encoding", "utf8"), - scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked", "-Xlint"), + scalacOptions ++= Seq("-deprecation", "-feature", "-unchecked"), scalacOptions += "-language:higherKinds", scalacOptions += "-language:implicitConversions", scalacOptions ++= "-Xfuture".ifScala213OrMinus.value.toList, - scalacOptions += "-Xlint", + scalacOptions ++= "-Xlint".ifScala213OrMinus.value, scalacOptions ++= "-Xfatal-warnings" .ifScala(v => { sys.props.get("sbt.build.fatal") match { @@ -27,9 +27,9 @@ object HouseRulesPlugin extends AutoPlugin { .toList, scalacOptions ++= "-Yinline-warnings".ifScala211OrMinus.value.toList, scalacOptions ++= "-Yno-adapted-args".ifScala212OrMinus.value.toList, - scalacOptions += "-Ywarn-dead-code", - scalacOptions += "-Ywarn-numeric-widen", - scalacOptions += "-Ywarn-value-discard", + scalacOptions ++= "-Ywarn-dead-code".ifScala213OrMinus.value, + scalacOptions ++= "-Ywarn-numeric-widen".ifScala213OrMinus.value, + scalacOptions ++= "-Ywarn-value-discard".ifScala213OrMinus.value, scalacOptions ++= "-Ywarn-unused-import".ifScala(v => 11 <= v && v <= 12).value.toList ) ++ Seq(Compile, Test).flatMap(c => (c / console / scalacOptions) --= Seq("-Ywarn-unused-import", "-Xlint") From fdaa66202dc0ffe9d4f8342be7de0de9560bad03 Mon Sep 17 00:00:00 2001 From: xuwei-k <6b656e6a69@gmail.com> Date: Sat, 5 Oct 2024 07:14:07 +0900 Subject: [PATCH 1022/1030] fix warnings --- .../librarymanagement/ConflictWarning.scala | 2 +- .../DependencyResolution.scala | 4 ++-- .../sbt/librarymanagement/ModuleIDExtra.scala | 2 +- .../librarymanagement/ConvertResolver.scala | 2 +- .../librarymanagement/CustomPomParser.scala | 12 +++++----- .../sbt/internal/librarymanagement/Ivy.scala | 10 ++++---- .../librarymanagement/IvyActions.scala | 2 +- .../CachedResolutionResolveEngine.scala | 2 +- .../ivyint/IvyCredentialsLookup.scala | 21 ++++++++++------- .../ivyint/ParallelResolveEngine.scala | 2 +- .../ivyint/SbtChainResolver.scala | 6 ++--- .../PomExtraDependencyAttributes.scala | 10 ++++---- .../librarymanagement/ivy/Credentials.scala | 2 +- .../librarymanagement/FrozenModeSpec.scala | 23 ++++++++++++++----- .../librarymanagement/IvyRepoSpec.scala | 3 +-- .../ManagedChecksumsSpec.scala | 2 +- .../ModuleResolversTest.scala | 6 +++-- .../librarymanagement/OfflineModeSpec.scala | 8 ++++--- 18 files changed, 69 insertions(+), 50 deletions(-) diff --git a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala index bed999164..5122b0144 100644 --- a/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala +++ b/core/src/main/scala/sbt/librarymanagement/ConflictWarning.scala @@ -44,7 +44,7 @@ object ConflictWarning { /** Map from (organization, rawName) to set of multiple full names. */ def crossVersionMismatches(report: UpdateReport): Map[(String, String), Set[String]] = { val mismatches = report.configurations.flatMap { confReport => - groupByRawName(confReport.allModules).mapValues { modules => + groupByRawName(confReport.allModules).view.mapValues { modules => val differentFullNames = modules.map(_.name).toSet if (differentFullNames.size > 1) differentFullNames else Set.empty[String] } diff --git a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala index 1f2b37a2d..71b85a272 100644 --- a/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala +++ b/core/src/main/scala/sbt/librarymanagement/DependencyResolution.scala @@ -186,8 +186,8 @@ class DependencyResolution private[sbt] (lmEngine: DependencyResolutionInterface // The artifacts that came from Ivy don't have their classifier set, let's set it according to // FIXME: this is only done because IDE plugins depend on `classifier` to determine type. They val typeClassifierMap: Map[String, String] = - ((sourceArtifactTypes.toIterable map (_ -> Artifact.SourceClassifier)) - :: (docArtifactTypes.toIterable map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap + ((sourceArtifactTypes.toSeq map (_ -> Artifact.SourceClassifier)) + :: (docArtifactTypes.toSeq map (_ -> Artifact.DocClassifier)) :: Nil).flatten.toMap Right(r.substitute { (conf, mid, artFileSeq) => artFileSeq map { case (art, f) => // Deduce the classifier from the type if no classifier is present already diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index f62f83d1b..0778ad831 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -64,7 +64,7 @@ private[librarymanagement] abstract class ModuleIDExtra { /** Returns the extra attributes except for ones marked as information only (ones that typically would not be used for dependency resolution). */ def extraDependencyAttributes: Map[String, String] = - extraAttributes.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)).toMap + extraAttributes.view.filterKeys(!_.startsWith(SbtPomExtraProperties.POM_INFO_KEY_PREFIX)).toMap @deprecated( "Use `cross(CrossVersion)`, the variant accepting a CrossVersion value constructed by a member of the CrossVersion object instead.", diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 1bd0d7aad..adc202711 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -35,7 +35,7 @@ import org.apache.ivy.core.module.descriptor.DefaultArtifact import org.apache.ivy.core.report.DownloadReport import org.apache.ivy.plugins.resolver.util.{ ResolvedResource, ResourceMDParser } import org.apache.ivy.util.{ ChecksumHelper, FileUtil, Message } -import scala.collection.JavaConverters._ +import scala.jdk.CollectionConverters._ import sbt.internal.librarymanagement.mavenint.PomExtraDependencyAttributes import sbt.io.IO import sbt.util.Logger diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index eb9378880..e7ded5b3a 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -171,7 +171,7 @@ object CustomPomParser { // The extra sbt plugin metadata in pom.xml does not need to be readable by maven, but the other information may be. // However, the pom.xml needs to be valid in all cases because other tools like repository managers may read the pom.xml. private[sbt] def getPomProperties(md: ModuleDescriptor): Map[String, String] = { - import collection.JavaConverters._ + import scala.jdk.CollectionConverters._ PomModuleDescriptorBuilder .extractPomProperties(md.getExtraInfo) .asInstanceOf[java.util.Map[String, String]] @@ -182,13 +182,13 @@ object CustomPomParser { (propertyAttributes - ExtraAttributesKey) map { case (k, v) => ("e:" + k, v) } private[this] def shouldBeUnqualified(m: Map[String, String]): Map[String, String] = - m.filterKeys(unqualifiedKeys).toMap + m.view.filterKeys(unqualifiedKeys).toMap private[this] def addExtra( properties: Map[String, String], id: ModuleRevisionId ): ModuleRevisionId = { - import collection.JavaConverters._ + import scala.jdk.CollectionConverters._ val oldExtra = qualifiedExtra(id) val newExtra = (oldExtra ++ properties).asJava // remove the sbt plugin cross version from the resolved ModuleRevisionId @@ -211,9 +211,9 @@ object CustomPomParser { def qualifiedExtra(item: ExtendableItem): Map[String, String] = PomExtraDependencyAttributes.qualifiedExtra(item) def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = - (qualifiedExtra(item) filterKeys { k => + qualifiedExtra(item).view.filterKeys { k => qualifiedIsExtra(k) == include - }).toMap + }.toMap def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = PomExtraDependencyAttributes.writeDependencyExtra(s) @@ -275,7 +275,7 @@ object CustomPomParser { case None => dd } - import collection.JavaConverters._ + import scala.jdk.CollectionConverters._ def addExtra( properties: Map[String, String], dependencyExtra: Map[ModuleRevisionId, Map[String, String]], diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 97bc40143..48d360c5c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -561,7 +561,7 @@ private[sbt] object IvySbt { * Clearly, it would be better to have an explicit option in Ivy to control this. */ def hasImplicitClassifier(artifact: IArtifact): Boolean = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ artifact.getQualifiedExtraAttributes.asScala.keys .exists(_.asInstanceOf[String] startsWith "m:") } @@ -795,7 +795,7 @@ private[sbt] object IvySbt { artifact } def getExtraAttributes(revID: ExtendableItem): Map[String, String] = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ revID.getExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } private[sbt] def extra( @@ -808,7 +808,7 @@ private[sbt] object IvySbt { javaMap(ea.extraAttributes, unqualify) } private[sbt] def javaMap(m: Map[String, String], unqualify: Boolean = false) = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ val map = if (unqualify) m map { case (k, v) => (k.stripPrefix("e:"), v) } else m if (map.isEmpty) null else map.asJava @@ -962,9 +962,9 @@ private[sbt] object IvySbt { deps.put(id, updated) } - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ deps.values.asScala.toSeq.flatMap { dds => - val mergeable = (dds, dds.tail).zipped.forall(ivyint.MergeDescriptors.mergeable _) + val mergeable = dds.lazyZip(dds.tail).forall(ivyint.MergeDescriptors.mergeable _) if (mergeable) dds.reverse.reduceLeft(ivyint.MergeDescriptors.apply _) :: Nil else dds } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 42a0eed7f..62099d06e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -236,7 +236,7 @@ object IvyActions { }.toMap def grouped[T](grouping: ModuleID => T)(mods: Seq[ModuleID]): Map[T, Set[String]] = - mods.groupBy(grouping).mapValues(_.map(_.revision).toSet).toMap + mods.groupBy(grouping).view.mapValues(_.map(_.revision).toSet).toMap def addExcluded( report: UpdateReport, diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 57d1eed9b..9eea99693 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -158,7 +158,7 @@ private[sbt] class CachedResolutionResolveCache { (md1, IvySbt.isChanging(dd) || internalDependency(dd, prOpt).isDefined, dd) } def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { case (k, _) => k.toString diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala index 9d8148323..9630e3258 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/IvyCredentialsLookup.scala @@ -2,7 +2,7 @@ package sbt.internal.librarymanagement package ivyint import org.apache.ivy.util.url.CredentialsStore -import collection.JavaConverters._ +import scala.jdk.CollectionConverters._ /** A key used to store credentials in the ivy credentials store. */ private[sbt] sealed trait CredentialKey @@ -56,11 +56,16 @@ private[sbt] object IvyCredentialsLookup { * A mapping of host -> realms in the ivy credentials store. */ def realmsForHost: Map[String, Set[String]] = - (keyringKeys collect { case x: Realm => - x - } groupBy { realm => - realm.host - } mapValues { realms => - realms map (_.realm) - }).toMap + keyringKeys + .collect { case x: Realm => + x + } + .groupBy { realm => + realm.host + } + .view + .mapValues { realms => + realms map (_.realm) + } + .toMap } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala index 711e03225..e683e5710 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/ParallelResolveEngine.scala @@ -40,7 +40,7 @@ private[sbt] class ParallelResolveEngine( artifactFilter: Filter, options: DownloadOptions ): Unit = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ val start = System.currentTimeMillis report.getArtifacts match { case typed: java.util.List[Artifact @unchecked] => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala index 9dfd3b83f..494e72d91 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/SbtChainResolver.scala @@ -433,9 +433,9 @@ private[sbt] case class SbtChainResolver( case _ => None } - val artifactRefs = md.getConfigurations.toIterator flatMap { conf => - md.getArtifacts(conf.getName).toIterator flatMap { af => - artifactRef(af, data.getDate).toIterator + val artifactRefs = md.getConfigurations.iterator flatMap { conf => + md.getArtifacts(conf.getName).iterator flatMap { af => + artifactRef(af, data.getDate).iterator } } if (artifactRefs.hasNext) Some(artifactRefs.next()) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index 25ab896b1..7e2d79c33 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -35,7 +35,7 @@ object PomExtraDependencyAttributes { def readFromAether( props: java.util.Map[String, AnyRef] ): Map[ModuleRevisionId, Map[String, String]] = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ (props.asScala get ExtraAttributesKey) match { case None => Map.empty case Some(str) => @@ -74,13 +74,13 @@ object PomExtraDependencyAttributes { } def qualifiedExtra(item: ExtendableItem): Map[String, String] = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = - (qualifiedExtra(item) filterKeys { k => + qualifiedExtra(item).view.filterKeys { k => qualifiedIsExtra(k) == include - }).toMap + }.toMap def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) @@ -89,7 +89,7 @@ object PomExtraDependencyAttributes { // This makes the id suitable as a key to associate a dependency parsed from a element // with the extra attributes from the section def simplify(id: ModuleRevisionId): ModuleRevisionId = { - import scala.collection.JavaConverters._ + import scala.jdk.CollectionConverters._ ModuleRevisionId.newInstance( id.getOrganisation, id.getName, diff --git a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala index 656247304..ee29f9f60 100644 --- a/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala +++ b/ivy/src/main/scala/sbt/librarymanagement/ivy/Credentials.scala @@ -67,7 +67,7 @@ object Credentials { private[this] val UserKeys = List("user", "user.name", "username") private[this] val PasswordKeys = List("password", "pwd", "pass", "passwd") - import collection.JavaConverters._ + import scala.jdk.CollectionConverters._ private[this] def read(from: File): Map[String, String] = { val properties = new java.util.Properties IO.load(properties, from) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala index ab6a93c90..7186fd68b 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/FrozenModeSpec.scala @@ -34,18 +34,23 @@ object FrozenModeSpec extends BaseIvySpecification { val toResolve = module(defaultModuleId, stoml, None, normalOptions) val onlineResolution = update(toResolve, onlineConf) assert(onlineResolution.isRight) - val numberResolved = onlineResolution.right.get.allModules.size - val numberReportsResolved = onlineResolution.right.get.allModuleReports.size + val numberResolved = + onlineResolution.fold(e => throw e.resolveException, identity).allModules.size + val numberReportsResolved = + onlineResolution.fold(e => throw e.resolveException, identity).allModuleReports.size cleanIvyCache() val singleFrozenResolution = update(toResolve, frozenConf) assert(singleFrozenResolution.isRight) assert( - singleFrozenResolution.right.get.allModules.size == 1, + singleFrozenResolution.fold(e => throw e.resolveException, identity).allModules.size == 1, s"The number of explicit modules in frozen mode should 1" ) assert( - singleFrozenResolution.right.get.allModuleReports.size == 1, + singleFrozenResolution + .fold(e => throw e.resolveException, identity) + .allModuleReports + .size == 1, s"The number of explicit module reports in frozen mode should 1" ) @@ -55,11 +60,17 @@ object FrozenModeSpec extends BaseIvySpecification { val frozenResolution = update(toExplicitResolve, frozenConf) assert(frozenResolution.isRight) assert( - frozenResolution.right.get.allModules.size == numberResolved, + frozenResolution + .fold(e => throw e.resolveException, identity) + .allModules + .size == numberResolved, s"The number of explicit modules in frozen mode should be equal than $numberResolved" ) assert( - frozenResolution.right.get.allModuleReports.size == numberReportsResolved, + frozenResolution + .fold(e => throw e.resolveException, identity) + .allModuleReports + .size == numberReportsResolved, s"The number of explicit module reports in frozen mode should be equal than $numberReportsResolved" ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala index c3235b934..e9902bc96 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/IvyRepoSpec.scala @@ -84,8 +84,7 @@ object IvyRepoSpec extends BaseIvySpecification { val report2 = lmEngine() .updateClassifiers(gcm, UnresolvedWarningConfiguration(), Vector(), log) - .right - .get + .fold(e => throw e.resolveException, identity) import Inside._ inside(report2.configuration(ConfigRef("compile")).map(_.modules)) { case Some(Seq(mr)) => diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala index fb2bc687a..df8241a2c 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ManagedChecksumsSpec.scala @@ -51,7 +51,7 @@ object ManagedChecksumsSpec extends BaseIvySpecification { val toResolve = module(defaultModuleId, dependencies, None, updateOptions) val res = IvyActions.updateEither(toResolve, onlineConf, warningConf, log) assert(res.isRight, s"Resolution with managed checksums failed! $res") - val updateReport = res.right.get + val updateReport = res.fold(e => throw e.resolveException, identity) val allModuleReports = updateReport.configurations.flatMap(_.modules) val allArtifacts: Seq[File] = allModuleReports.flatMap(_.artifacts.map(_._2)) allArtifacts.foreach(assertChecksumExists) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index d1b06b242..5541937c7 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -26,7 +26,8 @@ object ModuleResolversTest extends BaseIvySpecification { val ivyModule = module(stubModule, dependencies, None, updateOptions) val normalResolution = ivyUpdateEither(ivyModule) assert(normalResolution.isRight) - val normalResolutionTime = normalResolution.right.get.stats.resolveTime + val normalResolutionTime = + normalResolution.fold(e => throw e.resolveException, identity).stats.resolveTime cleanIvyCache() val moduleResolvers = Map( @@ -37,7 +38,8 @@ object ModuleResolversTest extends BaseIvySpecification { val ivyModule2 = module(stubModule, dependencies, None, customUpdateOptions) val fasterResolution = ivyUpdateEither(ivyModule2) assert(fasterResolution.isRight) - val fasterResolutionTime = fasterResolution.right.get.stats.resolveTime + val fasterResolutionTime = + fasterResolution.fold(e => throw e.resolveException, identity).stats.resolveTime // THis is left on purpose so that in spurious error we see the times println(s"NORMAL RESOLUTION TIME $normalResolutionTime") diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala index 5044be951..04484931e 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/OfflineModeSpec.scala @@ -34,14 +34,16 @@ object OfflineModeSpec extends BaseIvySpecification { val onlineResolution = IvyActions.updateEither(toResolve, onlineConf, warningConf, log) assert(onlineResolution.isRight) - assert(onlineResolution.right.exists(report => report.stats.resolveTime > 0)) + assert(onlineResolution.toOption.exists(report => report.stats.resolveTime > 0)) - val originalResolveTime = onlineResolution.right.get.stats.resolveTime + val originalResolveTime = + onlineResolution.fold(e => throw e.resolveException, identity).stats.resolveTime val offlineResolution = IvyActions.updateEither(toResolve, offlineConf, warningConf, log) assert(offlineResolution.isRight) - val resolveTime = offlineResolution.right.get.stats.resolveTime + val resolveTime = + offlineResolution.fold(e => throw e.resolveException, identity).stats.resolveTime assert(originalResolveTime > resolveTime) } From dd9e3265031fc318066935417182dac4f84fde67 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 7 Oct 2024 15:41:15 +0200 Subject: [PATCH 1023/1030] Exclude custom extra from POM dependency --- .../PomExtraDependencyAttributes.scala | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index 25ab896b1..4160b6009 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -78,9 +78,7 @@ object PomExtraDependencyAttributes { item.getQualifiedExtraAttributes.asInstanceOf[java.util.Map[String, String]].asScala.toMap } def filterCustomExtra(item: ExtendableItem, include: Boolean): Map[String, String] = - (qualifiedExtra(item) filterKeys { k => - qualifiedIsExtra(k) == include - }).toMap + qualifiedExtra(item).filterKeys { k => qualifiedIsExtra(k) == include }.toMap def qualifiedIsExtra(k: String): Boolean = k.endsWith(ScalaVersionKey) || k.endsWith(SbtVersionKey) @@ -107,17 +105,27 @@ object PomExtraDependencyAttributes { /** * Creates the "extra" property values for DependencyDescriptors that can be written into a maven pom - * so we don't loose the information. + * so we don't lose the information. * @param s * @return */ def writeDependencyExtra(s: Seq[DependencyDescriptor]): Seq[String] = s.flatMap { dd => val revId = dd.getDependencyRevisionId - if (filterCustomExtra(revId, include = true).isEmpty) + val filteredExtra = filterCustomExtra(revId, include = true) + if (filteredExtra.isEmpty) Nil - else - revId.encodeToString :: Nil + else { + import scala.collection.JavaConverters._ + val revId0 = ModuleRevisionId.newInstance( + revId.getOrganisation, + revId.getName, + revId.getBranch, + revId.getRevision, + filteredExtra.asJava + ) + revId0.encodeToString :: Nil + } } } From a4d2b9c03bac2a8167ccab9d3a0e31ddfcf2987a Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Mon, 7 Oct 2024 15:41:25 +0200 Subject: [PATCH 1024/1030] Fix ModuleResolversTest --- .../internal/librarymanagement/ModuleResolversTest.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala index 96f4c5b28..94c30d244 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/ModuleResolversTest.scala @@ -3,13 +3,13 @@ package sbt.internal.librarymanagement import sbt.librarymanagement._ import sbt.librarymanagement.syntax._ import sbt.librarymanagement.ivy.UpdateOptions -import Resolver._ object ModuleResolversTest extends BaseIvySpecification { override final val resolvers = Vector( - DefaultMavenRepository, - JavaNet2Repository, - JCenterRepository, + MavenRepository( + "JFrog OSS Releases", + "https://releases.jfrog.io/artifactory/oss-releases/" + ), Resolver.sbtPluginRepo("releases") ) From 099087f486d274635efc9a29d7c6ef7e0deecd60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 22:10:40 +0100 Subject: [PATCH 1025/1030] Revert "Merge pull request #447 from eed3si9n/wip/revert" This reverts commit ddf3f5ef99726106e940eefe80b894dce4587241, reversing changes made to cb24883c154dab489ae728d144f16be78f16ee58. --- .../sbt/librarymanagement/Artifact.scala | 12 +++++------ .../librarymanagement/ArtifactFormats.scala | 2 +- .../sbt/librarymanagement/Developer.scala | 8 +++---- .../librarymanagement/DeveloperFormats.scala | 2 +- .../sbt/librarymanagement/ModuleInfo.scala | 16 +++++++------- .../librarymanagement/ModuleInfoFormats.scala | 6 +++--- .../sbt/librarymanagement/ScmInfo.scala | 14 ++++++------- .../librarymanagement/ScmInfoFormats.scala | 2 +- .../main/contraband/librarymanagement.json | 12 +++++------ .../sbt/librarymanagement/ArtifactExtra.scala | 21 ++++++++++--------- .../sbt/librarymanagement/ModuleIDExtra.scala | 2 +- .../librarymanagement/ComponentManager.scala | 5 +---- .../librarymanagement/ConvertResolver.scala | 12 +++++------ .../librarymanagement/FakeResolver.scala | 2 +- .../sbt/internal/librarymanagement/Ivy.scala | 2 +- .../librarymanagement/IvyRetrieve.scala | 2 +- .../DMSerializationSpec.scala | 2 +- 17 files changed, 60 insertions(+), 62 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala index 24764d0cb..e7d033043 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Artifact.scala @@ -10,13 +10,13 @@ final class Artifact private ( val extension: String, val classifier: Option[String], val configurations: Vector[sbt.librarymanagement.ConfigRef], - val url: Option[java.net.URL], + val url: Option[java.net.URI], val extraAttributes: Map[String, String], val checksum: Option[sbt.librarymanagement.Checksum], val allowInsecureProtocol: Boolean) extends sbt.librarymanagement.ArtifactExtra with Serializable { private[sbt] def validateProtocol(logger: sbt.util.Logger): Boolean = Resolver.validateArtifact(this, logger) private def this(name: String) = this(name, Artifact.DefaultType, Artifact.DefaultExtension, None, Vector.empty, None, Map.empty, None, false) - private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) + private def this(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]) = this(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, false) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: Artifact => (this.name == x.name) && (this.`type` == x.`type`) && (this.extension == x.extension) && (this.classifier == x.classifier) && (this.configurations == x.configurations) && (this.url == x.url) && (this.extraAttributes == x.extraAttributes) && (this.checksum == x.checksum) && (this.allowInsecureProtocol == x.allowInsecureProtocol) @@ -28,7 +28,7 @@ final class Artifact private ( override def toString: String = { "Artifact(" + name + ", " + `type` + ", " + extension + ", " + classifier + ", " + configurations + ", " + url + ", " + extraAttributes + ", " + checksum + ", " + allowInsecureProtocol + ")" } - private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URL] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { + private[this] def copy(name: String = name, `type`: String = `type`, extension: String = extension, classifier: Option[String] = classifier, configurations: Vector[sbt.librarymanagement.ConfigRef] = configurations, url: Option[java.net.URI] = url, extraAttributes: Map[String, String] = extraAttributes, checksum: Option[sbt.librarymanagement.Checksum] = checksum, allowInsecureProtocol: Boolean = allowInsecureProtocol): Artifact = { new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } def withName(name: String): Artifact = { @@ -46,7 +46,7 @@ final class Artifact private ( def withConfigurations(configurations: Vector[sbt.librarymanagement.ConfigRef]): Artifact = { copy(configurations = configurations) } - def withUrl(url: Option[java.net.URL]): Artifact = { + def withUrl(url: Option[java.net.URI]): Artifact = { copy(url = url) } def withExtraAttributes(extraAttributes: Map[String, String]): Artifact = { @@ -62,6 +62,6 @@ final class Artifact private ( object Artifact extends sbt.librarymanagement.ArtifactFunctions { def apply(name: String): Artifact = new Artifact(name) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) - def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URL], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum]): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum) + def apply(name: String, `type`: String, extension: String, classifier: Option[String], configurations: Vector[sbt.librarymanagement.ConfigRef], url: Option[java.net.URI], extraAttributes: Map[String, String], checksum: Option[sbt.librarymanagement.Checksum], allowInsecureProtocol: Boolean): Artifact = new Artifact(name, `type`, extension, classifier, configurations, url, extraAttributes, checksum, allowInsecureProtocol) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala index ae951d635..6b92852cf 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ArtifactFormats.scala @@ -16,7 +16,7 @@ implicit lazy val ArtifactFormat: JsonFormat[sbt.librarymanagement.Artifact] = n val extension = unbuilder.readField[String]("extension") val classifier = unbuilder.readField[Option[String]]("classifier") val configurations = unbuilder.readField[Vector[sbt.librarymanagement.ConfigRef]]("configurations") - val url = unbuilder.readField[Option[java.net.URL]]("url") + val url = unbuilder.readField[Option[java.net.URI]]("url") val extraAttributes = unbuilder.readField[Map[String, String]]("extraAttributes") val checksum = unbuilder.readField[Option[sbt.librarymanagement.Checksum]]("checksum") val allowInsecureProtocol = unbuilder.readField[Boolean]("allowInsecureProtocol") diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala index fc52d4e7b..0afb34a0f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/Developer.scala @@ -8,7 +8,7 @@ final class Developer private ( val id: String, val name: String, val email: String, - val url: java.net.URL) extends Serializable { + val url: java.net.URI) extends Serializable { @@ -22,7 +22,7 @@ final class Developer private ( override def toString: String = { "Developer(" + id + ", " + name + ", " + email + ", " + url + ")" } - private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URL = url): Developer = { + private[this] def copy(id: String = id, name: String = name, email: String = email, url: java.net.URI = url): Developer = { new Developer(id, name, email, url) } def withId(id: String): Developer = { @@ -34,11 +34,11 @@ final class Developer private ( def withEmail(email: String): Developer = { copy(email = email) } - def withUrl(url: java.net.URL): Developer = { + def withUrl(url: java.net.URI): Developer = { copy(url = url) } } object Developer { - def apply(id: String, name: String, email: String, url: java.net.URL): Developer = new Developer(id, name, email, url) + def apply(id: String, name: String, email: String, url: java.net.URI): Developer = new Developer(id, name, email, url) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala index 381013ab0..3a7cdbf60 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/DeveloperFormats.scala @@ -14,7 +14,7 @@ implicit lazy val DeveloperFormat: JsonFormat[sbt.librarymanagement.Developer] = val id = unbuilder.readField[String]("id") val name = unbuilder.readField[String]("name") val email = unbuilder.readField[String]("email") - val url = unbuilder.readField[java.net.URL]("url") + val url = unbuilder.readField[java.net.URI]("url") unbuilder.endObject() sbt.librarymanagement.Developer(id, name, email, url) case None => diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala index 383a144eb..46f2d6f7f 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfo.scala @@ -8,11 +8,11 @@ package sbt.librarymanagement final class ModuleInfo private ( val nameFormal: String, val description: String, - val homepage: Option[java.net.URL], + val homepage: Option[java.net.URI], val startYear: Option[Int], - val licenses: Vector[scala.Tuple2[String, java.net.URL]], + val licenses: Vector[scala.Tuple2[String, java.net.URI]], val organizationName: String, - val organizationHomepage: Option[java.net.URL], + val organizationHomepage: Option[java.net.URI], val scmInfo: Option[sbt.librarymanagement.ScmInfo], val developers: Vector[sbt.librarymanagement.Developer]) extends Serializable { @@ -28,7 +28,7 @@ final class ModuleInfo private ( override def toString: String = { "ModuleInfo(" + nameFormal + ", " + description + ", " + homepage + ", " + startYear + ", " + licenses + ", " + organizationName + ", " + organizationHomepage + ", " + scmInfo + ", " + developers + ")" } - private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URL] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URL]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URL] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { + private[this] def copy(nameFormal: String = nameFormal, description: String = description, homepage: Option[java.net.URI] = homepage, startYear: Option[Int] = startYear, licenses: Vector[scala.Tuple2[String, java.net.URI]] = licenses, organizationName: String = organizationName, organizationHomepage: Option[java.net.URI] = organizationHomepage, scmInfo: Option[sbt.librarymanagement.ScmInfo] = scmInfo, developers: Vector[sbt.librarymanagement.Developer] = developers): ModuleInfo = { new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } def withNameFormal(nameFormal: String): ModuleInfo = { @@ -37,19 +37,19 @@ final class ModuleInfo private ( def withDescription(description: String): ModuleInfo = { copy(description = description) } - def withHomepage(homepage: Option[java.net.URL]): ModuleInfo = { + def withHomepage(homepage: Option[java.net.URI]): ModuleInfo = { copy(homepage = homepage) } def withStartYear(startYear: Option[Int]): ModuleInfo = { copy(startYear = startYear) } - def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URL]]): ModuleInfo = { + def withLicenses(licenses: Vector[scala.Tuple2[String, java.net.URI]]): ModuleInfo = { copy(licenses = licenses) } def withOrganizationName(organizationName: String): ModuleInfo = { copy(organizationName = organizationName) } - def withOrganizationHomepage(organizationHomepage: Option[java.net.URL]): ModuleInfo = { + def withOrganizationHomepage(organizationHomepage: Option[java.net.URI]): ModuleInfo = { copy(organizationHomepage = organizationHomepage) } def withScmInfo(scmInfo: Option[sbt.librarymanagement.ScmInfo]): ModuleInfo = { @@ -62,5 +62,5 @@ final class ModuleInfo private ( object ModuleInfo { def apply(nameFormal: String): ModuleInfo = new ModuleInfo(nameFormal) - def apply(nameFormal: String, description: String, homepage: Option[java.net.URL], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URL]], organizationName: String, organizationHomepage: Option[java.net.URL], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) + def apply(nameFormal: String, description: String, homepage: Option[java.net.URI], startYear: Option[Int], licenses: Vector[scala.Tuple2[String, java.net.URI]], organizationName: String, organizationHomepage: Option[java.net.URI], scmInfo: Option[sbt.librarymanagement.ScmInfo], developers: Vector[sbt.librarymanagement.Developer]): ModuleInfo = new ModuleInfo(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, developers) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala index 4707e0bd1..aa586ebca 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ModuleInfoFormats.scala @@ -13,11 +13,11 @@ implicit lazy val ModuleInfoFormat: JsonFormat[sbt.librarymanagement.ModuleInfo] unbuilder.beginObject(__js) val nameFormal = unbuilder.readField[String]("nameFormal") val description = unbuilder.readField[String]("description") - val homepage = unbuilder.readField[Option[java.net.URL]]("homepage") + val homepage = unbuilder.readField[Option[java.net.URI]]("homepage") val startYear = unbuilder.readField[Option[Int]]("startYear") - val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URL]]]("licenses") + val licenses = unbuilder.readField[Vector[scala.Tuple2[String, java.net.URI]]]("licenses") val organizationName = unbuilder.readField[String]("organizationName") - val organizationHomepage = unbuilder.readField[Option[java.net.URL]]("organizationHomepage") + val organizationHomepage = unbuilder.readField[Option[java.net.URI]]("organizationHomepage") val scmInfo = unbuilder.readField[Option[sbt.librarymanagement.ScmInfo]]("scmInfo") val developers = unbuilder.readField[Vector[sbt.librarymanagement.Developer]]("developers") unbuilder.endObject() diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala index 4fadcae1f..f91a5bbf1 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfo.scala @@ -6,11 +6,11 @@ package sbt.librarymanagement /** Basic SCM information for a project module */ final class ScmInfo private ( - val browseUrl: java.net.URL, + val browseUrl: java.net.URI, val connection: String, val devConnection: Option[String]) extends Serializable { - private def this(browseUrl: java.net.URL, connection: String) = this(browseUrl, connection, None) + private def this(browseUrl: java.net.URI, connection: String) = this(browseUrl, connection, None) override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { case x: ScmInfo => (this.browseUrl == x.browseUrl) && (this.connection == x.connection) && (this.devConnection == x.devConnection) @@ -22,10 +22,10 @@ final class ScmInfo private ( override def toString: String = { "ScmInfo(" + browseUrl + ", " + connection + ", " + devConnection + ")" } - private[this] def copy(browseUrl: java.net.URL = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { + private[this] def copy(browseUrl: java.net.URI = browseUrl, connection: String = connection, devConnection: Option[String] = devConnection): ScmInfo = { new ScmInfo(browseUrl, connection, devConnection) } - def withBrowseUrl(browseUrl: java.net.URL): ScmInfo = { + def withBrowseUrl(browseUrl: java.net.URI): ScmInfo = { copy(browseUrl = browseUrl) } def withConnection(connection: String): ScmInfo = { @@ -40,7 +40,7 @@ final class ScmInfo private ( } object ScmInfo { - def apply(browseUrl: java.net.URL, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) - def apply(browseUrl: java.net.URL, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) - def apply(browseUrl: java.net.URL, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) + def apply(browseUrl: java.net.URI, connection: String): ScmInfo = new ScmInfo(browseUrl, connection) + def apply(browseUrl: java.net.URI, connection: String, devConnection: Option[String]): ScmInfo = new ScmInfo(browseUrl, connection, devConnection) + def apply(browseUrl: java.net.URI, connection: String, devConnection: String): ScmInfo = new ScmInfo(browseUrl, connection, Option(devConnection)) } diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala index bacca95d8..70e7f40f0 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/ScmInfoFormats.scala @@ -11,7 +11,7 @@ implicit lazy val ScmInfoFormat: JsonFormat[sbt.librarymanagement.ScmInfo] = new __jsOpt match { case Some(__js) => unbuilder.beginObject(__js) - val browseUrl = unbuilder.readField[java.net.URL]("browseUrl") + val browseUrl = unbuilder.readField[java.net.URI]("browseUrl") val connection = unbuilder.readField[String]("connection") val devConnection = unbuilder.readField[Option[String]]("devConnection") unbuilder.endObject() diff --git a/core/src/main/contraband/librarymanagement.json b/core/src/main/contraband/librarymanagement.json index 89d20007d..37ede5b91 100644 --- a/core/src/main/contraband/librarymanagement.json +++ b/core/src/main/contraband/librarymanagement.json @@ -141,7 +141,7 @@ { "name": "extension", "type": "String", "default": "Artifact.DefaultExtension", "since": "0.0.1" }, { "name": "classifier", "type": "Option[String]", "default": "None", "since": "0.0.1" }, { "name": "configurations", "type": "sbt.librarymanagement.ConfigRef*", "default": "Vector.empty", "since": "0.0.1" }, - { "name": "url", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "url", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "extraAttributes", "type": "Map[String, String]", "default": "Map.empty", "since": "0.0.1" }, { "name": "checksum", "type": "Option[sbt.librarymanagement.Checksum]", "default": "None", "since": "0.0.1" }, { "name": "allowInsecureProtocol", "type": "Boolean", "default": "false", "since": "1.3.0" } @@ -244,7 +244,7 @@ { "name": "id", "type": "String" }, { "name": "name", "type": "String" }, { "name": "email", "type": "String" }, - { "name": "url", "type": "java.net.URL" } + { "name": "url", "type": "java.net.URI" } ] }, { @@ -365,11 +365,11 @@ "fields": [ { "name": "nameFormal", "type": "String" }, { "name": "description", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "homepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "homepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "startYear", "type": "Option[Int]", "default": "None", "since": "0.0.1" }, - { "name": "licenses", "type": "scala.Tuple2[String, java.net.URL]*", "default": "Vector.empty", "since": "0.0.1" }, + { "name": "licenses", "type": "scala.Tuple2[String, java.net.URI]*", "default": "Vector.empty", "since": "0.0.1" }, { "name": "organizationName", "type": "String", "default": "\"\"", "since": "0.0.1" }, - { "name": "organizationHomepage", "type": "Option[java.net.URL]", "default": "None", "since": "0.0.1" }, + { "name": "organizationHomepage", "type": "Option[java.net.URI]", "default": "None", "since": "0.0.1" }, { "name": "scmInfo", "type": "Option[sbt.librarymanagement.ScmInfo]", "default": "None", "since": "0.0.1" }, { "name": "developers", "type": "sbt.librarymanagement.Developer*", "default": "Vector.empty", "since": "0.0.1" } ] @@ -728,7 +728,7 @@ "type": "record", "doc": "Basic SCM information for a project module", "fields": [ - { "name": "browseUrl", "type": "java.net.URL" }, + { "name": "browseUrl", "type": "java.net.URI" }, { "name": "connection", "type": "String" }, { "name": "devConnection", "type": "String?", "default": "None", "since": "0.0.1" } ] diff --git a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala index 63a992d2d..411f486aa 100644 --- a/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ArtifactExtra.scala @@ -4,7 +4,7 @@ package sbt.librarymanagement import java.io.File -import java.net.URL +import java.net.URI private[librarymanagement] abstract class ArtifactExtra { def extraAttributes: Map[String, String] @@ -26,15 +26,15 @@ private[librarymanagement] abstract class ArtifactFunctions { Artifact(name, `type`, extension, None, Vector.empty, None) def apply(name: String, `type`: String, extension: String, classifier: String): Artifact = Artifact(name, `type`, extension, Some(classifier), Vector.empty, None) - def apply(name: String, url: URL): Artifact = Artifact(name, url, false) - def apply(name: String, url: URL, allowInsecureProtocol: Boolean): Artifact = + def apply(name: String, uri: URI): Artifact = Artifact(name, uri, false) + def apply(name: String, uri: URI, allowInsecureProtocol: Boolean): Artifact = Artifact( name, - extract(url, DefaultType), - extract(url, DefaultExtension), + extract(uri, DefaultType), + extract(uri, DefaultExtension), None, Vector.empty, - Some(url), + Some(uri), Map.empty, None, allowInsecureProtocol @@ -47,8 +47,9 @@ private[librarymanagement] abstract class ArtifactFunctions { extension: String, classifier: Option[String], configurations: Vector[ConfigRef], - url: Option[URL] - ): Artifact = Artifact(name, `type`, extension, classifier, configurations, url, empty, None) + uri: Option[URI] + ): Artifact = + Artifact(name, `type`, extension, classifier, configurations, uri, empty, None) val DefaultExtension = "jar" val DefaultType = "jar" @@ -78,7 +79,7 @@ private[librarymanagement] abstract class ArtifactFunctions { assert(DefaultDocTypes contains DocType) assert(DefaultSourceTypes contains SourceType) - def extract(url: URL, default: String): String = extract(url.toString, default) + def extract(uri: URI, default: String): String = extract(uri.toString, default) def extract(name: String, default: String): String = { val i = name.lastIndexOf('.') if (i >= 0) @@ -96,7 +97,7 @@ private[librarymanagement] abstract class ArtifactFunctions { extract(name, DefaultExtension), None, Vector.empty, - Some(file.toURI.toURL) + Some(file.toURI) ) } def artifactName(scalaVersion: ScalaVersion, module: ModuleID, artifact: Artifact): String = { diff --git a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala index 0778ad831..f8eb4fe6c 100644 --- a/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala +++ b/core/src/main/scala/sbt/librarymanagement/ModuleIDExtra.scala @@ -133,7 +133,7 @@ private[librarymanagement] abstract class ModuleIDExtra { * It is not included in published metadata. */ def from(url: String, allowInsecureProtocol: Boolean): ModuleID = - artifacts(Artifact(name, new URI(url).toURL, allowInsecureProtocol)) + artifacts(Artifact(name, new URI(url), allowInsecureProtocol)) /** Adds a dependency on the artifact for this module with classifier `c`. */ def classifier(c: String): ModuleID = artifacts(Artifact(name, c)) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala index 710c120de..7f84c3bf8 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ComponentManager.scala @@ -101,7 +101,7 @@ object IfMissing { object ComponentManager { lazy val (version, timestamp) = { val properties = new java.util.Properties - val propertiesStream = versionResource.openStream + val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") try { properties.load(propertiesStream) } finally { @@ -110,7 +110,4 @@ object ComponentManager { (properties.getProperty("version"), properties.getProperty("timestamp")) } lazy val stampedVersion = version + "_" + timestamp - - import java.net.URL - private def versionResource: URL = getClass.getResource("/xsbt.version.properties") } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index adc202711..43c168d4c 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -394,17 +394,17 @@ private[sbt] object ConvertResolver { private[this] val repo = new WarnOnOverwriteFileRepo() private[this] val progress = new RepositoryCopyProgressListener(this); override def getResource(source: String) = { - val url = new URI(source).toURL - if (url.getProtocol == IO.FileScheme) - new FileResource(repo, IO.toFile(url)) + val uri = new URI(source) + if (uri.getScheme == IO.FileScheme) + new FileResource(repo, IO.toFile(uri)) else super.getResource(source) } override def put(source: File, destination: String, overwrite: Boolean): Unit = { - val url = new URI(destination).toURL + val uri = new URI(destination) try { - if (url.getProtocol != IO.FileScheme) super.put(source, destination, overwrite) + if (uri.getScheme != IO.FileScheme) super.put(source, destination, overwrite) else { // Here we duplicate the put method for files so we don't just bail on trying ot use Http handler val resource = getResource(destination) @@ -417,7 +417,7 @@ private[sbt] object ConvertResolver { if (totalLength > 0) { progress.setTotalLength(totalLength); } - FileUtil.copy(source, new java.io.File(url.toURI), progress, overwrite) + FileUtil.copy(source, new java.io.File(uri), progress, overwrite) () } catch { case ex: IOException => diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala index 2d6ef89de..00c0275ae 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/FakeResolver.scala @@ -69,7 +69,7 @@ private[sbt] class FakeResolver(private var name: String, cacheDir: File, module ): ArtifactDownloadReport = { val report = new ArtifactDownloadReport(artifact.getArtifact) - val path = new URI(artifact.getLocation).toURL.toURI.getPath + val path = new URI(artifact.getLocation).getPath val localFile = new File(path) if (path.nonEmpty && localFile.exists) { diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index 48d360c5c..b040888a0 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -1000,7 +1000,7 @@ private[sbt] object IvySbt { name, `type`, extension, - url.orNull, + url.map(_.toURL).orNull, extraMap ) copyConfigurations(artifact, (ref: ConfigRef) => { ivyArtifact.addConfiguration(ref.name) }) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index a1784ffd0..0560036d3 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -229,7 +229,7 @@ object IvyRetrieve { getConfigurations.toVector map { (c: String) => ConfigRef(c) }, - Option(getUrl) + Option(getUrl).map(_.toURI) ) } diff --git a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala index bc035efa1..b380800fc 100644 --- a/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala +++ b/ivy/src/test/scala/sbt/internal/librarymanagement/DMSerializationSpec.scala @@ -43,7 +43,7 @@ object DMSerializationSpec extends BasicTestSuite { } test("""Artifact("foo", url("http://example.com/")) should roundtrip""") { - roundtrip(Artifact("foo", new URI("http://example.com/").toURL)) + roundtrip(Artifact("foo", new URI("http://example.com/"))) } test("""Artifact("foo").extra(("key", "value")) should roundtrip""") { From e8b0cd08e69bb3bace34c09a097d778f7aebff3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 23:31:14 +0100 Subject: [PATCH 1026/1030] fix array conversions warnings method copyArrayToImmutableIndexedSeq in class LowPriorityImplicits2 is deprecated since 2.13.0: implicit conversions from Array to immutable.IndexedSeq are implemented by copying; use `toIndexedSeq` explicitly if you want to copy, or use the more efficient non-copying ArraySeq.unsafeWrapArray --- .../sbt/librarymanagement/SemanticSelector.scala | 2 +- core/src/main/contraband/librarymanagement2.json | 2 +- .../librarymanagement/SemanticSelectorExtra.scala | 3 ++- .../librarymanagement/CustomPomParser.scala | 3 ++- .../sbt/internal/librarymanagement/Ivy.scala | 3 ++- .../internal/librarymanagement/IvyActions.scala | 3 ++- .../internal/librarymanagement/IvyRetrieve.scala | 7 +++++-- .../sbt/internal/librarymanagement/MakePom.scala | 15 ++++++++++----- .../ivyint/CachedResolutionResolveEngine.scala | 10 +++++----- .../ivyint/MergeDescriptors.scala | 5 +++-- .../mavenint/PomExtraDependencyAttributes.scala | 4 +++- 11 files changed, 36 insertions(+), 21 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala index ca5386b34..6ebc65a99 100644 --- a/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala +++ b/core/src/main/contraband-scala/sbt/librarymanagement/SemanticSelector.scala @@ -84,7 +84,7 @@ object SemanticSelector { def apply(selector: String): SemanticSelector = { val orChunkTokens = selector.split("\\s+\\|\\|\\s+").map(_.trim) val orChunks = orChunkTokens.map { chunk => sbt.internal.librarymanagement.SemSelAndChunk(chunk) } - SemanticSelector(orChunks) + SemanticSelector(scala.collection.immutable.ArraySeq.unsafeWrapArray(orChunks)) } def apply(selectors: Seq[sbt.internal.librarymanagement.SemSelAndChunk]): SemanticSelector = new SemanticSelector(selectors) } diff --git a/core/src/main/contraband/librarymanagement2.json b/core/src/main/contraband/librarymanagement2.json index 1e85d3b52..ffdee8da4 100644 --- a/core/src/main/contraband/librarymanagement2.json +++ b/core/src/main/contraband/librarymanagement2.json @@ -87,7 +87,7 @@ "def apply(selector: String): SemanticSelector = {", " val orChunkTokens = selector.split(\"\\\\s+\\\\|\\\\|\\\\s+\").map(_.trim)", " val orChunks = orChunkTokens.map { chunk => sbt.internal.librarymanagement.SemSelAndChunk(chunk) }", - " SemanticSelector(orChunks)", + " SemanticSelector(scala.collection.immutable.ArraySeq.unsafeWrapArray(orChunks))", "}" ] }, diff --git a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala index d9a7fb24f..2020e71fd 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/SemanticSelectorExtra.scala @@ -8,7 +8,8 @@ import java.util.Locale private[librarymanagement] abstract class SemSelAndChunkFunctions { protected def parse(andClauseToken: String): SemSelAndChunk = { - val comparatorTokens = andClauseToken.split("\\s+") + val comparatorTokens = + scala.collection.immutable.ArraySeq.unsafeWrapArray(andClauseToken.split("\\s+")) val hyphenIndex = comparatorTokens.indexWhere(_ == "-") val comparators = if (hyphenIndex == -1) { comparatorTokens.map(SemComparator.apply) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala index e7ded5b3a..8f7170d75 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/CustomPomParser.scala @@ -29,6 +29,7 @@ import sbt.internal.librarymanagement.mavenint.{ SbtPomExtraProperties } import sbt.io.Hash +import scala.collection.immutable.ArraySeq // @deprecated("We now use an Aether-based pom parser.", "0.13.8") final class CustomPomParser( @@ -311,7 +312,7 @@ object CustomPomParser { ) dmd.addExtraAttributeNamespace(key, value) IvySbt.addExtraNamespace(dmd) - val withExtra = md.getDependencies map { dd => + val withExtra = ArraySeq.unsafeWrapArray(md.getDependencies) map { dd => addExtra(dd, dependencyExtra) } val withVersionRangeMod: Seq[DependencyDescriptor] = diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala index b040888a0..074e7c380 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/Ivy.scala @@ -36,6 +36,7 @@ import org.apache.ivy.util.extendable.ExtendableItem import org.apache.ivy.util.url._ import scala.xml.NodeSeq import scala.collection.mutable +import scala.collection.immutable.ArraySeq import scala.util.{ Success, Failure } import sbt.util._ import sbt.librarymanagement.{ ModuleDescriptorConfiguration => InlineConfiguration, _ } @@ -891,7 +892,7 @@ private[sbt] object IvySbt { def inconsistentDuplicateWarning(moduleID: DefaultModuleDescriptor): List[String] = { import IvyRetrieve.toModuleID - val dds = moduleID.getDependencies + val dds = ArraySeq.unsafeWrapArray(moduleID.getDependencies) val deps = dds flatMap { dd => val module = toModuleID(dd.getDependencyRevisionId) dd.getModuleConfigurations map (c => module.withConfigurations(Some(c))) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala index 62099d06e..a7a550bb6 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyActions.scala @@ -320,8 +320,9 @@ object IvyActions { val resolveReport = ivyInstance.resolve(moduleDescriptor, resolveOptions) if (resolveReport.hasError && !missingOk) { + import scala.jdk.CollectionConverters._ // If strict error, collect report information and generated UnresolvedWarning - val messages = resolveReport.getAllProblemMessages.toArray.map(_.toString).distinct + val messages = resolveReport.getAllProblemMessages.asScala.toSeq.map(_.toString).distinct val failedPaths = resolveReport.getUnresolvedDependencies.map { node => val moduleID = IvyRetrieve.toModuleID(node.getId) val path = IvyRetrieve diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala index 0560036d3..836b3ede7 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/IvyRetrieve.scala @@ -6,6 +6,7 @@ package sbt.internal.librarymanagement import java.io.File import java.{ util => ju } import collection.mutable +import collection.immutable.ArraySeq import org.apache.ivy.core.{ module, report, resolve } import module.descriptor.{ Artifact => IvyArtifact, License => IvyLicense } import module.id.{ ModuleRevisionId, ModuleId => IvyModuleId } @@ -187,7 +188,9 @@ object IvyRetrieve { case _ => Vector.empty } val callers = dep.getCallers(confReport.getConfiguration).toVector map { toCaller } - val (resolved, missing) = artifacts(confReport getDownloadReports revId) + val (resolved, missing) = artifacts( + ArraySeq.unsafeWrapArray(confReport.getDownloadReports(revId)) + ) ModuleReport( moduleId, @@ -212,7 +215,7 @@ object IvyRetrieve { } def evicted(confReport: ConfigurationResolveReport): Seq[ModuleID] = - confReport.getEvictedNodes.map(node => toModuleID(node.getId)) + ArraySeq.unsafeWrapArray(confReport.getEvictedNodes).map(node => toModuleID(node.getId)) def toModuleID(revID: ModuleRevisionId): ModuleID = ModuleID(revID.getOrganisation, revID.getName, revID.getRevision) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala index 8e90b4eb1..58d05628e 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/MakePom.scala @@ -13,6 +13,7 @@ import sbt.librarymanagement._ import Resolver._ import mavenint.PomExtraDependencyAttributes +import scala.collection.immutable.ArraySeq // Node needs to be renamed to XNode because the task subproject contains a Node type that will shadow // scala.xml.Node when generating aggregated API documentation import scala.xml.{ Elem, Node => XNode, NodeSeq, PrettyPrinter, PrefixedAttribute } @@ -147,7 +148,7 @@ class MakePom(val log: Logger) { { val deps = depsInConfs(module, configurations) makeProperties(module, deps) ++ - makeDependencies(deps, includeTypes, module.getAllExcludeRules) + makeDependencies(deps, includeTypes, ArraySeq.unsafeWrapArray(module.getAllExcludeRules)) } {makeRepositories(ivy.getSettings, allRepositories, filterRepositories)} ) @@ -442,7 +443,9 @@ class MakePom(val log: Logger) { def exclusions(dependency: DependencyDescriptor): NodeSeq = exclusions(dependency, Nil) def exclusions(dependency: DependencyDescriptor, excludes: Seq[ExcludeRule]): NodeSeq = { - val excl = dependency.getExcludeRules(dependency.getModuleConfigurations) ++ excludes + val excl = ArraySeq.unsafeWrapArray( + dependency.getExcludeRules(dependency.getModuleConfigurations) + ) ++ excludes val (warns, excls) = IvyUtil.separate(excl.map(makeExclusion)) if (warns.nonEmpty) log.warn(warns.mkString(IO.Newline)) if (excls.nonEmpty) { @@ -500,8 +503,10 @@ class MakePom(val log: Logger) { r match { case c: ChainResolver => flatten(castResolvers(c.getResolvers)); case _ => r :: Nil } // cast the contents of a pre-generics collection - private def castResolvers(s: java.util.Collection[_]): Seq[DependencyResolver] = - s.toArray.map(_.asInstanceOf[DependencyResolver]) + private def castResolvers(s: java.util.Collection[_]): Seq[DependencyResolver] = { + import scala.jdk.CollectionConverters._ + s.asScala.toSeq.map(_.asInstanceOf[DependencyResolver]) + } def toID(name: String) = checkID(name.filter(isValidIDCharacter).mkString, name) def isValidIDCharacter(c: Char) = !"""\/:"<>|?*""".contains(c) @@ -535,6 +540,6 @@ class MakePom(val log: Logger) { else // TODO: translate the dependency to contain only configurations to keep Some(dependency) } - module.getDependencies flatMap translate + ArraySeq.unsafeWrapArray(module.getDependencies) flatMap translate } } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index 9eea99693..a7db35077 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -159,9 +159,8 @@ private[sbt] class CachedResolutionResolveCache { } def extractOverrides(md0: ModuleDescriptor): Vector[IvyOverride] = { import scala.jdk.CollectionConverters._ - md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toSeq.toVector sortBy { - case (k, _) => - k.toString + md0.getAllDependencyDescriptorMediators.getAllRules.asScala.toVector sortBy { case (k, _) => + k.toString } collect { case (k: MapMatcher, v: OverrideDependencyDescriptorMediator) => val attr: Map[Any, Any] = k.getAttributes.asScala.toMap val module = IvyModuleId.newInstance( @@ -398,13 +397,14 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { doWorkUsingIvy(md) } def doWorkUsingIvy(md: ModuleDescriptor): Either[ResolveException, UpdateReport] = { + import scala.jdk.CollectionConverters._ val options1 = new ResolveOptions(options0) val rr = withIvy(log) { ivy => ivy.resolve(md, options1) } if (!rr.hasError || missingOk) Right(IvyRetrieve.updateReport(rr, cachedDescriptor)) else { - val messages = rr.getAllProblemMessages.toArray.map(_.toString).distinct + val messages = rr.getAllProblemMessages.asScala.toSeq.map(_.toString).distinct val failedPaths = ListMap(rr.getUnresolvedDependencies map { node => val m = IvyRetrieve.toModuleID(node.getId) val path = IvyRetrieve.findPath(node, md.getModuleRevisionId) map { x => @@ -781,7 +781,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { } val merged = (modules groupBy { m => (m.module.organization, m.module.name, m.module.revision) - }).toSeq.toVector flatMap { case (_, xs) => + }).toVector flatMap { case (_, xs) => if (xs.size < 2) xs else Vector(mergeModuleReports(xs)) } diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala index 765360d90..a86ed3689 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/MergeDescriptors.scala @@ -1,6 +1,7 @@ package sbt.internal.librarymanagement package ivyint +import scala.collection.immutable.ArraySeq import org.apache.ivy.core import core.module.descriptor.{ DependencyArtifactDescriptor, DefaultDependencyArtifactDescriptor } import core.module.descriptor.DependencyDescriptor @@ -117,7 +118,7 @@ private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: Depe // See gh-1500, gh-2002 aConfs match { case None | Some(Nil) | Some(List("*")) => - copyWithConfigurations(art, base.getModuleConfigurations) + copyWithConfigurations(art, ArraySeq.unsafeWrapArray(base.getModuleConfigurations)) case _ => art } } @@ -132,7 +133,7 @@ private[sbt] final case class MergedDescriptors(a: DependencyDescriptor, b: Depe null, null ) - addConfigurations(dd, a.getModuleConfigurations) + addConfigurations(dd, ArraySeq.unsafeWrapArray(a.getModuleConfigurations)) // If the dependency descriptor is empty, then it means that it has been created from a POM file. In this case, // it is correct to create a seemingly non-existent dependency artifact. if (a.getAllDependencyArtifacts.isEmpty) Array(dd) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala index 7e2d79c33..ef070a02f 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/mavenint/PomExtraDependencyAttributes.scala @@ -1,6 +1,7 @@ package sbt.internal.librarymanagement package mavenint +import scala.collection.immutable.ArraySeq import java.util.Properties import java.util.regex.Pattern @@ -100,8 +101,9 @@ object PomExtraDependencyAttributes { } /** parses the sequence of dependencies with extra attribute information, with one dependency per line */ - def readDependencyExtra(s: String): Seq[ModuleRevisionId] = + def readDependencyExtra(s: String): Seq[ModuleRevisionId] = ArraySeq.unsafeWrapArray( LinesP.split(s).map(_.trim).filter(!_.isEmpty).map(ModuleRevisionId.decode) + ) private[this] val LinesP = Pattern.compile("(?m)^") From baa3845c7154b761ad7d0d61ca5f542f4fb26c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 23:31:51 +0100 Subject: [PATCH 1027/1030] fix Infinite loop in function body warning --- .../internal/librarymanagement/formats/GlobalLockFormat.scala | 2 +- .../sbt/internal/librarymanagement/formats/LoggerFormat.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala index fffd9b6a8..2e4ced132 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/GlobalLockFormat.scala @@ -15,7 +15,7 @@ trait GlobalLockFormat { self: BasicJsonProtocol => implicit lazy val globalLockIsoString: IsoString[GlobalLock] = IsoString.iso(_ => "", _ => NoGlobalLock) - implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = implicitly + implicit lazy val GlobalLockFormat: JsonFormat[GlobalLock] = isoStringFormat(globalLockIsoString) } private[sbt] object GlobalLockFormats { diff --git a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala index 954b48127..f10fdb03f 100644 --- a/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala +++ b/core/src/main/scala/sbt/internal/librarymanagement/formats/LoggerFormat.scala @@ -12,5 +12,5 @@ trait LoggerFormat { self: BasicJsonProtocol => implicit lazy val xsbtiLoggerIsoString: IsoString[Logger] = IsoString.iso(_ => "", _ => Null) - implicit lazy val LoggerFormat: JsonFormat[Logger] = implicitly + implicit lazy val LoggerFormat: JsonFormat[Logger] = isoStringFormat(implicitly) } From 885cca3204a2bce4f0a56610b71375fa8950c9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 23:38:35 +0100 Subject: [PATCH 1028/1030] fix indentation warnings --- .../librarymanagement/SemComparator.scala | 68 +++++++++--------- .../ivy/ExternalIvyConfigurationFormats.scala | 54 +++++++------- .../ivy/InlineIvyConfigurationFormats.scala | 70 +++++++++---------- .../ivy/IvyConfigurationFormats.scala | 2 +- 4 files changed, 97 insertions(+), 97 deletions(-) diff --git a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala index 2baccd6b9..25765e8f8 100644 --- a/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala +++ b/core/src/main/contraband-scala/sbt/internal/librarymanagement/SemComparator.scala @@ -13,42 +13,42 @@ final class SemComparator private ( def matches(version: sbt.librarymanagement.VersionNumber): Boolean = this.matchesImpl(version) def expandWildcard: Seq[SemComparator] = { if (op == sbt.internal.librarymanagement.SemSelOperator.Eq && !allFieldsSpecified) { - Seq( - this.withOp(sbt.internal.librarymanagement.SemSelOperator.Gte), - this.withOp(sbt.internal.librarymanagement.SemSelOperator.Lte) - ) - } else { Seq(this) } -} + Seq( + this.withOp(sbt.internal.librarymanagement.SemSelOperator.Gte), + this.withOp(sbt.internal.librarymanagement.SemSelOperator.Lte) + ) + } else { Seq(this) } + } -override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { - case x: SemComparator => (this.op == x.op) && (this.major == x.major) && (this.minor == x.minor) && (this.patch == x.patch) && (this.tags == x.tags) - case _ => false -}) -override def hashCode: Int = { - 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.SemComparator".##) + op.##) + major.##) + minor.##) + patch.##) + tags.##) -} -override def toString: String = { - this.toStringImpl -} -private[this] def copy(op: sbt.internal.librarymanagement.SemSelOperator = op, major: Option[Long] = major, minor: Option[Long] = minor, patch: Option[Long] = patch, tags: Seq[String] = tags): SemComparator = { - new SemComparator(op, major, minor, patch, tags) -} -def withOp(op: sbt.internal.librarymanagement.SemSelOperator): SemComparator = { - copy(op = op) -} -def withMajor(major: Option[Long]): SemComparator = { - copy(major = major) -} -def withMinor(minor: Option[Long]): SemComparator = { - copy(minor = minor) -} -def withPatch(patch: Option[Long]): SemComparator = { - copy(patch = patch) -} -def withTags(tags: Seq[String]): SemComparator = { - copy(tags = tags) -} + override def equals(o: Any): Boolean = this.eq(o.asInstanceOf[AnyRef]) || (o match { + case x: SemComparator => (this.op == x.op) && (this.major == x.major) && (this.minor == x.minor) && (this.patch == x.patch) && (this.tags == x.tags) + case _ => false + }) + override def hashCode: Int = { + 37 * (37 * (37 * (37 * (37 * (37 * (17 + "sbt.internal.librarymanagement.SemComparator".##) + op.##) + major.##) + minor.##) + patch.##) + tags.##) + } + override def toString: String = { + this.toStringImpl + } + private[this] def copy(op: sbt.internal.librarymanagement.SemSelOperator = op, major: Option[Long] = major, minor: Option[Long] = minor, patch: Option[Long] = patch, tags: Seq[String] = tags): SemComparator = { + new SemComparator(op, major, minor, patch, tags) + } + def withOp(op: sbt.internal.librarymanagement.SemSelOperator): SemComparator = { + copy(op = op) + } + def withMajor(major: Option[Long]): SemComparator = { + copy(major = major) + } + def withMinor(minor: Option[Long]): SemComparator = { + copy(minor = minor) + } + def withPatch(patch: Option[Long]): SemComparator = { + copy(patch = patch) + } + def withTags(tags: Seq[String]): SemComparator = { + copy(tags = tags) + } } object SemComparator extends sbt.internal.librarymanagement.SemComparatorFunctions { def apply(comparator: String): SemComparator = parse(comparator) diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala index 49c66fc7b..553943e65 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/ExternalIvyConfigurationFormats.scala @@ -36,32 +36,32 @@ trait ExternalIvyConfigurationFormats { self: sbt.internal.librarymanagement.for with sbt.librarymanagement.SftpRepositoryFormats with sbt.librarymanagement.PasswordAuthenticationFormats with sbt.librarymanagement.KeyFileAuthenticationFormats => -implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] { - override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { - __jsOpt match { - case Some(__js) => - unbuilder.beginObject(__js) - val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") - val log = unbuilder.readField[Option[xsbti.Logger]]("log") - val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") - val baseDirectory = unbuilder.readField[Option[java.io.File]]("baseDirectory") - val uri = unbuilder.readField[Option[java.net.URI]]("uri") - val extraResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("extraResolvers") - unbuilder.endObject() - sbt.librarymanagement.ivy.ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) - case None => - deserializationError("Expected JsObject but found None") + implicit lazy val ExternalIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.ExternalIvyConfiguration] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.ExternalIvyConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") + val log = unbuilder.readField[Option[xsbti.Logger]]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") + val baseDirectory = unbuilder.readField[Option[java.io.File]]("baseDirectory") + val uri = unbuilder.readField[Option[java.net.URI]]("uri") + val extraResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("extraResolvers") + unbuilder.endObject() + sbt.librarymanagement.ivy.ExternalIvyConfiguration(lock, log, updateOptions, baseDirectory, uri, extraResolvers) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ivy.ExternalIvyConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("lock", obj.lock) + builder.addField("log", obj.log) + builder.addField("updateOptions", obj.updateOptions) + builder.addField("baseDirectory", obj.baseDirectory) + builder.addField("uri", obj.uri) + builder.addField("extraResolvers", obj.extraResolvers) + builder.endObject() + } } - } - override def write[J](obj: sbt.librarymanagement.ivy.ExternalIvyConfiguration, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("lock", obj.lock) - builder.addField("log", obj.log) - builder.addField("updateOptions", obj.updateOptions) - builder.addField("baseDirectory", obj.baseDirectory) - builder.addField("uri", obj.uri) - builder.addField("extraResolvers", obj.extraResolvers) - builder.endObject() - } -} } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala index 28fbd616f..22f92e099 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/InlineIvyConfigurationFormats.scala @@ -38,40 +38,40 @@ trait InlineIvyConfigurationFormats { self: sbt.internal.librarymanagement.forma with sbt.librarymanagement.SftpRepositoryFormats with sbt.librarymanagement.PasswordAuthenticationFormats with sbt.librarymanagement.KeyFileAuthenticationFormats => -implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { - override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { - __jsOpt match { - case Some(__js) => - unbuilder.beginObject(__js) - val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") - val log = unbuilder.readField[Option[xsbti.Logger]]("log") - val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") - val paths = unbuilder.readField[Option[sbt.librarymanagement.ivy.IvyPaths]]("paths") - val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") - val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") - val moduleConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ModuleConfiguration]]("moduleConfigurations") - val checksums = unbuilder.readField[Vector[String]]("checksums") - val managedChecksums = unbuilder.readField[Boolean]("managedChecksums") - val resolutionCacheDir = unbuilder.readField[Option[java.io.File]]("resolutionCacheDir") - unbuilder.endObject() - sbt.librarymanagement.ivy.InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) - case None => - deserializationError("Expected JsObject but found None") + implicit lazy val InlineIvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] = new JsonFormat[sbt.librarymanagement.ivy.InlineIvyConfiguration] { + override def read[J](__jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.librarymanagement.ivy.InlineIvyConfiguration = { + __jsOpt match { + case Some(__js) => + unbuilder.beginObject(__js) + val lock = unbuilder.readField[Option[xsbti.GlobalLock]]("lock") + val log = unbuilder.readField[Option[xsbti.Logger]]("log") + val updateOptions = unbuilder.readField[sbt.librarymanagement.ivy.UpdateOptions]("updateOptions") + val paths = unbuilder.readField[Option[sbt.librarymanagement.ivy.IvyPaths]]("paths") + val resolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("resolvers") + val otherResolvers = unbuilder.readField[Vector[sbt.librarymanagement.Resolver]]("otherResolvers") + val moduleConfigurations = unbuilder.readField[Vector[sbt.librarymanagement.ModuleConfiguration]]("moduleConfigurations") + val checksums = unbuilder.readField[Vector[String]]("checksums") + val managedChecksums = unbuilder.readField[Boolean]("managedChecksums") + val resolutionCacheDir = unbuilder.readField[Option[java.io.File]]("resolutionCacheDir") + unbuilder.endObject() + sbt.librarymanagement.ivy.InlineIvyConfiguration(lock, log, updateOptions, paths, resolvers, otherResolvers, moduleConfigurations, checksums, managedChecksums, resolutionCacheDir) + case None => + deserializationError("Expected JsObject but found None") + } + } + override def write[J](obj: sbt.librarymanagement.ivy.InlineIvyConfiguration, builder: Builder[J]): Unit = { + builder.beginObject() + builder.addField("lock", obj.lock) + builder.addField("log", obj.log) + builder.addField("updateOptions", obj.updateOptions) + builder.addField("paths", obj.paths) + builder.addField("resolvers", obj.resolvers) + builder.addField("otherResolvers", obj.otherResolvers) + builder.addField("moduleConfigurations", obj.moduleConfigurations) + builder.addField("checksums", obj.checksums) + builder.addField("managedChecksums", obj.managedChecksums) + builder.addField("resolutionCacheDir", obj.resolutionCacheDir) + builder.endObject() + } } - } - override def write[J](obj: sbt.librarymanagement.ivy.InlineIvyConfiguration, builder: Builder[J]): Unit = { - builder.beginObject() - builder.addField("lock", obj.lock) - builder.addField("log", obj.log) - builder.addField("updateOptions", obj.updateOptions) - builder.addField("paths", obj.paths) - builder.addField("resolvers", obj.resolvers) - builder.addField("otherResolvers", obj.otherResolvers) - builder.addField("moduleConfigurations", obj.moduleConfigurations) - builder.addField("checksums", obj.checksums) - builder.addField("managedChecksums", obj.managedChecksums) - builder.addField("resolutionCacheDir", obj.resolutionCacheDir) - builder.endObject() - } -} } diff --git a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala index cbab06322..324710d4f 100644 --- a/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala +++ b/ivy/src/main/contraband-scala/sbt/librarymanagement/ivy/IvyConfigurationFormats.scala @@ -41,5 +41,5 @@ trait IvyConfigurationFormats { self: sbt.internal.librarymanagement.formats.Glo with sbt.librarymanagement.SftpRepositoryFormats with sbt.librarymanagement.PasswordAuthenticationFormats with sbt.librarymanagement.KeyFileAuthenticationFormats => -implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.IvyConfiguration] = flatUnionFormat2[sbt.librarymanagement.ivy.IvyConfiguration, sbt.librarymanagement.ivy.InlineIvyConfiguration, sbt.librarymanagement.ivy.ExternalIvyConfiguration]("type") + implicit lazy val IvyConfigurationFormat: JsonFormat[sbt.librarymanagement.ivy.IvyConfiguration] = flatUnionFormat2[sbt.librarymanagement.ivy.IvyConfiguration, sbt.librarymanagement.ivy.InlineIvyConfiguration, sbt.librarymanagement.ivy.ExternalIvyConfiguration]("type") } From 46452a2e9e816d711b9711b249f43117a357ba53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 23:39:05 +0100 Subject: [PATCH 1029/1030] fix match warning --- .../ivyint/CachedResolutionResolveEngine.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala index a7db35077..ed0a8a6b1 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ivyint/CachedResolutionResolveEngine.scala @@ -937,7 +937,7 @@ private[sbt] trait CachedResolutionResolveEngine extends ResolveEngine { }).mkString("(", ", ", ")") ) } - case None => + case _ => getSettings.getConflictManager(IvyModuleId.newInstance(organization, name)) match { case ncm: NoConflictManager => (conflicts, Vector(), ncm.toString) case _: StrictConflictManager => From 8519cba481fc08442034b2cd5913842a1edcd200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Ferreira?= Date: Mon, 7 Oct 2024 23:45:38 +0100 Subject: [PATCH 1030/1030] fix warning reflectiveCalls warning by fixing TODO method reflectiveSelectableFromLangReflectiveCalls in object Selectable is deprecated since 3.0: import scala.reflect.Selectable.reflectiveSelectable instead of scala.language.reflectiveCalls --- .../sbt/internal/librarymanagement/ConvertResolver.scala | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala index 43c168d4c..4a8a96e13 100644 --- a/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala +++ b/ivy/src/main/scala/sbt/internal/librarymanagement/ConvertResolver.scala @@ -50,16 +50,11 @@ private[sbt] object ConvertResolver { * checksum-friendly URL publishing shim. */ private object ChecksumFriendlyURLResolver { - // TODO - When we dump JDK6 support we can remove this hackery - // import java.lang.reflect.AccessibleObject - type AccessibleObject = { - def setAccessible(value: Boolean): Unit - } + import java.lang.reflect.AccessibleObject private def reflectiveLookup[A <: AccessibleObject](f: Class[_] => A): Option[A] = try { val cls = classOf[RepositoryResolver] val thing = f(cls) - import scala.language.reflectiveCalls thing.setAccessible(true) Some(thing) } catch {